mirror of
https://github.com/cosinekitty/astronomy.git
synced 2025-12-31 03:30:26 -05:00
The following C functions now support searching
in forward or reverse chronological order:
Astronomy_SearchRiseSet
Astronomy_SearchAltitude
Astronomy_SearchHourAngleEx
The function Astronomy_SearchHourAngleEx replaces
Astronomy_SearchHourAngle, adding a new `direction` parameter.
A #define for Astronomy_SearchHourAngle preserves backward
compatibility for older code.
Implementation notes:
Astronomy_SearchRiseSet and Astronomy_SearchAltitude used
to call a private function InternalSearchAltitude.
That function has been split into two functions:
BackwardSearchAltitude and ForwardSearchAltitude,
for searching both directions in time.
Fixed a bug where it was possible to report a successful
altitude event that went outside the time limit specified
by `limitDays`.
160 lines
4.2 KiB
C
160 lines
4.2 KiB
C
/*
|
|
linux_riseset.c - by Don Cross - 2020-09-08
|
|
|
|
Example C program for Astronomy Engine:
|
|
https://github.com/cosinekitty/astronomy
|
|
|
|
This program calculates sunrise, sunset, moonrise, and moonset
|
|
times for an observer at a given latitude and longitude.
|
|
|
|
It uses timezone functions available in Linux to print
|
|
the events the system's configured local time, instead of UTC.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <math.h>
|
|
#include "astro_demo_common.h"
|
|
|
|
void PrintLocalTime(astro_time_t time)
|
|
{
|
|
astro_time_t linux_epoch;
|
|
time_t seconds;
|
|
struct tm local;
|
|
const char *dow;
|
|
|
|
/* Calculate the Linux Epoch as an astronomy time. */
|
|
linux_epoch = Astronomy_MakeTime(1970, 1, 1, 0, 0, 0);
|
|
|
|
/* Subtract the two UT values to find the number of seconds elapsed. */
|
|
seconds = (time_t) round((time.ut - linux_epoch.ut) * 86400.0);
|
|
|
|
/* Obtain the corresponding local time for this system's timezone. */
|
|
localtime_r(&seconds, &local);
|
|
|
|
switch (local.tm_wday)
|
|
{
|
|
case 0: dow = "Sun"; break;
|
|
case 1: dow = "Mon"; break;
|
|
case 2: dow = "Tue"; break;
|
|
case 3: dow = "Wed"; break;
|
|
case 4: dow = "Thu"; break;
|
|
case 5: dow = "Fri"; break;
|
|
case 6: dow = "Sat"; break;
|
|
default: dow = "---"; break;
|
|
}
|
|
|
|
printf("%04d-%02d-%02d %s %02d:%02d:%02d %s",
|
|
local.tm_year+1900, local.tm_mon+1, local.tm_mday,
|
|
dow,
|
|
local.tm_hour, local.tm_min, local.tm_sec,
|
|
(local.tm_isdst ? "DT" : "ST"));
|
|
}
|
|
|
|
|
|
typedef struct
|
|
{
|
|
const char *name;
|
|
astro_time_t time;
|
|
double altitude; /* angle of culmination above horizon; otherwise NAN */
|
|
}
|
|
event_t;
|
|
|
|
|
|
void AppendCulm(
|
|
event_t evtlist[],
|
|
int *evtcount,
|
|
const char *name,
|
|
astro_body_t body,
|
|
astro_observer_t observer,
|
|
astro_time_t search_time)
|
|
{
|
|
astro_hour_angle_t culm;
|
|
|
|
culm = Astronomy_SearchHourAngleEx(body, observer, 0.0, search_time, +1);
|
|
if (culm.status == ASTRO_SUCCESS)
|
|
{
|
|
evtlist[*evtcount].name = name;
|
|
evtlist[*evtcount].time = culm.time;
|
|
evtlist[*evtcount].altitude = culm.hor.altitude;
|
|
++(*evtcount);
|
|
}
|
|
else
|
|
{
|
|
printf("ERROR %d finding culmination of %s\n", culm.status, name);
|
|
}
|
|
}
|
|
|
|
|
|
void AppendEvent(const char *name, event_t evtlist[], int *evtcount, astro_search_result_t result)
|
|
{
|
|
if (result.status == ASTRO_SUCCESS)
|
|
{
|
|
evtlist[*evtcount].name = name;
|
|
evtlist[*evtcount].time = result.time;
|
|
evtlist[*evtcount].altitude = NAN;
|
|
++(*evtcount);
|
|
}
|
|
else
|
|
{
|
|
printf("ERROR %d finding %s\n", result.status, name);
|
|
}
|
|
}
|
|
|
|
|
|
int EventCompare(const void *aptr, const void *bptr)
|
|
{
|
|
const event_t *a = aptr;
|
|
const event_t *b = bptr;
|
|
if (a->time.ut < b->time.ut)
|
|
return -1;
|
|
if (a->time.ut > b->time.ut)
|
|
return +1;
|
|
return 0;
|
|
}
|
|
|
|
|
|
int main(int argc, const char *argv[])
|
|
{
|
|
astro_observer_t observer;
|
|
astro_time_t time;
|
|
astro_search_result_t result;
|
|
event_t evtlist[6];
|
|
int evtcount = 0;
|
|
int i;
|
|
|
|
if (ParseArgs(argc, argv, &observer, &time))
|
|
return 1;
|
|
|
|
result = Astronomy_SearchRiseSet(BODY_SUN, observer, DIRECTION_RISE, time, 300.0);
|
|
AppendEvent("sunrise", evtlist, &evtcount, result);
|
|
|
|
result = Astronomy_SearchRiseSet(BODY_SUN, observer, DIRECTION_SET, time, 300.0);
|
|
AppendEvent("sunset", evtlist, &evtcount, result);
|
|
|
|
result = Astronomy_SearchRiseSet(BODY_MOON, observer, DIRECTION_RISE, time, 300.0);
|
|
AppendEvent("moonrise", evtlist, &evtcount, result);
|
|
|
|
result = Astronomy_SearchRiseSet(BODY_MOON, observer, DIRECTION_SET, time, 300.0);
|
|
AppendEvent("moonset", evtlist, &evtcount, result);
|
|
|
|
AppendCulm(evtlist, &evtcount, "moonculm", BODY_MOON, observer, time);
|
|
AppendCulm(evtlist, &evtcount, "sunculm", BODY_SUN, observer, time);
|
|
|
|
/* Sort the events in chronological order. */
|
|
qsort(evtlist, (size_t)evtcount, sizeof(event_t), EventCompare);
|
|
|
|
/* Print the sorted events. */
|
|
for (i=0; i < evtcount; ++i)
|
|
{
|
|
printf("%-8s : ", evtlist[i].name);
|
|
PrintLocalTime(evtlist[i].time);
|
|
if (isfinite(evtlist[i].altitude))
|
|
printf(" alt = %0.2lf", evtlist[i].altitude);
|
|
printf("\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|