mirror of
https://github.com/cosinekitty/astronomy.git
synced 2026-05-24 16:56:39 -04:00
Added C function Astronomy_PairLongitude.
This function is a generalization of Astronomy_LongitudeFromSun, which it replaces. It calculates the relative ecliptic longitude of one body with respect to another body, as seen from the Earth. After implementing the same function in C#, JavaScript, and Python, I will come back and create a generalized search algorithm to find the next time two bodies are at a given apparent relative longitude. Even though this is a generalization of SearchRelativeLongitude, I will have to figure out a more general way of tuning the search.
This commit is contained in:
@@ -3717,7 +3717,7 @@ astro_elongation_t Astronomy_Elongation(astro_body_t body, astro_time_t time)
|
||||
astro_elongation_t result;
|
||||
astro_angle_result_t angres;
|
||||
|
||||
angres = Astronomy_LongitudeFromSun(body, time);
|
||||
angres = Astronomy_PairLongitude(body, BODY_SUN, time);
|
||||
if (angres.status != ASTRO_SUCCESS)
|
||||
return ElongError(angres.status);
|
||||
|
||||
@@ -3925,33 +3925,32 @@ astro_elongation_t Astronomy_SearchMaxElongation(astro_body_t body, astro_time_t
|
||||
return ElongError(ASTRO_SEARCH_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Returns a body's ecliptic longitude with respect to the Sun, as seen from the Earth.
|
||||
* @brief Returns one body's ecliptic longitude with respect another, as seen from the Earth.
|
||||
*
|
||||
* This function can be used to determine where a planet appears around the ecliptic plane
|
||||
* This function determines where one body appears around the ecliptic plane
|
||||
* (the plane of the Earth's orbit around the Sun) as seen from the Earth,
|
||||
* relative to the Sun's apparent position.
|
||||
* relative to the another body's apparent position.
|
||||
* The function returns an angle in the half-open range [0, 360) degrees.
|
||||
* The value is the ecliptic longitude of `body1` relative to the ecliptic
|
||||
* longitude of `body2`.
|
||||
*
|
||||
* The angle starts at 0 when the body and the Sun are at the same ecliptic longitude
|
||||
* The angle is 0 when the two bodies are at the same ecliptic longitude
|
||||
* as seen from the Earth. The angle increases in the prograde direction
|
||||
* (the direction that the planets orbit the Sun and the Moon orbits the Earth).
|
||||
*
|
||||
* When the angle is 180 degrees, it means the Sun and the body appear on opposite sides
|
||||
* of the sky for an Earthly observer. When `body` is a planet whose orbit around the
|
||||
* Sun is farther than the Earth's, 180 degrees indicates opposition. For the Moon,
|
||||
* it indicates a full moon.
|
||||
* When the angle is 180 degrees, it means the two bodies appear on opposite sides
|
||||
* of the sky for an Earthly observer.
|
||||
*
|
||||
* The angle keeps increasing up to 360 degrees as the body's apparent prograde
|
||||
* motion continues relative to the Sun. When the angle reaches 360 degrees, it starts
|
||||
* over at 0 degrees.
|
||||
* Neither `body1` nor `body2` is allowed to be `BODY_EARTH`.
|
||||
* If this happens, the function fails with the error code `ASTRO_EARTH_NOT_ALLOWED`.
|
||||
*
|
||||
* Values between 0 and 180 degrees indicate that the body is visible in the evening sky
|
||||
* after sunset. Values between 180 degrees and 360 degrees indicate that the body
|
||||
* is visible in the morning sky before sunrise.
|
||||
* @param body1
|
||||
* The first body, whose longitude is to be found relative to the second body.
|
||||
*
|
||||
* @param body
|
||||
* The celestial body for which to find longitude from the Sun.
|
||||
* @param body2
|
||||
* The second body, relative to which the longitude of the first body is to be found.
|
||||
*
|
||||
* @param time
|
||||
* The date and time of the observation.
|
||||
@@ -3961,30 +3960,34 @@ astro_elongation_t Astronomy_SearchMaxElongation(astro_body_t body, astro_time_t
|
||||
* the `angle` field holds a value in the range [0, 360).
|
||||
* On failure, the `status` field contains some other value indicating an error condition.
|
||||
*/
|
||||
astro_angle_result_t Astronomy_LongitudeFromSun(astro_body_t body, astro_time_t time)
|
||||
astro_angle_result_t Astronomy_PairLongitude(
|
||||
astro_body_t body1,
|
||||
astro_body_t body2,
|
||||
astro_time_t time)
|
||||
{
|
||||
astro_vector_t sv, bv;
|
||||
astro_ecliptic_t se, be;
|
||||
astro_vector_t vector1, vector2;
|
||||
astro_ecliptic_t eclip1, eclip2;
|
||||
astro_angle_result_t result;
|
||||
|
||||
if (body == BODY_EARTH)
|
||||
if (body1 == BODY_EARTH || body2 == BODY_EARTH)
|
||||
return AngleError(ASTRO_EARTH_NOT_ALLOWED);
|
||||
|
||||
sv = Astronomy_GeoVector(BODY_SUN, time, NO_ABERRATION);
|
||||
se = Astronomy_Ecliptic(sv); /* checks for errors in sv */
|
||||
if (se.status != ASTRO_SUCCESS)
|
||||
return AngleError(se.status);
|
||||
vector1 = Astronomy_GeoVector(body1, time, NO_ABERRATION);
|
||||
eclip1 = Astronomy_Ecliptic(vector1); /* checks for errors in vector1 */
|
||||
if (eclip1.status != ASTRO_SUCCESS)
|
||||
return AngleError(eclip1.status);
|
||||
|
||||
bv = Astronomy_GeoVector(body, time, NO_ABERRATION);
|
||||
be = Astronomy_Ecliptic(bv); /* checks for errors in bv */
|
||||
if (be.status != ASTRO_SUCCESS)
|
||||
return AngleError(be.status);
|
||||
vector2 = Astronomy_GeoVector(body2, time, NO_ABERRATION);
|
||||
eclip2 = Astronomy_Ecliptic(vector2); /* checks for errors in vector2 */
|
||||
if (eclip2.status != ASTRO_SUCCESS)
|
||||
return AngleError(eclip2.status);
|
||||
|
||||
result.status = ASTRO_SUCCESS;
|
||||
result.angle = NormalizeLongitude(be.elon - se.elon);
|
||||
result.angle = NormalizeLongitude(eclip1.elon - eclip2.elon);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Returns the Moon's phase as an angle from 0 to 360 degrees.
|
||||
@@ -4011,7 +4014,7 @@ astro_angle_result_t Astronomy_LongitudeFromSun(astro_body_t body, astro_time_t
|
||||
*/
|
||||
astro_angle_result_t Astronomy_MoonPhase(astro_time_t time)
|
||||
{
|
||||
return Astronomy_LongitudeFromSun(BODY_MOON, time);
|
||||
return Astronomy_PairLongitude(BODY_MOON, BODY_SUN, time);
|
||||
}
|
||||
|
||||
static astro_func_result_t moon_offset(void *context, astro_time_t time)
|
||||
|
||||
@@ -55,7 +55,7 @@ To get started quickly, here are some [examples](../../demo/c/).
|
||||
| [Ecliptic](#Astronomy_Ecliptic) | Converts J2000 equatorial coordinates to J2000 ecliptic coordinates. |
|
||||
| [EclipticLongitude](#Astronomy_EclipticLongitude) | Calculates ecliptic longitude of a body in the J2000 system. |
|
||||
| [Horizon](#Astronomy_Horizon) | Calculates horizontal coordinates (azimuth, altitude) for a given observer on the Earth. |
|
||||
| [LongitudeFromSun](#Astronomy_LongitudeFromSun) | Calculates a body's apparent ecliptic longitude difference from the Sun, as seen by an observer on the Earth. |
|
||||
| [PairLongitude](#Astronomy_PairLongitude) | Calculates the difference in apparent ecliptic longitude between two bodies, as seen from the Earth. |
|
||||
|
||||
### Rise, set, and culmination times
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ To get started quickly, here are some [examples](../../demo/c/).
|
||||
| [Ecliptic](#Astronomy_Ecliptic) | Converts J2000 equatorial coordinates to J2000 ecliptic coordinates. |
|
||||
| [EclipticLongitude](#Astronomy_EclipticLongitude) | Calculates ecliptic longitude of a body in the J2000 system. |
|
||||
| [Horizon](#Astronomy_Horizon) | Calculates horizontal coordinates (azimuth, altitude) for a given observer on the Earth. |
|
||||
| [LongitudeFromSun](#Astronomy_LongitudeFromSun) | Calculates a body's apparent ecliptic longitude difference from the Sun, as seen by an observer on the Earth. |
|
||||
| [PairLongitude](#Astronomy_PairLongitude) | Calculates the difference in apparent ecliptic longitude between two bodies, as seen from the Earth. |
|
||||
|
||||
### Rise, set, and culmination times
|
||||
|
||||
@@ -868,39 +868,6 @@ To convert to heliocentric position vectors, call [`Astronomy_HelioVector`](#Ast
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="Astronomy_LongitudeFromSun"></a>
|
||||
### Astronomy_LongitudeFromSun(body, time) ⇒ [`astro_angle_result_t`](#astro_angle_result_t)
|
||||
|
||||
**Returns a body's ecliptic longitude with respect to the Sun, as seen from the Earth.**
|
||||
|
||||
|
||||
|
||||
This function can be used to determine where a planet appears around the ecliptic plane (the plane of the Earth's orbit around the Sun) as seen from the Earth, relative to the Sun's apparent position.
|
||||
|
||||
The angle starts at 0 when the body and the Sun are at the same ecliptic longitude as seen from the Earth. The angle increases in the prograde direction (the direction that the planets orbit the Sun and the Moon orbits the Earth).
|
||||
|
||||
When the angle is 180 degrees, it means the Sun and the body appear on opposite sides of the sky for an Earthly observer. When `body` is a planet whose orbit around the Sun is farther than the Earth's, 180 degrees indicates opposition. For the Moon, it indicates a full moon.
|
||||
|
||||
The angle keeps increasing up to 360 degrees as the body's apparent prograde motion continues relative to the Sun. When the angle reaches 360 degrees, it starts over at 0 degrees.
|
||||
|
||||
Values between 0 and 180 degrees indicate that the body is visible in the evening sky after sunset. Values between 180 degrees and 360 degrees indicate that the body is visible in the morning sky before sunrise.
|
||||
|
||||
|
||||
|
||||
**Returns:** On success, the `status` field in the returned structure holds `ASTRO_SUCCESS` and the `angle` field holds a value in the range [0, 360). On failure, the `status` field contains some other value indicating an error condition.
|
||||
|
||||
|
||||
|
||||
| Type | Parameter | Description |
|
||||
| --- | --- | --- |
|
||||
| [`astro_body_t`](#astro_body_t) | `body` | The celestial body for which to find longitude from the Sun. |
|
||||
| [`astro_time_t`](#astro_time_t) | `time` | The date and time of the observation. |
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="Astronomy_MakeObserver"></a>
|
||||
@@ -1195,6 +1162,38 @@ The returned vector has components expressed in astronomical units (AU). To conv
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="Astronomy_PairLongitude"></a>
|
||||
### Astronomy_PairLongitude(body1, body2, time) ⇒ [`astro_angle_result_t`](#astro_angle_result_t)
|
||||
|
||||
**Returns one body's ecliptic longitude with respect another, as seen from the Earth.**
|
||||
|
||||
|
||||
|
||||
This function determines where one body appears around the ecliptic plane (the plane of the Earth's orbit around the Sun) as seen from the Earth, relative to the another body's apparent position. The function returns an angle in the half-open range [0, 360) degrees. The value is the ecliptic longitude of `body1` relative to the ecliptic longitude of `body2`.
|
||||
|
||||
The angle is 0 when the two bodies are at the same ecliptic longitude as seen from the Earth. The angle increases in the prograde direction (the direction that the planets orbit the Sun and the Moon orbits the Earth).
|
||||
|
||||
When the angle is 180 degrees, it means the two bodies appear on opposite sides of the sky for an Earthly observer.
|
||||
|
||||
Neither `body1` nor `body2` is allowed to be `BODY_EARTH`. If this happens, the function fails with the error code `ASTRO_EARTH_NOT_ALLOWED`.
|
||||
|
||||
|
||||
|
||||
**Returns:** On success, the `status` field in the returned structure holds `ASTRO_SUCCESS` and the `angle` field holds a value in the range [0, 360). On failure, the `status` field contains some other value indicating an error condition.
|
||||
|
||||
|
||||
|
||||
| Type | Parameter | Description |
|
||||
| --- | --- | --- |
|
||||
| [`astro_body_t`](#astro_body_t) | `body1` | The first body, whose longitude is to be found relative to the second body. |
|
||||
| [`astro_body_t`](#astro_body_t) | `body2` | The second body, relative to which the longitude of the first body is to be found. |
|
||||
| [`astro_time_t`](#astro_time_t) | `time` | The date and time of the observation. |
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
<a name="Astronomy_Pivot"></a>
|
||||
|
||||
@@ -4943,7 +4943,7 @@ astro_elongation_t Astronomy_Elongation(astro_body_t body, astro_time_t time)
|
||||
astro_elongation_t result;
|
||||
astro_angle_result_t angres;
|
||||
|
||||
angres = Astronomy_LongitudeFromSun(body, time);
|
||||
angres = Astronomy_PairLongitude(body, BODY_SUN, time);
|
||||
if (angres.status != ASTRO_SUCCESS)
|
||||
return ElongError(angres.status);
|
||||
|
||||
@@ -5151,33 +5151,32 @@ astro_elongation_t Astronomy_SearchMaxElongation(astro_body_t body, astro_time_t
|
||||
return ElongError(ASTRO_SEARCH_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Returns a body's ecliptic longitude with respect to the Sun, as seen from the Earth.
|
||||
* @brief Returns one body's ecliptic longitude with respect another, as seen from the Earth.
|
||||
*
|
||||
* This function can be used to determine where a planet appears around the ecliptic plane
|
||||
* This function determines where one body appears around the ecliptic plane
|
||||
* (the plane of the Earth's orbit around the Sun) as seen from the Earth,
|
||||
* relative to the Sun's apparent position.
|
||||
* relative to the another body's apparent position.
|
||||
* The function returns an angle in the half-open range [0, 360) degrees.
|
||||
* The value is the ecliptic longitude of `body1` relative to the ecliptic
|
||||
* longitude of `body2`.
|
||||
*
|
||||
* The angle starts at 0 when the body and the Sun are at the same ecliptic longitude
|
||||
* The angle is 0 when the two bodies are at the same ecliptic longitude
|
||||
* as seen from the Earth. The angle increases in the prograde direction
|
||||
* (the direction that the planets orbit the Sun and the Moon orbits the Earth).
|
||||
*
|
||||
* When the angle is 180 degrees, it means the Sun and the body appear on opposite sides
|
||||
* of the sky for an Earthly observer. When `body` is a planet whose orbit around the
|
||||
* Sun is farther than the Earth's, 180 degrees indicates opposition. For the Moon,
|
||||
* it indicates a full moon.
|
||||
* When the angle is 180 degrees, it means the two bodies appear on opposite sides
|
||||
* of the sky for an Earthly observer.
|
||||
*
|
||||
* The angle keeps increasing up to 360 degrees as the body's apparent prograde
|
||||
* motion continues relative to the Sun. When the angle reaches 360 degrees, it starts
|
||||
* over at 0 degrees.
|
||||
* Neither `body1` nor `body2` is allowed to be `BODY_EARTH`.
|
||||
* If this happens, the function fails with the error code `ASTRO_EARTH_NOT_ALLOWED`.
|
||||
*
|
||||
* Values between 0 and 180 degrees indicate that the body is visible in the evening sky
|
||||
* after sunset. Values between 180 degrees and 360 degrees indicate that the body
|
||||
* is visible in the morning sky before sunrise.
|
||||
* @param body1
|
||||
* The first body, whose longitude is to be found relative to the second body.
|
||||
*
|
||||
* @param body
|
||||
* The celestial body for which to find longitude from the Sun.
|
||||
* @param body2
|
||||
* The second body, relative to which the longitude of the first body is to be found.
|
||||
*
|
||||
* @param time
|
||||
* The date and time of the observation.
|
||||
@@ -5187,30 +5186,34 @@ astro_elongation_t Astronomy_SearchMaxElongation(astro_body_t body, astro_time_t
|
||||
* the `angle` field holds a value in the range [0, 360).
|
||||
* On failure, the `status` field contains some other value indicating an error condition.
|
||||
*/
|
||||
astro_angle_result_t Astronomy_LongitudeFromSun(astro_body_t body, astro_time_t time)
|
||||
astro_angle_result_t Astronomy_PairLongitude(
|
||||
astro_body_t body1,
|
||||
astro_body_t body2,
|
||||
astro_time_t time)
|
||||
{
|
||||
astro_vector_t sv, bv;
|
||||
astro_ecliptic_t se, be;
|
||||
astro_vector_t vector1, vector2;
|
||||
astro_ecliptic_t eclip1, eclip2;
|
||||
astro_angle_result_t result;
|
||||
|
||||
if (body == BODY_EARTH)
|
||||
if (body1 == BODY_EARTH || body2 == BODY_EARTH)
|
||||
return AngleError(ASTRO_EARTH_NOT_ALLOWED);
|
||||
|
||||
sv = Astronomy_GeoVector(BODY_SUN, time, NO_ABERRATION);
|
||||
se = Astronomy_Ecliptic(sv); /* checks for errors in sv */
|
||||
if (se.status != ASTRO_SUCCESS)
|
||||
return AngleError(se.status);
|
||||
vector1 = Astronomy_GeoVector(body1, time, NO_ABERRATION);
|
||||
eclip1 = Astronomy_Ecliptic(vector1); /* checks for errors in vector1 */
|
||||
if (eclip1.status != ASTRO_SUCCESS)
|
||||
return AngleError(eclip1.status);
|
||||
|
||||
bv = Astronomy_GeoVector(body, time, NO_ABERRATION);
|
||||
be = Astronomy_Ecliptic(bv); /* checks for errors in bv */
|
||||
if (be.status != ASTRO_SUCCESS)
|
||||
return AngleError(be.status);
|
||||
vector2 = Astronomy_GeoVector(body2, time, NO_ABERRATION);
|
||||
eclip2 = Astronomy_Ecliptic(vector2); /* checks for errors in vector2 */
|
||||
if (eclip2.status != ASTRO_SUCCESS)
|
||||
return AngleError(eclip2.status);
|
||||
|
||||
result.status = ASTRO_SUCCESS;
|
||||
result.angle = NormalizeLongitude(be.elon - se.elon);
|
||||
result.angle = NormalizeLongitude(eclip1.elon - eclip2.elon);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Returns the Moon's phase as an angle from 0 to 360 degrees.
|
||||
@@ -5237,7 +5240,7 @@ astro_angle_result_t Astronomy_LongitudeFromSun(astro_body_t body, astro_time_t
|
||||
*/
|
||||
astro_angle_result_t Astronomy_MoonPhase(astro_time_t time)
|
||||
{
|
||||
return Astronomy_LongitudeFromSun(BODY_MOON, time);
|
||||
return Astronomy_PairLongitude(BODY_MOON, BODY_SUN, time);
|
||||
}
|
||||
|
||||
static astro_func_result_t moon_offset(void *context, astro_time_t time)
|
||||
|
||||
@@ -992,7 +992,13 @@ astro_horizon_t Astronomy_Horizon(
|
||||
astro_angle_result_t Astronomy_AngleFromSun(astro_body_t body, astro_time_t time);
|
||||
astro_elongation_t Astronomy_Elongation(astro_body_t body, astro_time_t time);
|
||||
astro_elongation_t Astronomy_SearchMaxElongation(astro_body_t body, astro_time_t startTime);
|
||||
astro_angle_result_t Astronomy_LongitudeFromSun(astro_body_t body, astro_time_t time);
|
||||
astro_angle_result_t Astronomy_PairLongitude(astro_body_t body1, astro_body_t body2, astro_time_t time);
|
||||
|
||||
/** @cond DOXYGEN_SKIP */
|
||||
/* Provided for backward compatibility. Newer code can use Astronomy_PairLongitude. */
|
||||
#define Astronomy_LongitudeFromSun(body,time) (Astronomy_PairLongitude((body), BODY_SUN, (time)))
|
||||
/** @endcond */
|
||||
|
||||
astro_search_result_t Astronomy_SearchRelativeLongitude(astro_body_t body, double targetRelLon, astro_time_t startTime);
|
||||
astro_angle_result_t Astronomy_MoonPhase(astro_time_t time);
|
||||
astro_search_result_t Astronomy_SearchMoonPhase(double targetLon, astro_time_t startTime, double limitDays);
|
||||
|
||||
Reference in New Issue
Block a user