@typescriptify/sweph 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +422 -0
- package/ephe/semo_18.se1 +0 -0
- package/ephe/sepl_18.se1 +0 -0
- package/originalCode/.eslintrc.json +124 -0
- package/originalCode/.gitattributes +2 -0
- package/originalCode/.github/FUNDING.yml +5 -0
- package/originalCode/.github/workflows/test.yml +35 -0
- package/originalCode/LICENSE +840 -0
- package/originalCode/README.md +91 -0
- package/originalCode/binding.gyp +41 -0
- package/originalCode/constants.js +366 -0
- package/originalCode/docs.gif +0 -0
- package/originalCode/index.d.ts +5115 -0
- package/originalCode/index.js +7 -0
- package/originalCode/index.mjs +109 -0
- package/originalCode/package.json +55 -0
- package/originalCode/src/functions/azalt.cpp +39 -0
- package/originalCode/src/functions/azalt_rev.cpp +35 -0
- package/originalCode/src/functions/calc.cpp +29 -0
- package/originalCode/src/functions/calc_pctr.cpp +31 -0
- package/originalCode/src/functions/calc_ut.cpp +29 -0
- package/originalCode/src/functions/close.cpp +6 -0
- package/originalCode/src/functions/cotrans.cpp +26 -0
- package/originalCode/src/functions/cotrans_sp.cpp +26 -0
- package/originalCode/src/functions/cs2degstr.cpp +19 -0
- package/originalCode/src/functions/cs2lonlatstr.cpp +23 -0
- package/originalCode/src/functions/cs2timestr.cpp +23 -0
- package/originalCode/src/functions/csnorm.cpp +15 -0
- package/originalCode/src/functions/csroundsec.cpp +15 -0
- package/originalCode/src/functions/d2l.cpp +15 -0
- package/originalCode/src/functions/date_conversion.cpp +30 -0
- package/originalCode/src/functions/day_of_week.cpp +15 -0
- package/originalCode/src/functions/degnorm.cpp +15 -0
- package/originalCode/src/functions/deltat.cpp +15 -0
- package/originalCode/src/functions/deltat_ex.cpp +24 -0
- package/originalCode/src/functions/difcs2n.cpp +19 -0
- package/originalCode/src/functions/difcsn.cpp +19 -0
- package/originalCode/src/functions/difdeg2n.cpp +19 -0
- package/originalCode/src/functions/difdegn.cpp +19 -0
- package/originalCode/src/functions/fixstar.cpp +32 -0
- package/originalCode/src/functions/fixstar2.cpp +32 -0
- package/originalCode/src/functions/fixstar2_mag.cpp +28 -0
- package/originalCode/src/functions/fixstar2_ut.cpp +32 -0
- package/originalCode/src/functions/fixstar_mag.cpp +28 -0
- package/originalCode/src/functions/fixstar_ut.cpp +32 -0
- package/originalCode/src/functions/gauquelin_sector.cpp +44 -0
- package/originalCode/src/functions/get_ayanamsa.cpp +15 -0
- package/originalCode/src/functions/get_ayanamsa_ex.cpp +27 -0
- package/originalCode/src/functions/get_ayanamsa_ex_ut.cpp +27 -0
- package/originalCode/src/functions/get_ayanamsa_name.cpp +19 -0
- package/originalCode/src/functions/get_ayanamsa_ut.cpp +15 -0
- package/originalCode/src/functions/get_current_file_data.cpp +28 -0
- package/originalCode/src/functions/get_library_path.cpp +8 -0
- package/originalCode/src/functions/get_orbital_elements.cpp +29 -0
- package/originalCode/src/functions/get_planet_name.cpp +19 -0
- package/originalCode/src/functions/get_tid_acc.cpp +7 -0
- package/originalCode/src/functions/heliacal_pheno_ut.cpp +52 -0
- package/originalCode/src/functions/heliacal_ut.cpp +52 -0
- package/originalCode/src/functions/helio_cross.cpp +33 -0
- package/originalCode/src/functions/helio_cross_ut.cpp +33 -0
- package/originalCode/src/functions/house_name.cpp +20 -0
- package/originalCode/src/functions/house_pos.cpp +36 -0
- package/originalCode/src/functions/houses.cpp +35 -0
- package/originalCode/src/functions/houses_armc.cpp +38 -0
- package/originalCode/src/functions/houses_armc_ex2.cpp +47 -0
- package/originalCode/src/functions/houses_ex.cpp +37 -0
- package/originalCode/src/functions/houses_ex2.cpp +46 -0
- package/originalCode/src/functions/jdet_to_utc.cpp +38 -0
- package/originalCode/src/functions/jdut1_to_utc.cpp +38 -0
- package/originalCode/src/functions/julday.cpp +25 -0
- package/originalCode/src/functions/lat_to_lmt.cpp +27 -0
- package/originalCode/src/functions/lmt_to_lat.cpp +27 -0
- package/originalCode/src/functions/lun_eclipse_how.cpp +34 -0
- package/originalCode/src/functions/lun_eclipse_when.cpp +31 -0
- package/originalCode/src/functions/lun_eclipse_when_loc.cpp +39 -0
- package/originalCode/src/functions/lun_occult_when_glob.cpp +35 -0
- package/originalCode/src/functions/lun_occult_when_loc.cpp +43 -0
- package/originalCode/src/functions/lun_occult_where.cpp +34 -0
- package/originalCode/src/functions/mooncross.cpp +26 -0
- package/originalCode/src/functions/mooncross_node.cpp +30 -0
- package/originalCode/src/functions/mooncross_node_ut.cpp +30 -0
- package/originalCode/src/functions/mooncross_ut.cpp +26 -0
- package/originalCode/src/functions/nod_aps.cpp +42 -0
- package/originalCode/src/functions/nod_aps_ut.cpp +42 -0
- package/originalCode/src/functions/orbit_max_min_true_distance.cpp +37 -0
- package/originalCode/src/functions/pheno.cpp +29 -0
- package/originalCode/src/functions/pheno_ut.cpp +29 -0
- package/originalCode/src/functions/radnorm.cpp +15 -0
- package/originalCode/src/functions/refrac.cpp +23 -0
- package/originalCode/src/functions/refrac_extended.cpp +32 -0
- package/originalCode/src/functions/revjul.cpp +33 -0
- package/originalCode/src/functions/rise_trans.cpp +44 -0
- package/originalCode/src/functions/rise_trans_true_hor.cpp +46 -0
- package/originalCode/src/functions/set_delta_t_userdef.cpp +14 -0
- package/originalCode/src/functions/set_ephe_path.cpp +14 -0
- package/originalCode/src/functions/set_jpl_file.cpp +14 -0
- package/originalCode/src/functions/set_sid_mode.cpp +20 -0
- package/originalCode/src/functions/set_tid_acc.cpp +14 -0
- package/originalCode/src/functions/set_topo.cpp +20 -0
- package/originalCode/src/functions/sidtime.cpp +15 -0
- package/originalCode/src/functions/sidtime0.cpp +21 -0
- package/originalCode/src/functions/sol_eclipse_how.cpp +34 -0
- package/originalCode/src/functions/sol_eclipse_when_glob.cpp +31 -0
- package/originalCode/src/functions/sol_eclipse_when_loc.cpp +39 -0
- package/originalCode/src/functions/sol_eclipse_where.cpp +30 -0
- package/originalCode/src/functions/solcross.cpp +26 -0
- package/originalCode/src/functions/solcross_ut.cpp +26 -0
- package/originalCode/src/functions/split_deg.cpp +35 -0
- package/originalCode/src/functions/time_equ.cpp +25 -0
- package/originalCode/src/functions/utc_time_zone.cpp +48 -0
- package/originalCode/src/functions/utc_to_jd.cpp +37 -0
- package/originalCode/src/functions/version.cpp +8 -0
- package/originalCode/src/functions/vis_limit_mag.cpp +50 -0
- package/originalCode/src/sweph.cpp +150 -0
- package/originalCode/src/sweph.h +119 -0
- package/originalCode/swisseph/swecl.c +6428 -0
- package/originalCode/swisseph/swedate.c +588 -0
- package/originalCode/swisseph/swedate.h +81 -0
- package/originalCode/swisseph/swehel.c +3511 -0
- package/originalCode/swisseph/swehouse.c +3143 -0
- package/originalCode/swisseph/swehouse.h +98 -0
- package/originalCode/swisseph/swejpl.c +958 -0
- package/originalCode/swisseph/swejpl.h +103 -0
- package/originalCode/swisseph/swemmoon.c +1930 -0
- package/originalCode/swisseph/swemplan.c +967 -0
- package/originalCode/swisseph/swemptab.h +10640 -0
- package/originalCode/swisseph/swenut2000a.h +2819 -0
- package/originalCode/swisseph/sweodef.h +326 -0
- package/originalCode/swisseph/sweph.c +8614 -0
- package/originalCode/swisseph/sweph.h +849 -0
- package/originalCode/swisseph/swephexp.h +1020 -0
- package/originalCode/swisseph/swephlib.c +4634 -0
- package/originalCode/swisseph/swephlib.h +189 -0
- package/package.json +28 -0
- package/scripts/gen-swemptab.js +177 -0
- package/scripts/gen-swenut2000a.js +106 -0
- package/src/SwissEph/README.md +268 -0
- package/src/SwissEph/UseCases/Ayanamsa.md +363 -0
- package/src/SwissEph/UseCases/AzimuthAltitude.md +408 -0
- package/src/SwissEph/UseCases/CoordinateSystems.md +337 -0
- package/src/SwissEph/UseCases/DateAndTime.md +368 -0
- package/src/SwissEph/UseCases/DeltaT.md +258 -0
- package/src/SwissEph/UseCases/EphemerisFiles.md +338 -0
- package/src/SwissEph/UseCases/FixedStars.md +300 -0
- package/src/SwissEph/UseCases/GauquelinSectors.md +304 -0
- package/src/SwissEph/UseCases/HeliacalEvents.md +396 -0
- package/src/SwissEph/UseCases/HelioCrossings.md +325 -0
- package/src/SwissEph/UseCases/HousePosition.md +254 -0
- package/src/SwissEph/UseCases/HouseSystems.md +279 -0
- package/src/SwissEph/UseCases/LunarEclipse.md +326 -0
- package/src/SwissEph/UseCases/MeridianTransit.md +279 -0
- package/src/SwissEph/UseCases/MoonCrossings.md +373 -0
- package/src/SwissEph/UseCases/NodesAndApsides.md +307 -0
- package/src/SwissEph/UseCases/Occultation.md +352 -0
- package/src/SwissEph/UseCases/OrbitalElements.md +469 -0
- package/src/SwissEph/UseCases/Phenomena.md +328 -0
- package/src/SwissEph/UseCases/PlanetPositions.md +366 -0
- package/src/SwissEph/UseCases/Planetocentric.md +278 -0
- package/src/SwissEph/UseCases/Refraction.md +314 -0
- package/src/SwissEph/UseCases/RiseAndSet.md +433 -0
- package/src/SwissEph/UseCases/SiderealTime.md +302 -0
- package/src/SwissEph/UseCases/SolarEclipse.md +379 -0
- package/src/SwissEph/UseCases/SunCrossings.md +275 -0
- package/src/SwissEph/UseCases/TopocentricCorrection.md +335 -0
- package/src/SwissEph/errors.ts +10 -0
- package/src/SwissEph/index.ts +823 -0
- package/src/SwissEph/types.ts +291 -0
- package/src/constants.ts +762 -0
- package/src/file-reader.ts +147 -0
- package/src/index.ts +10 -0
- package/src/swecl.ts +4526 -0
- package/src/swedate.ts +376 -0
- package/src/swehel.ts +1939 -0
- package/src/swehouse.ts +2167 -0
- package/src/swejpl.ts +470 -0
- package/src/swemmoon.ts +1318 -0
- package/src/swemplan.ts +585 -0
- package/src/swemptab.ts +4448 -0
- package/src/swenut2000a.ts +2763 -0
- package/src/sweph.ts +3993 -0
- package/src/swephlib.ts +2720 -0
- package/src/types.ts +490 -0
- package/tests/c-style/ayanamsa.test.ts +63 -0
- package/tests/c-style/config.test.ts +96 -0
- package/tests/c-style/crossings.test.ts +81 -0
- package/tests/c-style/date-time.test.ts +114 -0
- package/tests/c-style/eclipses.test.ts +84 -0
- package/tests/c-style/fixed-stars.test.ts +66 -0
- package/tests/c-style/heliacal.test.ts +34 -0
- package/tests/c-style/houses.test.ts +135 -0
- package/tests/c-style/math-utils.test.ts +160 -0
- package/tests/c-style/orbital.test.ts +78 -0
- package/tests/c-style/phenomena.test.ts +42 -0
- package/tests/c-style/planetocentric.test.ts +26 -0
- package/tests/c-style/planets.test.ts +117 -0
- package/tests/c-style/rise-set.test.ts +71 -0
- package/tests/helpers.ts +21 -0
- package/tests/modern/ayanamsa.test.ts +47 -0
- package/tests/modern/calc.test.ts +113 -0
- package/tests/modern/config.test.ts +46 -0
- package/tests/modern/crossings.test.ts +45 -0
- package/tests/modern/eclipses.test.ts +81 -0
- package/tests/modern/errors.test.ts +71 -0
- package/tests/modern/heliacal.test.ts +30 -0
- package/tests/modern/houses.test.ts +87 -0
- package/tests/modern/orbital.test.ts +79 -0
- package/tests/modern/phenomena.test.ts +41 -0
- package/tests/modern/rise-set.test.ts +60 -0
- package/tests/modern/statics.test.ts +99 -0
- package/tests/modern/utilities.test.ts +70 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
# Orbital Elements
|
|
2
|
+
|
|
3
|
+
**Keplerian orbital elements** are the six numbers that completely define the shape, orientation, and timing of an orbit. They are the language of celestial mechanics -- given these six values, you can reconstruct the exact path of a planet around the Sun and predict where it will be at any moment.
|
|
4
|
+
|
|
5
|
+
This library provides three related methods:
|
|
6
|
+
- **`orbitalElements(jd, planet)`** -- returns the six classical elements plus derived quantities like period and daily motion
|
|
7
|
+
- **`orbitDistances(jd, planet)`** -- returns the maximum, minimum, and current distance of the planet
|
|
8
|
+
- **`nodesApsides(jd, planet)`** -- returns the positions of the orbital nodes and apsides (perihelion/aphelion) as full position objects
|
|
9
|
+
|
|
10
|
+
These are useful for:
|
|
11
|
+
- Understanding the physical structure of planetary orbits
|
|
12
|
+
- Computing orbital periods (how long a "year" is on each planet)
|
|
13
|
+
- Finding closest/farthest approaches
|
|
14
|
+
- Understanding why planets speed up and slow down
|
|
15
|
+
- Astronomical education and visualization
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Quick Example
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { SwissEph } from '../index';
|
|
23
|
+
import { SE_MARS } from '../../constants';
|
|
24
|
+
|
|
25
|
+
const swe = new SwissEph();
|
|
26
|
+
const jd = SwissEph.julianDay(2025, 1, 1, 0);
|
|
27
|
+
|
|
28
|
+
const elem = swe.orbitalElements(jd, SE_MARS);
|
|
29
|
+
|
|
30
|
+
console.log(`Mars orbital elements at J2025.0:`);
|
|
31
|
+
console.log(` Semi-major axis: ${elem.semiAxis.toFixed(4)} AU`);
|
|
32
|
+
console.log(` Eccentricity: ${elem.eccentricity.toFixed(6)}`);
|
|
33
|
+
console.log(` Inclination: ${elem.inclination.toFixed(4)}°`);
|
|
34
|
+
console.log(` Ascending node: ${elem.ascNode.toFixed(4)}°`);
|
|
35
|
+
console.log(` Arg of perihelion: ${elem.argPerihelion.toFixed(4)}°`);
|
|
36
|
+
console.log(` Mean anomaly: ${elem.meanAnomaly.toFixed(4)}°`);
|
|
37
|
+
console.log(` Tropical period: ${elem.tropicalPeriod.toFixed(4)} years`);
|
|
38
|
+
console.log(` Synodic period: ${elem.synodicPeriod.toFixed(1)} days`);
|
|
39
|
+
|
|
40
|
+
swe.close();
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Detailed Examples
|
|
46
|
+
|
|
47
|
+
### Orbital elements for all planets
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import { SwissEph } from '../index';
|
|
51
|
+
import {
|
|
52
|
+
SE_MERCURY, SE_VENUS, SE_EARTH, SE_MARS,
|
|
53
|
+
SE_JUPITER, SE_SATURN, SE_URANUS, SE_NEPTUNE, SE_PLUTO,
|
|
54
|
+
} from '../../constants';
|
|
55
|
+
|
|
56
|
+
const swe = new SwissEph();
|
|
57
|
+
const jd = SwissEph.julianDay(2025, 1, 1, 0);
|
|
58
|
+
|
|
59
|
+
const planets = [
|
|
60
|
+
{ id: SE_MERCURY, name: 'Mercury' },
|
|
61
|
+
{ id: SE_VENUS, name: 'Venus' },
|
|
62
|
+
{ id: SE_EARTH, name: 'Earth' },
|
|
63
|
+
{ id: SE_MARS, name: 'Mars' },
|
|
64
|
+
{ id: SE_JUPITER, name: 'Jupiter' },
|
|
65
|
+
{ id: SE_SATURN, name: 'Saturn' },
|
|
66
|
+
{ id: SE_URANUS, name: 'Uranus' },
|
|
67
|
+
{ id: SE_NEPTUNE, name: 'Neptune' },
|
|
68
|
+
{ id: SE_PLUTO, name: 'Pluto' },
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
console.log('Planet a (AU) e i (°) Period (yr)');
|
|
72
|
+
console.log('---------- ------- ------- ------- -----------');
|
|
73
|
+
|
|
74
|
+
for (const pl of planets) {
|
|
75
|
+
const elem = swe.orbitalElements(jd, pl.id);
|
|
76
|
+
console.log(
|
|
77
|
+
`${pl.name.padEnd(10)} ` +
|
|
78
|
+
`${elem.semiAxis.toFixed(4).padStart(7)} ` +
|
|
79
|
+
`${elem.eccentricity.toFixed(5).padStart(7)} ` +
|
|
80
|
+
`${elem.inclination.toFixed(3).padStart(7)} ` +
|
|
81
|
+
`${elem.tropicalPeriod.toFixed(3).padStart(11)}`
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
swe.close();
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Getting orbital distances
|
|
89
|
+
|
|
90
|
+
The `orbitDistances()` method gives you the maximum, minimum, and current (true) distance from the Sun (for heliocentric) or from Earth (for geocentric, the default):
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import { SwissEph } from '../index';
|
|
94
|
+
import {
|
|
95
|
+
SE_MARS, SE_JUPITER, SE_SATURN, SE_VENUS,
|
|
96
|
+
} from '../../constants';
|
|
97
|
+
|
|
98
|
+
const swe = new SwissEph();
|
|
99
|
+
const jd = SwissEph.julianDay(2025, 6, 15, 0);
|
|
100
|
+
|
|
101
|
+
const planets = [
|
|
102
|
+
{ id: SE_VENUS, name: 'Venus' },
|
|
103
|
+
{ id: SE_MARS, name: 'Mars' },
|
|
104
|
+
{ id: SE_JUPITER, name: 'Jupiter' },
|
|
105
|
+
{ id: SE_SATURN, name: 'Saturn' },
|
|
106
|
+
];
|
|
107
|
+
|
|
108
|
+
console.log('Planet Current (AU) Min (AU) Max (AU)');
|
|
109
|
+
console.log('--------- ----------- -------- --------');
|
|
110
|
+
|
|
111
|
+
for (const pl of planets) {
|
|
112
|
+
const dist = swe.orbitDistances(jd, pl.id);
|
|
113
|
+
console.log(
|
|
114
|
+
`${pl.name.padEnd(9)} ` +
|
|
115
|
+
`${dist.true.toFixed(4).padStart(11)} ` +
|
|
116
|
+
`${dist.min.toFixed(4).padStart(8)} ` +
|
|
117
|
+
`${dist.max.toFixed(4).padStart(8)}`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
swe.close();
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Nodes and apsides with different methods
|
|
125
|
+
|
|
126
|
+
The `nodesApsides()` method returns the positions of a planet's orbital nodes (where its orbit crosses the ecliptic) and apsides (perihelion and aphelion). There are several computation methods:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
import { SwissEph } from '../index';
|
|
130
|
+
import {
|
|
131
|
+
SE_MARS,
|
|
132
|
+
SE_NODBIT_MEAN, SE_NODBIT_OSCU, SE_NODBIT_OSCU_BAR, SE_NODBIT_FOPOINT,
|
|
133
|
+
} from '../../constants';
|
|
134
|
+
|
|
135
|
+
const swe = new SwissEph();
|
|
136
|
+
const jd = SwissEph.julianDay(2025, 1, 1, 0);
|
|
137
|
+
|
|
138
|
+
// Method 1: Mean nodes/apsides (long-term average, smoothly moving)
|
|
139
|
+
const mean = swe.nodesApsides(jd, SE_MARS, SE_NODBIT_MEAN);
|
|
140
|
+
console.log('Mean nodes/apsides:');
|
|
141
|
+
console.log(` Ascending node: ${mean.ascendingNode.longitude.toFixed(4)}°`);
|
|
142
|
+
console.log(` Descending node: ${mean.descendingNode.longitude.toFixed(4)}°`);
|
|
143
|
+
console.log(` Perihelion: ${mean.perihelion.longitude.toFixed(4)}° (dist: ${mean.perihelion.distance.toFixed(4)} AU)`);
|
|
144
|
+
console.log(` Aphelion: ${mean.aphelion.longitude.toFixed(4)}° (dist: ${mean.aphelion.distance.toFixed(4)} AU)`);
|
|
145
|
+
|
|
146
|
+
// Method 2: Osculating nodes/apsides (instantaneous, includes perturbations)
|
|
147
|
+
const oscu = swe.nodesApsides(jd, SE_MARS, SE_NODBIT_OSCU);
|
|
148
|
+
console.log('\nOsculating nodes/apsides:');
|
|
149
|
+
console.log(` Ascending node: ${oscu.ascendingNode.longitude.toFixed(4)}°`);
|
|
150
|
+
console.log(` Descending node: ${oscu.descendingNode.longitude.toFixed(4)}°`);
|
|
151
|
+
console.log(` Perihelion: ${oscu.perihelion.longitude.toFixed(4)}°`);
|
|
152
|
+
console.log(` Aphelion: ${oscu.aphelion.longitude.toFixed(4)}°`);
|
|
153
|
+
|
|
154
|
+
// Method 3: Osculating with barycentric computation (more accurate for outer planets)
|
|
155
|
+
const bar = swe.nodesApsides(jd, SE_MARS, SE_NODBIT_OSCU_BAR);
|
|
156
|
+
console.log('\nOsculating (barycentric):');
|
|
157
|
+
console.log(` Ascending node: ${bar.ascendingNode.longitude.toFixed(4)}°`);
|
|
158
|
+
console.log(` Perihelion: ${bar.perihelion.longitude.toFixed(4)}°`);
|
|
159
|
+
|
|
160
|
+
swe.close();
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Comparing perihelion distance to orbit eccentricity
|
|
164
|
+
|
|
165
|
+
The perihelion and aphelion distances are directly related to the semi-major axis and eccentricity:
|
|
166
|
+
- Perihelion distance = a * (1 - e)
|
|
167
|
+
- Aphelion distance = a * (1 + e)
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
import { SwissEph } from '../index';
|
|
171
|
+
import { SE_MARS, SE_NODBIT_MEAN } from '../../constants';
|
|
172
|
+
|
|
173
|
+
const swe = new SwissEph();
|
|
174
|
+
const jd = SwissEph.julianDay(2025, 1, 1, 0);
|
|
175
|
+
|
|
176
|
+
const elem = swe.orbitalElements(jd, SE_MARS);
|
|
177
|
+
const nodes = swe.nodesApsides(jd, SE_MARS, SE_NODBIT_MEAN);
|
|
178
|
+
|
|
179
|
+
console.log('Mars orbit verification:');
|
|
180
|
+
console.log(` Semi-major axis a = ${elem.semiAxis.toFixed(6)} AU`);
|
|
181
|
+
console.log(` Eccentricity e = ${elem.eccentricity.toFixed(6)}`);
|
|
182
|
+
console.log();
|
|
183
|
+
|
|
184
|
+
const computedPeri = elem.semiAxis * (1 - elem.eccentricity);
|
|
185
|
+
const computedAph = elem.semiAxis * (1 + elem.eccentricity);
|
|
186
|
+
|
|
187
|
+
console.log(` Perihelion (computed a*(1-e)): ${computedPeri.toFixed(6)} AU`);
|
|
188
|
+
console.log(` Perihelion (from nodesApsides): ${nodes.perihelion.distance.toFixed(6)} AU`);
|
|
189
|
+
console.log();
|
|
190
|
+
console.log(` Aphelion (computed a*(1+e)): ${computedAph.toFixed(6)} AU`);
|
|
191
|
+
console.log(` Aphelion (from nodesApsides): ${nodes.aphelion.distance.toFixed(6)} AU`);
|
|
192
|
+
|
|
193
|
+
swe.close();
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Using the focal point (SE_NODBIT_FOPOINT)
|
|
197
|
+
|
|
198
|
+
The `SE_NODBIT_FOPOINT` flag replaces the aphelion with the **second focus** of the elliptical orbit. An ellipse has two foci; the Sun is at one focus, and the second focus is the empty point on the opposite side. Combined with `SE_NODBIT_OSCU`, this gives you the osculating second focus:
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
import { SwissEph } from '../index';
|
|
202
|
+
import { SE_MARS, SE_NODBIT_OSCU, SE_NODBIT_FOPOINT } from '../../constants';
|
|
203
|
+
|
|
204
|
+
const swe = new SwissEph();
|
|
205
|
+
const jd = SwissEph.julianDay(2025, 1, 1, 0);
|
|
206
|
+
|
|
207
|
+
// Combine flags with bitwise OR
|
|
208
|
+
const method = SE_NODBIT_OSCU | SE_NODBIT_FOPOINT;
|
|
209
|
+
const result = swe.nodesApsides(jd, SE_MARS, method);
|
|
210
|
+
|
|
211
|
+
console.log('Mars osculating orbit:');
|
|
212
|
+
console.log(` Ascending node: ${result.ascendingNode.longitude.toFixed(4)}°`);
|
|
213
|
+
console.log(` Descending node: ${result.descendingNode.longitude.toFixed(4)}°`);
|
|
214
|
+
console.log(` Perihelion: ${result.perihelion.longitude.toFixed(4)}° at ${result.perihelion.distance.toFixed(4)} AU`);
|
|
215
|
+
console.log(` Second focus: ${result.aphelion.longitude.toFixed(4)}° at ${result.aphelion.distance.toFixed(4)} AU`);
|
|
216
|
+
// Note: when FOPOINT is set, the "aphelion" field contains the second focus instead
|
|
217
|
+
|
|
218
|
+
swe.close();
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Daily motion and orbital speed
|
|
222
|
+
|
|
223
|
+
The `dailyMotion` and `meanDailyMotion` fields tell you how fast the planet moves along its orbit:
|
|
224
|
+
|
|
225
|
+
```typescript
|
|
226
|
+
import { SwissEph } from '../index';
|
|
227
|
+
import {
|
|
228
|
+
SE_MERCURY, SE_VENUS, SE_EARTH, SE_MARS,
|
|
229
|
+
SE_JUPITER, SE_SATURN, SE_URANUS, SE_NEPTUNE, SE_PLUTO,
|
|
230
|
+
} from '../../constants';
|
|
231
|
+
|
|
232
|
+
const swe = new SwissEph();
|
|
233
|
+
const jd = SwissEph.julianDay(2025, 1, 1, 0);
|
|
234
|
+
|
|
235
|
+
const planets = [
|
|
236
|
+
{ id: SE_MERCURY, name: 'Mercury' },
|
|
237
|
+
{ id: SE_VENUS, name: 'Venus' },
|
|
238
|
+
{ id: SE_EARTH, name: 'Earth' },
|
|
239
|
+
{ id: SE_MARS, name: 'Mars' },
|
|
240
|
+
{ id: SE_JUPITER, name: 'Jupiter' },
|
|
241
|
+
{ id: SE_SATURN, name: 'Saturn' },
|
|
242
|
+
{ id: SE_URANUS, name: 'Uranus' },
|
|
243
|
+
{ id: SE_NEPTUNE, name: 'Neptune' },
|
|
244
|
+
{ id: SE_PLUTO, name: 'Pluto' },
|
|
245
|
+
];
|
|
246
|
+
|
|
247
|
+
console.log('Planet Daily Motion Mean Daily Period (yr)');
|
|
248
|
+
console.log('--------- ----------- ---------- -----------');
|
|
249
|
+
|
|
250
|
+
for (const pl of planets) {
|
|
251
|
+
const elem = swe.orbitalElements(jd, pl.id);
|
|
252
|
+
console.log(
|
|
253
|
+
`${pl.name.padEnd(9)} ` +
|
|
254
|
+
`${elem.dailyMotion.toFixed(6).padStart(10)}° ` +
|
|
255
|
+
`${elem.meanDailyMotion.toFixed(6).padStart(10)}° ` +
|
|
256
|
+
`${elem.tropicalPeriod.toFixed(3).padStart(11)}`
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
swe.close();
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Deep Explanation
|
|
266
|
+
|
|
267
|
+
### The Six Classical Orbital Elements
|
|
268
|
+
|
|
269
|
+
Every orbit in the solar system can be described by six numbers. Three define the shape and size of the orbit; three define its orientation in space.
|
|
270
|
+
|
|
271
|
+
#### Shape and Size
|
|
272
|
+
|
|
273
|
+
**1. Semi-major axis (a)** -- measured in AU (Astronomical Units, where 1 AU = Earth-Sun distance)
|
|
274
|
+
|
|
275
|
+
The semi-major axis is half the longest diameter of the elliptical orbit. It determines the size of the orbit and, by Kepler's Third Law, the orbital period.
|
|
276
|
+
|
|
277
|
+
```
|
|
278
|
+
Semi-major axis (a)
|
|
279
|
+
|<-------------------------->|
|
|
280
|
+
|
|
281
|
+
Aphelion --- Center --- Perihelion
|
|
282
|
+
|
|
|
283
|
+
Sun (at one focus)
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Typical values:
|
|
287
|
+
| Planet | a (AU) |
|
|
288
|
+
|--------|--------|
|
|
289
|
+
| Mercury | 0.387 |
|
|
290
|
+
| Venus | 0.723 |
|
|
291
|
+
| Earth | 1.000 |
|
|
292
|
+
| Mars | 1.524 |
|
|
293
|
+
| Jupiter | 5.203 |
|
|
294
|
+
| Saturn | 9.537 |
|
|
295
|
+
| Uranus | 19.19 |
|
|
296
|
+
| Neptune | 30.07 |
|
|
297
|
+
| Pluto | 39.48 |
|
|
298
|
+
|
|
299
|
+
**2. Eccentricity (e)** -- dimensionless, range 0 to 1
|
|
300
|
+
|
|
301
|
+
The eccentricity measures how elongated the ellipse is:
|
|
302
|
+
- **e = 0**: Perfect circle
|
|
303
|
+
- **e = 0.5**: Moderately elliptical
|
|
304
|
+
- **e = 1**: Parabola (escape trajectory)
|
|
305
|
+
- **e > 1**: Hyperbola (unbound orbit)
|
|
306
|
+
|
|
307
|
+
Most planets have nearly circular orbits (e < 0.1). Notable exceptions:
|
|
308
|
+
| Planet | e | Description |
|
|
309
|
+
|--------|------|-----------|
|
|
310
|
+
| Venus | 0.007 | Nearly circular |
|
|
311
|
+
| Earth | 0.017 | Very slightly elliptical |
|
|
312
|
+
| Mars | 0.093 | Noticeably elliptical |
|
|
313
|
+
| Pluto | 0.249 | Highly elliptical |
|
|
314
|
+
| Mercury | 0.206 | Quite elliptical |
|
|
315
|
+
|
|
316
|
+
Mars's eccentricity of ~0.093 causes its brightness at opposition to vary dramatically: a close opposition (perihelion side) makes Mars much brighter than a distant one.
|
|
317
|
+
|
|
318
|
+
**3. Inclination (i)** -- measured in degrees
|
|
319
|
+
|
|
320
|
+
The angle between the planet's orbital plane and the ecliptic (Earth's orbital plane). Most planets have very low inclinations:
|
|
321
|
+
| Planet | i |
|
|
322
|
+
|--------|------|
|
|
323
|
+
| Mercury | 7.0° |
|
|
324
|
+
| Venus | 3.4° |
|
|
325
|
+
| Mars | 1.9° |
|
|
326
|
+
| Jupiter | 1.3° |
|
|
327
|
+
| Pluto | 17.1° |
|
|
328
|
+
|
|
329
|
+
#### Orientation
|
|
330
|
+
|
|
331
|
+
**4. Longitude of the Ascending Node (Omega)** -- measured in degrees
|
|
332
|
+
|
|
333
|
+
The angle (measured along the ecliptic) from the Vernal Equinox to the point where the planet's orbit crosses the ecliptic going northward. This orients the orbital plane's "tilt axis" relative to the reference direction.
|
|
334
|
+
|
|
335
|
+
```
|
|
336
|
+
Ecliptic plane
|
|
337
|
+
Vernal Equinox ----Omega---- Ascending Node
|
|
338
|
+
/
|
|
339
|
+
Planet's orbit
|
|
340
|
+
(tilted)
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
**5. Argument of Perihelion (omega)** -- measured in degrees
|
|
344
|
+
|
|
345
|
+
The angle (measured within the orbital plane) from the ascending node to the perihelion point. This tells you where in the orbit the closest approach to the Sun occurs.
|
|
346
|
+
|
|
347
|
+
**6. Mean Anomaly (M)** -- measured in degrees
|
|
348
|
+
|
|
349
|
+
The position of the planet along its orbit at the given epoch. Mean anomaly increases uniformly with time (unlike the true anomaly, which speeds up near perihelion). M = 0 at perihelion.
|
|
350
|
+
|
|
351
|
+
### Kepler's Three Laws
|
|
352
|
+
|
|
353
|
+
These orbital elements are grounded in Kepler's laws of planetary motion:
|
|
354
|
+
|
|
355
|
+
**First Law (1609)**: Planets move in ellipses with the Sun at one focus.
|
|
356
|
+
- This is why we need `a` (size) and `e` (shape) to describe the orbit.
|
|
357
|
+
|
|
358
|
+
**Second Law (1609)**: A line from the Sun to a planet sweeps out equal areas in equal times.
|
|
359
|
+
- This means planets move faster at perihelion and slower at aphelion. It is why `dailyMotion` (actual current speed) differs from `meanDailyMotion` (average speed).
|
|
360
|
+
|
|
361
|
+
**Third Law (1619)**: The square of the orbital period is proportional to the cube of the semi-major axis.
|
|
362
|
+
- P^2 = a^3 (when P is in years and a is in AU)
|
|
363
|
+
- This connects `semiAxis` to `tropicalPeriod`
|
|
364
|
+
|
|
365
|
+
### Osculating Elements
|
|
366
|
+
|
|
367
|
+
The elements returned by `orbitalElements()` are **osculating elements** -- they describe the orbit the planet would follow if all gravitational perturbations suddenly stopped at the given moment. They are an instantaneous snapshot.
|
|
368
|
+
|
|
369
|
+
In reality, the gravitational pull of other planets causes orbital elements to change slowly over time. For example:
|
|
370
|
+
- Mercury's argument of perihelion advances by about 574 arcseconds per century (43 of which are due to general relativity -- the famous anomalous precession that Einstein explained)
|
|
371
|
+
- Earth's eccentricity oscillates between about 0.005 and 0.058 over a ~100,000-year cycle (affecting ice ages)
|
|
372
|
+
|
|
373
|
+
This is why the function requires a Julian Day -- the elements are specific to that moment.
|
|
374
|
+
|
|
375
|
+
### Derived Quantities
|
|
376
|
+
|
|
377
|
+
Beyond the six classical elements, `orbitalElements()` returns several useful derived quantities:
|
|
378
|
+
|
|
379
|
+
**Tropical Period** (`tropicalPeriod`): The time for the planet to complete one orbit relative to the Vernal Equinox (in years). Due to precession, this differs very slightly from the sidereal period.
|
|
380
|
+
|
|
381
|
+
**Synodic Period** (`synodicPeriod`): The time between successive conjunctions of the planet with the Sun as seen from Earth (in days). This is the cycle of visibility -- from one opposition to the next for outer planets, or from one inferior conjunction to the next for inner planets.
|
|
382
|
+
|
|
383
|
+
**Daily Motion** (`dailyMotion`): The planet's current angular velocity along its orbit (degrees per day). Varies due to Kepler's Second Law -- faster at perihelion, slower at aphelion.
|
|
384
|
+
|
|
385
|
+
**Mean Daily Motion** (`meanDailyMotion`): The average angular velocity (degrees per day), which is constant: 360 / (period in days).
|
|
386
|
+
|
|
387
|
+
**Mean Longitude** (`meanLongitude`): The sum of the ascending node, argument of perihelion, and mean anomaly. A single number that increases uniformly and wraps around every orbit.
|
|
388
|
+
|
|
389
|
+
### The Nodes and Apsides Methods
|
|
390
|
+
|
|
391
|
+
The `nodesApsides()` method returns the positions of four special points:
|
|
392
|
+
|
|
393
|
+
**Ascending Node**: Where the planet's orbit crosses the ecliptic going northward. Important in astrology (the "North Node" of the planet).
|
|
394
|
+
|
|
395
|
+
**Descending Node**: Where the orbit crosses the ecliptic going southward.
|
|
396
|
+
|
|
397
|
+
**Perihelion**: The point of closest approach to the Sun. The planet moves fastest here (Kepler's Second Law).
|
|
398
|
+
|
|
399
|
+
**Aphelion**: The point farthest from the Sun. The planet moves slowest here.
|
|
400
|
+
|
|
401
|
+
Each of these is returned as a full `PlanetPosition` object with longitude, latitude, distance, and speeds.
|
|
402
|
+
|
|
403
|
+
### Method Constants for nodesApsides
|
|
404
|
+
|
|
405
|
+
| Constant | Value | Description |
|
|
406
|
+
|----------|-------|-------------|
|
|
407
|
+
| `SE_NODBIT_MEAN` | 1 | Mean nodes/apsides -- smooth, long-term averages. These change slowly and predictably. Best for general astrological use. |
|
|
408
|
+
| `SE_NODBIT_OSCU` | 2 | Osculating nodes/apsides -- instantaneous values based on the current orbit. These can jump around due to perturbations. |
|
|
409
|
+
| `SE_NODBIT_OSCU_BAR` | 4 | Osculating, computed from barycentric positions. More accurate for outer planets where the Sun's wobble due to Jupiter matters. |
|
|
410
|
+
| `SE_NODBIT_FOPOINT` | 256 | Replace aphelion with the second focus of the ellipse. Can be combined with other flags using bitwise OR. |
|
|
411
|
+
|
|
412
|
+
### The Astronomical Unit (AU)
|
|
413
|
+
|
|
414
|
+
The AU is the standard unit for measuring distances within the solar system. Historically defined as the mean Earth-Sun distance, it is now precisely defined as:
|
|
415
|
+
|
|
416
|
+
**1 AU = 149,597,870.7 km**
|
|
417
|
+
|
|
418
|
+
All distances in `orbitalElements()` and `orbitDistances()` are given in AU. To convert to kilometers, multiply by 149,597,870.7. To convert to light-minutes, multiply by 8.317 (light takes about 8.3 minutes to travel 1 AU).
|
|
419
|
+
|
|
420
|
+
### Return Types
|
|
421
|
+
|
|
422
|
+
```typescript
|
|
423
|
+
interface OrbitalElements {
|
|
424
|
+
semiAxis: number; // a -- semi-major axis in AU
|
|
425
|
+
eccentricity: number; // e -- eccentricity (0-1)
|
|
426
|
+
inclination: number; // i -- inclination in degrees
|
|
427
|
+
ascNode: number; // Longitude of ascending node in degrees
|
|
428
|
+
argPerihelion: number; // Argument of perihelion in degrees
|
|
429
|
+
longPerihelion: number; // Longitude of perihelion in degrees (= ascNode + argPerihelion)
|
|
430
|
+
meanAnomaly: number; // Mean anomaly in degrees
|
|
431
|
+
meanLongitude: number; // Mean longitude in degrees (= longPerihelion + meanAnomaly)
|
|
432
|
+
dailyMotion: number; // Current daily motion in degrees/day
|
|
433
|
+
tropicalPeriod: number; // Tropical period in years
|
|
434
|
+
synodicPeriod: number; // Synodic period in days
|
|
435
|
+
meanDailyMotion: number; // Mean daily motion in degrees/day
|
|
436
|
+
meanLongJ2000: number; // Mean longitude referred to J2000 equinox
|
|
437
|
+
meanLongOfDate: number; // Mean longitude of date
|
|
438
|
+
meanLongSpeed: number; // Speed of mean longitude
|
|
439
|
+
nodeJ2000: number; // Ascending node referred to J2000
|
|
440
|
+
nodeOfDate: number; // Ascending node of date
|
|
441
|
+
nodeSpeed: number; // Speed of ascending node
|
|
442
|
+
perihelionJ2000: number; // Longitude of perihelion referred to J2000
|
|
443
|
+
perihelionOfDate: number; // Longitude of perihelion of date
|
|
444
|
+
perihelionSpeed: number; // Speed of longitude of perihelion
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
interface OrbitDistances {
|
|
448
|
+
max: number; // Maximum distance (aphelion for heliocentric) in AU
|
|
449
|
+
min: number; // Minimum distance (perihelion for heliocentric) in AU
|
|
450
|
+
true: number; // Current true distance in AU
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
interface NodesApsides {
|
|
454
|
+
ascendingNode: PlanetPosition; // Full position at ascending node
|
|
455
|
+
descendingNode: PlanetPosition; // Full position at descending node
|
|
456
|
+
perihelion: PlanetPosition; // Full position at perihelion
|
|
457
|
+
aphelion: PlanetPosition; // Full position at aphelion (or second focus if FOPOINT)
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
### Why Elements Change Over Time (Perturbations)
|
|
462
|
+
|
|
463
|
+
If the Sun and a single planet were the only objects in the universe, the orbital elements would be constant forever (a perfect Keplerian orbit). In reality, the gravitational pulls of other planets cause the elements to drift:
|
|
464
|
+
|
|
465
|
+
- **Precession of perihelion**: The orientation of the orbit slowly rotates. Mercury's perihelion advances 574"/century.
|
|
466
|
+
- **Nodal regression**: The orbital plane slowly wobbles, causing the ascending node to drift.
|
|
467
|
+
- **Eccentricity oscillation**: The shape of the orbit changes over very long timescales.
|
|
468
|
+
|
|
469
|
+
These changes are tiny from year to year but accumulate over millennia. This is why astronomers use osculating elements (valid for a specific instant) rather than fixed mean elements when precision matters.
|