Functions: Lagrange Points
Functions for computing Lagrange point equilibrium positions in the Circular Restricted Three-Body Problem (CR3BP). Lagrange points are the five positions where a small body can maintain a stable (or quasi-stable) position relative to two larger bodies. L1, L2, and L3 are collinear (unstable), while L4 and L5 form equilateral triangles with the two primaries (stable for mass ratios below the Routh critical value). All functions in this section are IMMUTABLE STRICT PARALLEL SAFE.
lagrange_heliocentric
Section titled “lagrange_heliocentric”Heliocentric ecliptic J2000 position of a Sun-planet Lagrange point. The CR3BP quintic solver finds the equilibrium position in the co-rotating frame, which is then rotated into the inertial ecliptic frame using VSOP87 planetary positions.
Signature
Section titled “Signature”lagrange_heliocentric(body_id int4, point_id int4, t timestamptz) → heliocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier: 1=Mercury, 2=Venus, 3=Earth, 4=Mars, 5=Jupiter, 6=Saturn, 7=Uranus, 8=Neptune |
point_id | int4 | Lagrange point: 1=L1, 2=L2, 3=L3, 4=L4, 5=L5 |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”A heliocentric position in AU (ecliptic J2000 frame).
Example
Section titled “Example”-- Sun-Earth L1: SOHO lives here (~0.97 AU from Sun)SELECT round(helio_distance(lagrange_heliocentric(3, 1, '2000-01-01 12:00:00+00'))::numeric, 2) AS sun_dist_au;-- -> 0.97-- All planets' L1 distances from the SunSELECT body_id, round(helio_distance(lagrange_heliocentric(body_id, 1, '2000-01-01 12:00:00+00'))::numeric, 4) AS l1_dist_auFROM generate_series(1, 8) AS body_id;lagrange_observe
Section titled “lagrange_observe”Observe a Sun-planet Lagrange point from a ground station. Computes the heliocentric Lagrange position, subtracts Earth’s geocentric position, and transforms to topocentric azimuth/elevation.
Signature
Section titled “Signature”lagrange_observe(body_id int4, point_id int4, obs observer, t timestamptz) → topocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier: 1-8 (Mercury-Neptune) |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
obs | observer | Observer location on Earth |
t | timestamptz | Observation time |
Returns
Section titled “Returns”A topocentric with azimuth, elevation (degrees), range (km), and range rate (km/s).
Example
Section titled “Example”-- Where is the Sun-Earth L2 (JWST's home) from Greenwich?SELECT round(topo_azimuth(t)::numeric, 2) AS az, round(topo_elevation(t)::numeric, 2) AS elFROM lagrange_observe(3, 2, '51.4769N 0.0005W 0m'::observer, now()) AS t;lagrange_equatorial
Section titled “lagrange_equatorial”Geocentric RA/Dec of a Sun-planet Lagrange point. Converts the heliocentric ecliptic position to geocentric equatorial coordinates, precessed to the date of observation.
Signature
Section titled “Signature”lagrange_equatorial(body_id int4, point_id int4, t timestamptz) → equatorialParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier: 1-8 (Mercury-Neptune) |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”An equatorial with RA (hours), Dec (degrees), and distance (km).
Example
Section titled “Example”-- Sun-Earth L2 sky position (near the anti-solar point)SELECT round(eq_ra(lagrange_equatorial(3, 2, now()))::numeric, 4) AS ra_hours, round(eq_dec(lagrange_equatorial(3, 2, now()))::numeric, 4) AS dec_deg;lagrange_distance
Section titled “lagrange_distance”Distance (AU) from a heliocentric position to a Sun-planet Lagrange point. Computes the Lagrange point position at the given time and returns the Euclidean distance.
Signature
Section titled “Signature”lagrange_distance(body_id int4, point_id int4, pos heliocentric, t timestamptz) → float8Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier: 1-8 (Mercury-Neptune) |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
pos | heliocentric | Heliocentric position to measure from |
t | timestamptz | Evaluation time (determines the Lagrange point position) |
Returns
Section titled “Returns”Distance in AU from the given position to the Lagrange point.
Example
Section titled “Example”-- Self-test: distance from Jupiter L4 to itselfSELECT round(lagrange_distance( 5, 4, lagrange_heliocentric(5, 4, '2000-01-01 12:00:00+00'), '2000-01-01 12:00:00+00')::numeric, 10) AS self_distance;-- -> 0.0000000000lagrange_distance_oe
Section titled “lagrange_distance_oe”Distance (AU) from an asteroid or comet (specified by orbital_elements) to a Sun-planet Lagrange point. Propagates the small body’s orbit to the given time via Keplerian mechanics, then measures the distance to the computed Lagrange position.
Signature
Section titled “Signature”lagrange_distance_oe(body_id int4, point_id int4, oe orbital_elements, t timestamptz) → float8Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier: 1-8 (Mercury-Neptune) |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
oe | orbital_elements | Orbital elements for the asteroid or comet |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”Distance in AU.
Example
Section titled “Example”-- Check if (588) Achilles is near Jupiter's L4 (Trojan territory)SELECT round(lagrange_distance_oe( 5, 4, oe_from_mpc('00588 14.39 0.15 K249V 41.50128 169.10254 334.19917 13.04512 0.0760428 0.22963720 5.1763803 0 MPO752723 4285 88 1992-2024 0.49 M-v 30h MPCW 0000 (588) Achilles 20240913'), '2024-06-21 12:00:00+00')::numeric, 4) AS dist_au;lunar_lagrange_observe
Section titled “lunar_lagrange_observe”Observe an Earth-Moon Lagrange point from a ground station. The Earth-Moon system is implied --- no body_id is needed. The Moon’s position is computed via ELP2000-82B.
Signature
Section titled “Signature”lunar_lagrange_observe(point_id int4, obs observer, t timestamptz) → topocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
obs | observer | Observer location on Earth |
t | timestamptz | Observation time |
Returns
Section titled “Returns”A topocentric with azimuth, elevation (degrees), range (km), and range rate (km/s).
Example
Section titled “Example”-- Earth-Moon L1 from Boulder (Artemis Gateway territory)SELECT round(topo_elevation(lunar_lagrange_observe(1, '40.0N 105.3W 1655m'::observer, now()))::numeric, 2) AS el_deg;lunar_lagrange_equatorial
Section titled “lunar_lagrange_equatorial”Geocentric RA/Dec of an Earth-Moon Lagrange point. The L1 point lies between Earth and Moon at roughly 84% of the Earth-Moon distance.
Signature
Section titled “Signature”lunar_lagrange_equatorial(point_id int4, t timestamptz) → equatorialParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”An equatorial with RA (hours), Dec (degrees), and distance (km).
Example
Section titled “Example”-- Earth-Moon L1 distance (~326,000 km from Earth)SELECT round(eq_distance(lunar_lagrange_equatorial(1, '2000-01-01 12:00:00+00'))::numeric, 0) AS dist_km;galilean_lagrange_observe
Section titled “galilean_lagrange_observe”Observe a Jupiter-Galilean moon Lagrange point from a ground station. Uses L1.2 theory (Lieske 1998) for the Galilean moon position and VSOP87 for Jupiter’s heliocentric position.
Signature
Section titled “Signature”galilean_lagrange_observe(body_id int4, point_id int4, obs observer, t timestamptz) → topocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Galilean moon: 0=Io, 1=Europa, 2=Ganymede, 3=Callisto |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
obs | observer | Observer location on Earth |
t | timestamptz | Observation time |
Returns
Section titled “Returns”A topocentric with azimuth, elevation (degrees), range (km), and range rate (km/s).
Example
Section titled “Example”-- Jupiter-Ganymede L3 from GreenwichSELECT round(topo_elevation(galilean_lagrange_observe(2, 3, '51.4769N 0.0005W 0m'::observer, now()))::numeric, 2) AS el_deg;galilean_lagrange_equatorial
Section titled “galilean_lagrange_equatorial”Geocentric RA/Dec of a Jupiter-Galilean moon Lagrange point.
Signature
Section titled “Signature”galilean_lagrange_equatorial(body_id int4, point_id int4, t timestamptz) → equatorialParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Galilean moon: 0=Io, 1=Europa, 2=Ganymede, 3=Callisto |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”An equatorial with RA (hours), Dec (degrees), and distance (km).
Example
Section titled “Example”-- Jupiter-Io L4 sky positionSELECT round(eq_ra(galilean_lagrange_equatorial(0, 4, now()))::numeric, 4) AS ra_hours, round(eq_dec(galilean_lagrange_equatorial(0, 4, now()))::numeric, 4) AS dec_deg;saturn_moon_lagrange_observe
Section titled “saturn_moon_lagrange_observe”Observe a Saturn moon Lagrange point from a ground station. Uses TASS17 theory (Vienne & Duriez 1995) for the moon position and VSOP87 for Saturn’s heliocentric position.
Signature
Section titled “Signature”saturn_moon_lagrange_observe(body_id int4, point_id int4, obs observer, t timestamptz) → topocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Saturn moon: 0=Mimas, 1=Enceladus, 2=Tethys, 3=Dione, 4=Rhea, 5=Titan, 6=Iapetus, 7=Hyperion |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
obs | observer | Observer location on Earth |
t | timestamptz | Observation time |
Returns
Section titled “Returns”A topocentric with azimuth, elevation (degrees), range (km), and range rate (km/s).
Example
Section titled “Example”-- Saturn-Titan L1 from BoulderSELECT round(topo_azimuth(t)::numeric, 2) AS az, round(topo_elevation(t)::numeric, 2) AS elFROM saturn_moon_lagrange_observe(5, 1, '40.0N 105.3W 1655m'::observer, now()) AS t;saturn_moon_lagrange_equatorial
Section titled “saturn_moon_lagrange_equatorial”Geocentric RA/Dec of a Saturn moon Lagrange point.
Signature
Section titled “Signature”saturn_moon_lagrange_equatorial(body_id int4, point_id int4, t timestamptz) → equatorialParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Saturn moon: 0=Mimas, 1=Enceladus, 2=Tethys, 3=Dione, 4=Rhea, 5=Titan, 6=Iapetus, 7=Hyperion |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”An equatorial with RA (hours), Dec (degrees), and distance (km).
Example
Section titled “Example”-- Saturn-Titan L1 sky positionSELECT round(eq_ra(saturn_moon_lagrange_equatorial(5, 1, now()))::numeric, 4) AS ra_hours;uranus_moon_lagrange_observe
Section titled “uranus_moon_lagrange_observe”Observe a Uranus moon Lagrange point from a ground station. Uses GUST86 theory (Laskar & Jacobson 1987) for the moon position and VSOP87 for Uranus’s heliocentric position.
Signature
Section titled “Signature”uranus_moon_lagrange_observe(body_id int4, point_id int4, obs observer, t timestamptz) → topocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Uranus moon: 0=Miranda, 1=Ariel, 2=Umbriel, 3=Titania, 4=Oberon |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
obs | observer | Observer location on Earth |
t | timestamptz | Observation time |
Returns
Section titled “Returns”A topocentric with azimuth, elevation (degrees), range (km), and range rate (km/s).
Example
Section titled “Example”-- Uranus-Titania L2 from GreenwichSELECT round(topo_elevation(uranus_moon_lagrange_observe(3, 2, '51.4769N 0.0005W 0m'::observer, now()))::numeric, 2) AS el_deg;uranus_moon_lagrange_equatorial
Section titled “uranus_moon_lagrange_equatorial”Geocentric RA/Dec of a Uranus moon Lagrange point.
Signature
Section titled “Signature”uranus_moon_lagrange_equatorial(body_id int4, point_id int4, t timestamptz) → equatorialParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Uranus moon: 0=Miranda, 1=Ariel, 2=Umbriel, 3=Titania, 4=Oberon |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”An equatorial with RA (hours), Dec (degrees), and distance (km).
Example
Section titled “Example”-- Uranus-Oberon L4 sky positionSELECT round(eq_ra(uranus_moon_lagrange_equatorial(4, 4, now()))::numeric, 4) AS ra_hours, round(eq_dec(uranus_moon_lagrange_equatorial(4, 4, now()))::numeric, 4) AS dec_deg;mars_moon_lagrange_observe
Section titled “mars_moon_lagrange_observe”Observe a Mars moon Lagrange point from a ground station. Uses MarsSat theory (Jacobson 2014) for the moon position and VSOP87 for Mars’s heliocentric position.
Signature
Section titled “Signature”mars_moon_lagrange_observe(body_id int4, point_id int4, obs observer, t timestamptz) → topocentricParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Mars moon: 0=Phobos, 1=Deimos |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
obs | observer | Observer location on Earth |
t | timestamptz | Observation time |
Returns
Section titled “Returns”A topocentric with azimuth, elevation (degrees), range (km), and range rate (km/s).
Example
Section titled “Example”-- Mars-Phobos L1 from BoulderSELECT round(topo_azimuth(t)::numeric, 2) AS az, round(topo_elevation(t)::numeric, 2) AS elFROM mars_moon_lagrange_observe(0, 1, '40.0N 105.3W 1655m'::observer, now()) AS t;mars_moon_lagrange_equatorial
Section titled “mars_moon_lagrange_equatorial”Geocentric RA/Dec of a Mars moon Lagrange point.
Signature
Section titled “Signature”mars_moon_lagrange_equatorial(body_id int4, point_id int4, t timestamptz) → equatorialParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Mars moon: 0=Phobos, 1=Deimos |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”An equatorial with RA (hours), Dec (degrees), and distance (km).
Example
Section titled “Example”-- Mars-Deimos L5 sky positionSELECT round(eq_ra(mars_moon_lagrange_equatorial(1, 5, now()))::numeric, 4) AS ra_hours, round(eq_dec(mars_moon_lagrange_equatorial(1, 5, now()))::numeric, 4) AS dec_deg;hill_radius
Section titled “hill_radius”Hill sphere radius (AU) for a Sun-planet system. The Hill sphere is the region where a planet’s gravity dominates over the Sun’s --- objects beyond this radius are more strongly influenced by the Sun. Computed as r_H = a * (m_p / (3 * m_sun))^(1/3), where a is the instantaneous Sun-planet distance from VSOP87.
Signature
Section titled “Signature”hill_radius(body_id int4, t timestamptz) → float8Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier: 1-8 (Mercury-Neptune) |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”Hill sphere radius in AU.
Example
Section titled “Example”-- Jupiter's Hill sphere (~0.35 AU)SELECT round(hill_radius(5, '2000-01-01 12:00:00+00')::numeric, 3) AS jupiter_hill_au;-- All planetsSELECT body_id, round(hill_radius(body_id, '2000-01-01 12:00:00+00')::numeric, 4) AS hill_auFROM generate_series(1, 8) AS body_id;hill_radius_lunar
Section titled “hill_radius_lunar”Hill sphere radius (AU) for the Earth-Moon system. Much smaller than planetary Hill spheres since the Moon is far less massive relative to Earth than planets are relative to the Sun.
Signature
Section titled “Signature”hill_radius_lunar(t timestamptz) → float8Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”Hill sphere radius in AU.
Example
Section titled “Example”SELECT hill_radius_lunar('2000-01-01 12:00:00+00') AS lunar_hill_au;lagrange_zone_radius
Section titled “lagrange_zone_radius”Approximate libration zone radius (AU) around a Sun-planet Lagrange point. For L4/L5, this is related to the tadpole/horseshoe orbit domain where Trojan asteroids can remain trapped. For collinear points (L1/L2/L3), it is the linearized stability boundary.
Signature
Section titled “Signature”lagrange_zone_radius(body_id int4, point_id int4, t timestamptz) → float8Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier: 1-8 (Mercury-Neptune) |
point_id | int4 | Lagrange point: 1-5 (L1-L5) |
t | timestamptz | Evaluation time |
Returns
Section titled “Returns”Zone radius in AU.
Example
Section titled “Example”-- Jupiter L4 libration zone (Trojan swarm extent)SELECT round(lagrange_zone_radius(5, 4, '2000-01-01 12:00:00+00')::numeric, 4) AS zone_au;lagrange_mass_ratio
Section titled “lagrange_mass_ratio”CR3BP mass parameter mu = M_planet / (M_sun + M_planet). A diagnostic function useful for verifying the CR3BP solver or understanding the relative gravitational influence of a planet in its system.
Signature
Section titled “Signature”lagrange_mass_ratio(body_id int4) → float8Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
body_id | int4 | Planet identifier: 1-8 (Mercury-Neptune) |
Returns
Section titled “Returns”Dimensionless mass ratio (small positive number; Jupiter is ~0.001, Earth is ~0.000003).
Example
Section titled “Example”SELECT lagrange_mass_ratio(5) AS jupiter_mu, lagrange_mass_ratio(3) AS earth_mu;lagrange_point_name
Section titled “lagrange_point_name”Human-readable name for a Lagrange point ID. A simple lookup that converts integer IDs to their standard labels.
Signature
Section titled “Signature”lagrange_point_name(point_id int4) → textParameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
point_id | int4 | Lagrange point: 1-5 |
Returns
Section titled “Returns”Text label: 'L1', 'L2', 'L3', 'L4', or 'L5'.
Example
Section titled “Example”SELECT lagrange_point_name(1) AS name;-- -> 'L1'-- Use in a query for readable outputSELECT lagrange_point_name(p) AS point, round(helio_distance(lagrange_heliocentric(3, p, now()))::numeric, 4) AS sun_dist_auFROM generate_series(1, 5) AS p;