mirror of
https://github.com/cosinekitty/astronomy.git
synced 2026-05-19 06:17:03 -04:00
Added C functions SearchMoonNode, NextMoonNode.
Implemented a pair of C functions for finding a series of
Moon nodes:
Astronomy_SearchMoonNode
Astronomy_NextMoonNode
Finished the C unit test "moon_nodes" that verifies
my calculations against Fred Espenak's test data.
This commit is contained in:
@@ -5162,9 +5162,15 @@ static int MoonNodes(void)
|
||||
astro_vector_t vec_eqj, vec_eqd, vec_test;
|
||||
double diff_lat, max_lat = 0.0;
|
||||
double diff_angle, max_angle = 0.0;
|
||||
double diff_minutes, max_minutes = 0.0;
|
||||
double dt, min_dt = 1.0e+99, max_dt = 0.0;
|
||||
astro_rotation_t rot;
|
||||
astro_spherical_t sphere;
|
||||
astro_angle_result_t result;
|
||||
astro_node_event_t node;
|
||||
|
||||
memset(&node, 0, sizeof(node));
|
||||
node.status = ASTRO_NOT_INITIALIZED;
|
||||
|
||||
infile = fopen(filename, "rt");
|
||||
if (infile == NULL)
|
||||
@@ -5238,6 +5244,51 @@ static int MoonNodes(void)
|
||||
if (diff_angle > 1.54)
|
||||
FAIL("MoonNodes(%s line %d): EXCESSIVE equatorial error = %0.3lf arcmin\n", filename, lnum, diff_angle);
|
||||
|
||||
/* Now test the Astronomy Engine moon node searcher. */
|
||||
if (lnum == 1)
|
||||
{
|
||||
/* The very first time, so search for the first node in the series. */
|
||||
/* Back up a few days to make sure we really are finding it ourselves. */
|
||||
astro_time_t earlier = Astronomy_AddDays(time, -6.5472); /* pick a weird amount of time */
|
||||
node = Astronomy_SearchMoonNode(earlier);
|
||||
}
|
||||
else
|
||||
{
|
||||
double prev_tt = node.time.tt;
|
||||
|
||||
/* Use the previous node to find the next node. */
|
||||
node = Astronomy_NextMoonNode(node);
|
||||
|
||||
/* Find the range of time intervals between consecutive nodes. */
|
||||
dt = node.time.tt - prev_tt;
|
||||
if (dt < min_dt)
|
||||
min_dt = dt;
|
||||
if (dt > max_dt)
|
||||
max_dt = dt;
|
||||
}
|
||||
|
||||
if (node.status != ASTRO_SUCCESS)
|
||||
FAIL("MoonNodes(%s line %d): error %d returned by node search\n", filename, lnum, node.status);
|
||||
|
||||
/* Verify the ecliptic longitude is very close to zero here. */
|
||||
ecl = Astronomy_EclipticGeoMoon(node.time);
|
||||
CHECK_STATUS(ecl);
|
||||
diff_lat = 60.0 * ABS(ecl.lat);
|
||||
if (diff_lat > 8.1e-4)
|
||||
FAIL("MoonNodes(%s line %d): found node has excessive latitude = %0.4le arcmin\n", filename, lnum, diff_lat);
|
||||
|
||||
/* Verify the time agrees with Espenak's time to within a few minutes. */
|
||||
diff_minutes = (24.0 * 60.0) * ABS(node.time.tt - time.tt);
|
||||
if (diff_minutes > max_minutes)
|
||||
max_minutes = diff_minutes;
|
||||
|
||||
/* Verify the kind of node matches what Espenak says (ascending or descending). */
|
||||
if (kind == 'A' && node.kind != ASCENDING_NODE)
|
||||
FAIL("MoonNodes(%s line %d): did not find ascending node as expected.\n", filename, lnum);
|
||||
|
||||
if (kind == 'D' && node.kind != DESCENDING_NODE)
|
||||
FAIL("MoonNodes(%s line %d): did not find descending node as expected.\n", filename, lnum);
|
||||
|
||||
/* Prepare for the next iteration. */
|
||||
prev_kind = kind;
|
||||
}
|
||||
@@ -5245,7 +5296,11 @@ static int MoonNodes(void)
|
||||
if (max_lat > 0.183)
|
||||
FAIL("MoonNodes: EXCESSIVE ecliptic latitude error = %0.3lf arcmin\n", max_lat);
|
||||
|
||||
printf("MoonNodes: PASS (%d nodes, max lat error = %0.3lf arcmin, max equ error = %0.3lf arcmin)\n", lnum, max_lat, max_angle);
|
||||
if (max_minutes > 3.682)
|
||||
FAIL("MoonNodes: EXCESSIVE time prediction error = %0.3lf minutes\n", max_minutes);
|
||||
|
||||
DEBUG("MoonNodes: min_dt = %0.3lf days, max_dt = %0.3lf days.\n", min_dt, max_dt);
|
||||
printf("MoonNodes: PASS (%d nodes, max lat error = %0.3lf arcmin, max equ error = %0.3lf arcmin, max time error = %0.3lf minutes)\n", lnum, max_lat, max_angle, max_minutes);
|
||||
error = 0;
|
||||
fail:
|
||||
if (infile != NULL) fclose(infile);
|
||||
|
||||
@@ -8719,7 +8719,7 @@ astro_transit_t Astronomy_SearchTransit(astro_body_t body, astro_time_t startTim
|
||||
* A date and time near the previous transit.
|
||||
*
|
||||
* @return
|
||||
* If successful, the `status` field in the returned structure hold `ASTRO_SUCCESS`
|
||||
* If successful, the `status` field in the returned structure holds `ASTRO_SUCCESS`
|
||||
* and the other fields are as documented in #astro_transit_t.
|
||||
* Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
*/
|
||||
@@ -8732,6 +8732,135 @@ astro_transit_t Astronomy_NextTransit(astro_body_t body, astro_time_t prevTransi
|
||||
}
|
||||
|
||||
|
||||
static astro_node_event_t NodeError(astro_status_t status)
|
||||
{
|
||||
astro_node_event_t node;
|
||||
|
||||
node.status = status;
|
||||
node.time = TimeError();
|
||||
node.kind = INVALID_NODE;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static astro_func_result_t MoonNodeSearchFunc(void *context, astro_time_t time)
|
||||
{
|
||||
astro_func_result_t result;
|
||||
astro_spherical_t eclip;
|
||||
astro_node_kind_t kind = *((astro_node_kind_t *)context);
|
||||
|
||||
eclip = Astronomy_EclipticGeoMoon(time);
|
||||
|
||||
result.value = eclip.lat * (double)kind;
|
||||
result.status = ASTRO_SUCCESS;
|
||||
return result;
|
||||
}
|
||||
|
||||
static const double MOON_NODE_STEP_DAYS = +10.0; /* a safe number of days to step without missing a Moon node */
|
||||
|
||||
/**
|
||||
* @brief Searches for a time when the Moon's center crosses through the ecliptic plane.
|
||||
*
|
||||
* Searches for the first ascending or descending node of the Moon after `startTime`.
|
||||
* An ascending node is when the Moon's center passes through the ecliptic plane
|
||||
* (the plane of the Earth's orbit around the Sun) from the south to the north.
|
||||
* A descending node is when the Moon's center passes through the ecliptic plane
|
||||
* from the north to the south. Nodes indicate possible times of solar or lunar eclipses,
|
||||
* if the Moon also happens to be in the correct phase (new or full, respectively).
|
||||
*
|
||||
* Call `Astronomy_SearchMoonNode` to find the first of a series of nodes.
|
||||
* Then call #Astronomy_NextMoonNode to find as many more nodes as desired.
|
||||
*
|
||||
* @param startTime
|
||||
* The date and time for starting the search for an ascending or descending node of the Moon.
|
||||
*
|
||||
* @return
|
||||
* If successful, the `status` field in the returned structure holds `ASTRO_SUCCESS`
|
||||
* and the other fields are as documented in #astro_node_event_t.
|
||||
* Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
*/
|
||||
astro_node_event_t Astronomy_SearchMoonNode(astro_time_t startTime)
|
||||
{
|
||||
astro_node_event_t node;
|
||||
astro_time_t time1, time2;
|
||||
astro_spherical_t eclip1, eclip2;
|
||||
astro_node_kind_t kind;
|
||||
astro_search_result_t result;
|
||||
|
||||
/* Start at the given moment in time and sample the Moon's ecliptic latitude. */
|
||||
/* Step 10 days at a time, searching for an interval where that latitude crosses zero. */
|
||||
time1 = startTime;
|
||||
eclip1 = Astronomy_EclipticGeoMoon(time1); /* never returns a failure code */
|
||||
|
||||
for(;;)
|
||||
{
|
||||
time2 = Astronomy_AddDays(time1, MOON_NODE_STEP_DAYS);
|
||||
eclip2 = Astronomy_EclipticGeoMoon(time2); /* never returns a failure code */
|
||||
if (eclip1.lat * eclip2.lat <= 0.0)
|
||||
{
|
||||
/* There is a node somewhere inside this closed time interval. */
|
||||
/* Figure out whether it is an ascending node or a descending node. */
|
||||
kind = (eclip2.lat > eclip1.lat) ? ASCENDING_NODE : DESCENDING_NODE;
|
||||
result = Astronomy_Search(MoonNodeSearchFunc, &kind, time1, time2, 1.0);
|
||||
if (result.status != ASTRO_SUCCESS)
|
||||
return NodeError(result.status);
|
||||
|
||||
node.status = ASTRO_SUCCESS;
|
||||
node.time = result.time;
|
||||
node.kind = kind;
|
||||
return node;
|
||||
}
|
||||
time1 = time2;
|
||||
eclip1 = eclip2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Searches for the next time when the Moon's center crosses through the ecliptic plane.
|
||||
*
|
||||
* Call #Astronomy_SearchMoonNode to find the first of a series of nodes.
|
||||
* Then call `Astronomy_NextMoonNode` to find as many more nodes as desired.
|
||||
*
|
||||
* @param prevNode
|
||||
* The previous node found from calling #Astronomy_SearchMoonNode or Astronomy_NextMoonNode.
|
||||
*
|
||||
* @return
|
||||
* If successful, the `status` field in the returned structure holds `ASTRO_SUCCESS`
|
||||
* and the other fields are as documented in #astro_node_event_t.
|
||||
* Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
*/
|
||||
astro_node_event_t Astronomy_NextMoonNode(astro_node_event_t prevNode)
|
||||
{
|
||||
astro_time_t time;
|
||||
astro_node_event_t node;
|
||||
|
||||
if (prevNode.status != ASTRO_SUCCESS)
|
||||
return NodeError(ASTRO_INVALID_PARAMETER);
|
||||
|
||||
if (prevNode.kind != ASCENDING_NODE && prevNode.kind != DESCENDING_NODE)
|
||||
return NodeError(ASTRO_INVALID_PARAMETER);
|
||||
|
||||
time = Astronomy_AddDays(prevNode.time, MOON_NODE_STEP_DAYS);
|
||||
node = Astronomy_SearchMoonNode(time);
|
||||
if (node.status == ASTRO_SUCCESS)
|
||||
{
|
||||
/* Verify nodes are alternating as expected. */
|
||||
if (prevNode.kind == ASCENDING_NODE)
|
||||
{
|
||||
if (node.kind != DESCENDING_NODE)
|
||||
return NodeError(ASTRO_INTERNAL_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node.kind != ASCENDING_NODE)
|
||||
return NodeError(ASTRO_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Frees up all dynamic memory allocated by Astronomy Engine.
|
||||
*
|
||||
|
||||
@@ -1229,6 +1229,30 @@ After using [`Astronomy_SearchLunarEclipse`](#Astronomy_SearchLunarEclipse) to f
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="Astronomy_NextMoonNode"></a>
|
||||
### Astronomy_NextMoonNode(prevNode) ⇒ [`astro_node_event_t`](#astro_node_event_t)
|
||||
|
||||
**Searches for the next time when the Moon's center crosses through the ecliptic plane.**
|
||||
|
||||
|
||||
|
||||
Call [`Astronomy_SearchMoonNode`](#Astronomy_SearchMoonNode) to find the first of a series of nodes. Then call `Astronomy_NextMoonNode` to find as many more nodes as desired.
|
||||
|
||||
|
||||
|
||||
**Returns:** If successful, the `status` field in the returned structure holds `ASTRO_SUCCESS` and the other fields are as documented in [`astro_node_event_t`](#astro_node_event_t). Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
|
||||
|
||||
|
||||
| Type | Parameter | Description |
|
||||
| --- | --- | --- |
|
||||
| [`astro_node_event_t`](#astro_node_event_t) | `prevNode` | The previous node found from calling [`Astronomy_SearchMoonNode`](#Astronomy_SearchMoonNode) or Astronomy_NextMoonNode. |
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="Astronomy_NextMoonQuarter"></a>
|
||||
@@ -1293,7 +1317,7 @@ After calling [`Astronomy_SearchTransit`](#Astronomy_SearchTransit) to find a tr
|
||||
|
||||
|
||||
|
||||
**Returns:** If successful, the `status` field in the returned structure hold `ASTRO_SUCCESS` and the other fields are as documented in [`astro_transit_t`](#astro_transit_t). Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
**Returns:** If successful, the `status` field in the returned structure holds `ASTRO_SUCCESS` and the other fields are as documented in [`astro_transit_t`](#astro_transit_t). Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
|
||||
|
||||
|
||||
@@ -2129,6 +2153,32 @@ This function solves for those times, reporting the next maximum elongation even
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="Astronomy_SearchMoonNode"></a>
|
||||
### Astronomy_SearchMoonNode(startTime) ⇒ [`astro_node_event_t`](#astro_node_event_t)
|
||||
|
||||
**Searches for a time when the Moon's center crosses through the ecliptic plane.**
|
||||
|
||||
|
||||
|
||||
Searches for the first ascending or descending node of the Moon after `startTime`. An ascending node is when the Moon's center passes through the ecliptic plane (the plane of the Earth's orbit around the Sun) from the south to the north. A descending node is when the Moon's center passes through the ecliptic plane from the north to the south. Nodes indicate possible times of solar or lunar eclipses, if the Moon also happens to be in the correct phase (new or full, respectively).
|
||||
|
||||
Call `Astronomy_SearchMoonNode` to find the first of a series of nodes. Then call [`Astronomy_NextMoonNode`](#Astronomy_NextMoonNode) to find as many more nodes as desired.
|
||||
|
||||
|
||||
|
||||
**Returns:** If successful, the `status` field in the returned structure holds `ASTRO_SUCCESS` and the other fields are as documented in [`astro_node_event_t`](#astro_node_event_t). Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
|
||||
|
||||
|
||||
| Type | Parameter | Description |
|
||||
| --- | --- | --- |
|
||||
| [`astro_time_t`](#astro_time_t) | `startTime` | The date and time for starting the search for an ascending or descending node of the Moon. |
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="Astronomy_SearchMoonPhase"></a>
|
||||
@@ -3346,6 +3396,23 @@ For some other purposes, it is more helpful to represent coordinates using the E
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="astro_node_kind_t"></a>
|
||||
### `astro_node_kind_t`
|
||||
|
||||
**Indicates whether a crossing through the ecliptic plane is ascending or descending.**
|
||||
|
||||
|
||||
|
||||
| Enum Value | Description |
|
||||
| --- | --- |
|
||||
| `INVALID_NODE` | Placeholder value for a missing or invalid node. |
|
||||
| `ASCENDING_NODE` | The body passes through the ecliptic plane from south to north. |
|
||||
| `DESCENDING_NODE` | The body passes through the ecliptic plane from north to south. |
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="astro_refraction_t"></a>
|
||||
@@ -3806,6 +3873,24 @@ Fields `sd_penum`, `sd_partial`, and `sd_total` hold the semi-duration of each p
|
||||
| [`astro_time_t`](#astro_time_t) | `time` | The date and time of the lunar quarter. |
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="astro_node_event_t"></a>
|
||||
### `astro_node_event_t`
|
||||
|
||||
**Information about an ascending or descending node of a body.**
|
||||
|
||||
|
||||
|
||||
This structure is returned by [`Astronomy_SearchMoonNode`](#Astronomy_SearchMoonNode) and [`Astronomy_NextMoonNode`](#Astronomy_NextMoonNode) to report information about the center of the Moon passing through the ecliptic plane.
|
||||
|
||||
| Type | Member | Description |
|
||||
| ---- | ------ | ----------- |
|
||||
| [`astro_status_t`](#astro_status_t) | `status` | `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. |
|
||||
| [`astro_time_t`](#astro_time_t) | `time` | The time when the body passes through the ecliptic plane. |
|
||||
| [`astro_node_kind_t`](#astro_node_kind_t) | `kind` | Either `ASCENDING_NODE` or `DESCENDING_NODE`, depending on the direction of the ecliptic plane crossing. |
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="astro_observer_t"></a>
|
||||
|
||||
@@ -10413,7 +10413,7 @@ astro_transit_t Astronomy_SearchTransit(astro_body_t body, astro_time_t startTim
|
||||
* A date and time near the previous transit.
|
||||
*
|
||||
* @return
|
||||
* If successful, the `status` field in the returned structure hold `ASTRO_SUCCESS`
|
||||
* If successful, the `status` field in the returned structure holds `ASTRO_SUCCESS`
|
||||
* and the other fields are as documented in #astro_transit_t.
|
||||
* Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
*/
|
||||
@@ -10426,6 +10426,135 @@ astro_transit_t Astronomy_NextTransit(astro_body_t body, astro_time_t prevTransi
|
||||
}
|
||||
|
||||
|
||||
static astro_node_event_t NodeError(astro_status_t status)
|
||||
{
|
||||
astro_node_event_t node;
|
||||
|
||||
node.status = status;
|
||||
node.time = TimeError();
|
||||
node.kind = INVALID_NODE;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
static astro_func_result_t MoonNodeSearchFunc(void *context, astro_time_t time)
|
||||
{
|
||||
astro_func_result_t result;
|
||||
astro_spherical_t eclip;
|
||||
astro_node_kind_t kind = *((astro_node_kind_t *)context);
|
||||
|
||||
eclip = Astronomy_EclipticGeoMoon(time);
|
||||
|
||||
result.value = eclip.lat * (double)kind;
|
||||
result.status = ASTRO_SUCCESS;
|
||||
return result;
|
||||
}
|
||||
|
||||
static const double MOON_NODE_STEP_DAYS = +10.0; /* a safe number of days to step without missing a Moon node */
|
||||
|
||||
/**
|
||||
* @brief Searches for a time when the Moon's center crosses through the ecliptic plane.
|
||||
*
|
||||
* Searches for the first ascending or descending node of the Moon after `startTime`.
|
||||
* An ascending node is when the Moon's center passes through the ecliptic plane
|
||||
* (the plane of the Earth's orbit around the Sun) from the south to the north.
|
||||
* A descending node is when the Moon's center passes through the ecliptic plane
|
||||
* from the north to the south. Nodes indicate possible times of solar or lunar eclipses,
|
||||
* if the Moon also happens to be in the correct phase (new or full, respectively).
|
||||
*
|
||||
* Call `Astronomy_SearchMoonNode` to find the first of a series of nodes.
|
||||
* Then call #Astronomy_NextMoonNode to find as many more nodes as desired.
|
||||
*
|
||||
* @param startTime
|
||||
* The date and time for starting the search for an ascending or descending node of the Moon.
|
||||
*
|
||||
* @return
|
||||
* If successful, the `status` field in the returned structure holds `ASTRO_SUCCESS`
|
||||
* and the other fields are as documented in #astro_node_event_t.
|
||||
* Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
*/
|
||||
astro_node_event_t Astronomy_SearchMoonNode(astro_time_t startTime)
|
||||
{
|
||||
astro_node_event_t node;
|
||||
astro_time_t time1, time2;
|
||||
astro_spherical_t eclip1, eclip2;
|
||||
astro_node_kind_t kind;
|
||||
astro_search_result_t result;
|
||||
|
||||
/* Start at the given moment in time and sample the Moon's ecliptic latitude. */
|
||||
/* Step 10 days at a time, searching for an interval where that latitude crosses zero. */
|
||||
time1 = startTime;
|
||||
eclip1 = Astronomy_EclipticGeoMoon(time1); /* never returns a failure code */
|
||||
|
||||
for(;;)
|
||||
{
|
||||
time2 = Astronomy_AddDays(time1, MOON_NODE_STEP_DAYS);
|
||||
eclip2 = Astronomy_EclipticGeoMoon(time2); /* never returns a failure code */
|
||||
if (eclip1.lat * eclip2.lat <= 0.0)
|
||||
{
|
||||
/* There is a node somewhere inside this closed time interval. */
|
||||
/* Figure out whether it is an ascending node or a descending node. */
|
||||
kind = (eclip2.lat > eclip1.lat) ? ASCENDING_NODE : DESCENDING_NODE;
|
||||
result = Astronomy_Search(MoonNodeSearchFunc, &kind, time1, time2, 1.0);
|
||||
if (result.status != ASTRO_SUCCESS)
|
||||
return NodeError(result.status);
|
||||
|
||||
node.status = ASTRO_SUCCESS;
|
||||
node.time = result.time;
|
||||
node.kind = kind;
|
||||
return node;
|
||||
}
|
||||
time1 = time2;
|
||||
eclip1 = eclip2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Searches for the next time when the Moon's center crosses through the ecliptic plane.
|
||||
*
|
||||
* Call #Astronomy_SearchMoonNode to find the first of a series of nodes.
|
||||
* Then call `Astronomy_NextMoonNode` to find as many more nodes as desired.
|
||||
*
|
||||
* @param prevNode
|
||||
* The previous node found from calling #Astronomy_SearchMoonNode or Astronomy_NextMoonNode.
|
||||
*
|
||||
* @return
|
||||
* If successful, the `status` field in the returned structure holds `ASTRO_SUCCESS`
|
||||
* and the other fields are as documented in #astro_node_event_t.
|
||||
* Otherwise, `status` holds an error code and the other structure members are undefined.
|
||||
*/
|
||||
astro_node_event_t Astronomy_NextMoonNode(astro_node_event_t prevNode)
|
||||
{
|
||||
astro_time_t time;
|
||||
astro_node_event_t node;
|
||||
|
||||
if (prevNode.status != ASTRO_SUCCESS)
|
||||
return NodeError(ASTRO_INVALID_PARAMETER);
|
||||
|
||||
if (prevNode.kind != ASCENDING_NODE && prevNode.kind != DESCENDING_NODE)
|
||||
return NodeError(ASTRO_INVALID_PARAMETER);
|
||||
|
||||
time = Astronomy_AddDays(prevNode.time, MOON_NODE_STEP_DAYS);
|
||||
node = Astronomy_SearchMoonNode(time);
|
||||
if (node.status == ASTRO_SUCCESS)
|
||||
{
|
||||
/* Verify nodes are alternating as expected. */
|
||||
if (prevNode.kind == ASCENDING_NODE)
|
||||
{
|
||||
if (node.kind != DESCENDING_NODE)
|
||||
return NodeError(ASTRO_INTERNAL_ERROR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (node.kind != ASCENDING_NODE)
|
||||
return NodeError(ASTRO_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Frees up all dynamic memory allocated by Astronomy Engine.
|
||||
*
|
||||
|
||||
@@ -1100,6 +1100,32 @@ typedef struct
|
||||
astro_jupiter_moons_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Indicates whether a crossing through the ecliptic plane is ascending or descending.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
INVALID_NODE = 0, /**< Placeholder value for a missing or invalid node. */
|
||||
ASCENDING_NODE = +1, /**< The body passes through the ecliptic plane from south to north. */
|
||||
DESCENDING_NODE = -1 /**< The body passes through the ecliptic plane from north to south. */
|
||||
}
|
||||
astro_node_kind_t;
|
||||
|
||||
/**
|
||||
* @brief Information about an ascending or descending node of a body.
|
||||
*
|
||||
* This structure is returned by #Astronomy_SearchMoonNode and #Astronomy_NextMoonNode
|
||||
* to report information about the center of the Moon passing through the ecliptic plane.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
astro_status_t status; /**< `ASTRO_SUCCESS` if this struct is valid; otherwise an error code. */
|
||||
astro_time_t time; /**< The time when the body passes through the ecliptic plane. */
|
||||
astro_node_kind_t kind; /**< Either `ASCENDING_NODE` or `DESCENDING_NODE`, depending on the direction of the ecliptic plane crossing. */
|
||||
}
|
||||
astro_node_event_t;
|
||||
|
||||
|
||||
/*---------- functions ----------*/
|
||||
|
||||
void Astronomy_Reset(void);
|
||||
@@ -1186,6 +1212,8 @@ astro_local_solar_eclipse_t Astronomy_SearchLocalSolarEclipse(astro_time_t start
|
||||
astro_local_solar_eclipse_t Astronomy_NextLocalSolarEclipse(astro_time_t prevEclipseTime, astro_observer_t observer);
|
||||
astro_transit_t Astronomy_SearchTransit(astro_body_t body, astro_time_t startTime);
|
||||
astro_transit_t Astronomy_NextTransit(astro_body_t body, astro_time_t prevTransitTime);
|
||||
astro_node_event_t Astronomy_SearchMoonNode(astro_time_t startTime);
|
||||
astro_node_event_t Astronomy_NextMoonNode(astro_node_event_t prevNode);
|
||||
|
||||
astro_search_result_t Astronomy_Search(
|
||||
astro_search_func_t func,
|
||||
|
||||
Reference in New Issue
Block a user