@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,328 @@
|
|
|
1
|
+
# Planetary Phenomena
|
|
2
|
+
|
|
3
|
+
Planetary phenomena are the observable characteristics of a planet as seen from Earth at a given moment. When you look at a planet in the night sky, you might wonder: How bright is it? How far from the Sun does it appear? How much of its surface is illuminated? The `phenomena()` method answers all these questions at once, returning five key measurements:
|
|
4
|
+
|
|
5
|
+
- **Phase angle**: the angle Sun-Planet-Earth, which determines how much of the planet's illuminated side faces us
|
|
6
|
+
- **Phase (illuminated fraction)**: a number from 0.0 to 1.0 representing what proportion of the visible disk is lit
|
|
7
|
+
- **Elongation**: the angular separation between the planet and the Sun as seen from Earth
|
|
8
|
+
- **Apparent diameter**: how large the planet appears, measured in arcseconds
|
|
9
|
+
- **Apparent magnitude**: how bright the planet appears on the astronomical magnitude scale
|
|
10
|
+
|
|
11
|
+
These quantities are useful for observation planning (can I see this planet tonight?), astrophotography, and understanding the geometric relationship between the Sun, a planet, and the Earth.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Quick Example
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { SwissEph } from '../index';
|
|
19
|
+
import { SE_VENUS } from '../../constants';
|
|
20
|
+
|
|
21
|
+
const swe = new SwissEph();
|
|
22
|
+
const jd = SwissEph.julianDay(2025, 3, 15, 20); // 2025 Mar 15, 20:00 UT
|
|
23
|
+
|
|
24
|
+
const p = swe.phenomena(jd, SE_VENUS);
|
|
25
|
+
|
|
26
|
+
console.log(`Phase angle: ${p.phaseAngle.toFixed(2)} deg`);
|
|
27
|
+
console.log(`Phase (illuminated): ${(p.phase * 100).toFixed(1)}%`);
|
|
28
|
+
console.log(`Elongation from Sun: ${p.elongation.toFixed(2)} deg`);
|
|
29
|
+
console.log(`Apparent diameter: ${p.apparentDiameter.toFixed(2)} arcsec`);
|
|
30
|
+
console.log(`Apparent magnitude: ${p.apparentMagnitude.toFixed(2)}`);
|
|
31
|
+
|
|
32
|
+
swe.close();
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Detailed Examples
|
|
38
|
+
|
|
39
|
+
### Phenomena for all visible planets
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { SwissEph } from '../index';
|
|
43
|
+
import {
|
|
44
|
+
SE_MERCURY, SE_VENUS, SE_MARS,
|
|
45
|
+
SE_JUPITER, SE_SATURN,
|
|
46
|
+
} from '../../constants';
|
|
47
|
+
|
|
48
|
+
const swe = new SwissEph();
|
|
49
|
+
const jd = SwissEph.julianDay(2025, 6, 1, 0);
|
|
50
|
+
|
|
51
|
+
const planets = [
|
|
52
|
+
{ id: SE_MERCURY, name: 'Mercury' },
|
|
53
|
+
{ id: SE_VENUS, name: 'Venus' },
|
|
54
|
+
{ id: SE_MARS, name: 'Mars' },
|
|
55
|
+
{ id: SE_JUPITER, name: 'Jupiter' },
|
|
56
|
+
{ id: SE_SATURN, name: 'Saturn' },
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
console.log('Planet Elong Phase% Mag Diam"');
|
|
60
|
+
console.log('---------- ------ ------ ----- -----');
|
|
61
|
+
|
|
62
|
+
for (const pl of planets) {
|
|
63
|
+
const p = swe.phenomena(jd, pl.id);
|
|
64
|
+
console.log(
|
|
65
|
+
`${pl.name.padEnd(10)} ` +
|
|
66
|
+
`${p.elongation.toFixed(1).padStart(5)}° ` +
|
|
67
|
+
`${(p.phase * 100).toFixed(1).padStart(5)}% ` +
|
|
68
|
+
`${p.apparentMagnitude.toFixed(1).padStart(5)} ` +
|
|
69
|
+
`${p.apparentDiameter.toFixed(2).padStart(5)}`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
swe.close();
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Checking if a planet is visible
|
|
77
|
+
|
|
78
|
+
A planet is generally visible to the naked eye when:
|
|
79
|
+
1. Its elongation from the Sun is greater than about 15 degrees (so the sky is dark enough where it appears)
|
|
80
|
+
2. Its apparent magnitude is less than about 6.0 (the naked-eye limit)
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { SwissEph } from '../index';
|
|
84
|
+
import {
|
|
85
|
+
SE_MERCURY, SE_VENUS, SE_MARS,
|
|
86
|
+
SE_JUPITER, SE_SATURN,
|
|
87
|
+
} from '../../constants';
|
|
88
|
+
|
|
89
|
+
const swe = new SwissEph();
|
|
90
|
+
const jd = SwissEph.julianDay(2025, 4, 10, 20);
|
|
91
|
+
|
|
92
|
+
const planets = [
|
|
93
|
+
{ id: SE_MERCURY, name: 'Mercury' },
|
|
94
|
+
{ id: SE_VENUS, name: 'Venus' },
|
|
95
|
+
{ id: SE_MARS, name: 'Mars' },
|
|
96
|
+
{ id: SE_JUPITER, name: 'Jupiter' },
|
|
97
|
+
{ id: SE_SATURN, name: 'Saturn' },
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
for (const pl of planets) {
|
|
101
|
+
const p = swe.phenomena(jd, pl.id);
|
|
102
|
+
|
|
103
|
+
const farEnoughFromSun = p.elongation > 15;
|
|
104
|
+
const brightEnough = p.apparentMagnitude < 6.0;
|
|
105
|
+
const visible = farEnoughFromSun && brightEnough;
|
|
106
|
+
|
|
107
|
+
console.log(
|
|
108
|
+
`${pl.name.padEnd(10)} elong=${p.elongation.toFixed(1).padStart(5)}° ` +
|
|
109
|
+
`mag=${p.apparentMagnitude.toFixed(1).padStart(5)} ` +
|
|
110
|
+
`→ ${visible ? 'VISIBLE' : 'not visible'}`
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
swe.close();
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Note: This is a simplified check. True visibility also depends on whether the planet is above the horizon at your location and the time of night. For a complete analysis, combine with `swe.riseSet()` and `swe.azalt()`.
|
|
118
|
+
|
|
119
|
+
### Tracking Venus phases over a synodic cycle
|
|
120
|
+
|
|
121
|
+
Venus goes through phases like the Moon. As an inferior planet (orbiting closer to the Sun than Earth), Venus shows a full range of phases depending on its position relative to the Sun and Earth.
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
import { SwissEph } from '../index';
|
|
125
|
+
import { SE_VENUS } from '../../constants';
|
|
126
|
+
|
|
127
|
+
const swe = new SwissEph();
|
|
128
|
+
|
|
129
|
+
// Track Venus phenomena monthly over ~19 months (Venus synodic period ≈ 584 days)
|
|
130
|
+
const startJd = SwissEph.julianDay(2025, 1, 1, 0);
|
|
131
|
+
|
|
132
|
+
console.log('Date Phase% Elong PhaseAngle Mag Diam"');
|
|
133
|
+
|
|
134
|
+
for (let month = 0; month < 20; month++) {
|
|
135
|
+
const jd = startJd + month * 30.44; // ~1 month intervals
|
|
136
|
+
const p = swe.phenomena(jd, SE_VENUS);
|
|
137
|
+
const d = SwissEph.fromJulianDay(jd);
|
|
138
|
+
|
|
139
|
+
console.log(
|
|
140
|
+
`${d.year}-${String(d.month).padStart(2,'0')}-${String(Math.floor(d.day)).padStart(2,'0')} ` +
|
|
141
|
+
`${(p.phase * 100).toFixed(1).padStart(5)}% ` +
|
|
142
|
+
`${p.elongation.toFixed(1).padStart(5)}° ` +
|
|
143
|
+
`${p.phaseAngle.toFixed(1).padStart(9)}° ` +
|
|
144
|
+
`${p.apparentMagnitude.toFixed(1).padStart(5)} ` +
|
|
145
|
+
`${p.apparentDiameter.toFixed(1).padStart(5)}`
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
swe.close();
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
When Venus is on the far side of the Sun (superior conjunction), it appears nearly full but small and faint. When it is closest to Earth (inferior conjunction), it appears as a thin crescent but very large and actually at its brightest just before/after, when the combination of size and illumination peaks.
|
|
153
|
+
|
|
154
|
+
### Moon phase as illuminated fraction
|
|
155
|
+
|
|
156
|
+
The `phenomena()` method works for the Moon too, giving you the illuminated fraction directly.
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { SwissEph } from '../index';
|
|
160
|
+
import { SE_MOON } from '../../constants';
|
|
161
|
+
|
|
162
|
+
const swe = new SwissEph();
|
|
163
|
+
|
|
164
|
+
// Check Moon phase nightly for a month
|
|
165
|
+
const startJd = SwissEph.julianDay(2025, 3, 1, 0);
|
|
166
|
+
|
|
167
|
+
for (let day = 0; day < 30; day++) {
|
|
168
|
+
const jd = startJd + day;
|
|
169
|
+
const p = swe.phenomena(jd, SE_MOON);
|
|
170
|
+
const d = SwissEph.fromJulianDay(jd);
|
|
171
|
+
|
|
172
|
+
// Simple phase name based on illuminated fraction and phase angle
|
|
173
|
+
const pct = p.phase * 100;
|
|
174
|
+
let phaseName: string;
|
|
175
|
+
if (pct < 2) phaseName = 'New Moon';
|
|
176
|
+
else if (pct < 40) phaseName = p.elongation < 180 ? 'Waxing Crescent' : 'Waning Crescent';
|
|
177
|
+
else if (pct < 60) phaseName = p.elongation < 180 ? 'First Quarter' : 'Last Quarter';
|
|
178
|
+
else if (pct < 98) phaseName = p.elongation < 180 ? 'Waxing Gibbous' : 'Waning Gibbous';
|
|
179
|
+
else phaseName = 'Full Moon';
|
|
180
|
+
|
|
181
|
+
const bar = '#'.repeat(Math.round(pct / 5)).padEnd(20);
|
|
182
|
+
console.log(
|
|
183
|
+
`Mar ${String(day + 1).padStart(2)} ${pct.toFixed(1).padStart(5)}% [${bar}] ${phaseName}`
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
swe.close();
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Deep Explanation
|
|
193
|
+
|
|
194
|
+
### Phase Angle
|
|
195
|
+
|
|
196
|
+
The phase angle is the angle formed at the planet between the directions to the Sun and to the Earth. Imagine standing on the planet's surface: the phase angle is the angle between the Sun and Earth in your sky.
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
Sun
|
|
200
|
+
/
|
|
201
|
+
/ phase angle
|
|
202
|
+
Planet ---------- Earth
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
- **0 degrees**: The Sun is directly behind Earth (from the planet's perspective). This is **opposition** for superior planets -- the planet's fully lit face points toward Earth. For the Moon, this is a Full Moon.
|
|
206
|
+
- **90 degrees**: Half the visible disk is illuminated (like a quarter Moon, or Mercury/Venus at greatest elongation).
|
|
207
|
+
- **180 degrees**: The planet is between Earth and the Sun (**conjunction**). The lit side faces away from Earth. For the Moon, this is a New Moon.
|
|
208
|
+
|
|
209
|
+
### Phase (Illuminated Fraction)
|
|
210
|
+
|
|
211
|
+
The phase is a value from 0.0 to 1.0 representing the fraction of the planet's visible disk that is illuminated by the Sun. It is related to the phase angle by:
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
phase = (1 + cos(phaseAngle)) / 2
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
- 1.0 = fully illuminated (opposition/full)
|
|
218
|
+
- 0.5 = half illuminated (quarter)
|
|
219
|
+
- 0.0 = unilluminated (conjunction/new)
|
|
220
|
+
|
|
221
|
+
For the Moon, this is the familiar "percent illumination" often shown in weather apps and calendars.
|
|
222
|
+
|
|
223
|
+
### Elongation
|
|
224
|
+
|
|
225
|
+
Elongation is the angular distance between the planet and the Sun as seen from Earth. It determines whether and when you can observe the planet:
|
|
226
|
+
|
|
227
|
+
- **0 degrees**: conjunction -- the planet is in the same direction as the Sun and invisible in the glare
|
|
228
|
+
- **~15 degrees**: the minimum elongation for a planet to be glimpsed in twilight
|
|
229
|
+
- **90 degrees**: quadrature -- the planet is a quarter of the sky away from the Sun
|
|
230
|
+
- **180 degrees**: opposition -- the planet is opposite the Sun, rising at sunset and visible all night
|
|
231
|
+
|
|
232
|
+
For **inferior planets** (Mercury and Venus, which orbit closer to the Sun than Earth), elongation has a maximum value:
|
|
233
|
+
- Mercury: ~18-28 degrees (varies due to orbital eccentricity)
|
|
234
|
+
- Venus: ~45-47 degrees
|
|
235
|
+
|
|
236
|
+
This is why Mercury and Venus are always seen near the Sun, as "morning stars" or "evening stars." They can never appear at opposition.
|
|
237
|
+
|
|
238
|
+
For **superior planets** (Mars through Pluto), elongation can range from 0 to 180 degrees.
|
|
239
|
+
|
|
240
|
+
### Apparent Diameter
|
|
241
|
+
|
|
242
|
+
The apparent diameter is how large the planet appears in the sky, measured in **arcseconds** (1/3600 of a degree). For reference:
|
|
243
|
+
- The Sun and Moon are each about 1800 arcseconds (30 arcminutes, or half a degree)
|
|
244
|
+
- Jupiter at opposition: ~45 arcseconds
|
|
245
|
+
- Saturn (disk only): ~18 arcseconds
|
|
246
|
+
- Mars at opposition: ~14-25 arcseconds (varies greatly)
|
|
247
|
+
- Venus at closest approach: ~60 arcseconds (larger than Jupiter!)
|
|
248
|
+
|
|
249
|
+
The apparent diameter changes as the planet's distance from Earth changes. It is inversely proportional to distance.
|
|
250
|
+
|
|
251
|
+
### Apparent Magnitude
|
|
252
|
+
|
|
253
|
+
The **magnitude scale** is the astronomer's measure of brightness. It was invented by the ancient Greek astronomer **Hipparchus** (~150 BC), who classified stars into six groups: the brightest stars were "first magnitude" and the faintest visible stars were "sixth magnitude."
|
|
254
|
+
|
|
255
|
+
The modern scale is logarithmic and extends in both directions:
|
|
256
|
+
- **Lower numbers = brighter**. Negative magnitudes are very bright.
|
|
257
|
+
- Each step of 1 magnitude corresponds to a brightness factor of about 2.512
|
|
258
|
+
- A difference of 5 magnitudes = exactly 100x brightness difference
|
|
259
|
+
|
|
260
|
+
Typical planet magnitudes:
|
|
261
|
+
| Object | Typical Magnitude |
|
|
262
|
+
|--------|------------------|
|
|
263
|
+
| Sun | -26.7 |
|
|
264
|
+
| Full Moon | -12.7 |
|
|
265
|
+
| Venus (brightest) | -4.6 |
|
|
266
|
+
| Jupiter (opposition) | -2.5 |
|
|
267
|
+
| Mars (opposition) | -2.0 to -2.9 |
|
|
268
|
+
| Saturn | +0.5 to +1.5 |
|
|
269
|
+
| Mercury | -0.5 to +3 |
|
|
270
|
+
| Uranus | +5.7 |
|
|
271
|
+
| Neptune | +7.8 (invisible to naked eye) |
|
|
272
|
+
| Naked eye limit | ~+6.0 |
|
|
273
|
+
|
|
274
|
+
### Geometry of Opposition and Conjunction
|
|
275
|
+
|
|
276
|
+
For a **superior planet** (orbiting farther from the Sun than Earth):
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
Sun
|
|
280
|
+
|
|
|
281
|
+
Earth-+--------Planet ← Opposition (phase angle ≈ 0°, elongation = 180°)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
At opposition, the planet is closest to Earth, appears brightest, shows its full disk, and is visible all night. This is the best time to observe it.
|
|
285
|
+
|
|
286
|
+
```
|
|
287
|
+
Sun
|
|
288
|
+
|
|
|
289
|
+
Planet-+-Earth ← Conjunction (phase angle ≈ 180°, elongation ≈ 0°)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
At conjunction, the planet is behind the Sun and invisible.
|
|
293
|
+
|
|
294
|
+
For an **inferior planet** (Mercury or Venus):
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
Sun
|
|
298
|
+
|
|
|
299
|
+
Earth-+ Venus ← Greatest Eastern Elongation (evening star)
|
|
300
|
+
seen after sunset in the west
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
Sun
|
|
305
|
+
|
|
|
306
|
+
Venus +-Earth ← Greatest Western Elongation (morning star)
|
|
307
|
+
seen before sunrise in the east
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
### Return Type
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
interface PhenoResult {
|
|
314
|
+
phaseAngle: number; // degrees, 0-180
|
|
315
|
+
phase: number; // illuminated fraction, 0.0-1.0
|
|
316
|
+
elongation: number; // degrees from Sun, 0-180
|
|
317
|
+
apparentDiameter: number; // arcseconds
|
|
318
|
+
apparentMagnitude: number; // magnitude (lower = brighter)
|
|
319
|
+
}
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Applicable Bodies
|
|
323
|
+
|
|
324
|
+
The `phenomena()` method works for all planets (Mercury through Pluto), the Moon, asteroids, and fixed stars. For the Sun itself, most values are not meaningful (the Sun's elongation from itself is always 0).
|
|
325
|
+
|
|
326
|
+
### Flags
|
|
327
|
+
|
|
328
|
+
The optional `flags` parameter controls the calculation method. Normally you can omit it and accept the defaults. Possible flags include sidereal mode flags, but for phenomena calculations the default tropical geocentric computation is standard.
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
# Planet Positions
|
|
2
|
+
|
|
3
|
+
Calculating the position of a planet is the most fundamental operation in astrology and astronomical computing. Given a moment in time (expressed as a Julian Day number), the Swiss Ephemeris computes where each planet appears in the sky. The result includes the planet's **longitude** (its position along the ecliptic, 0-360 degrees), **latitude** (how far above or below the ecliptic plane), and **distance** (how far away it is, in AU). You also get the **speed** of each value -- how fast the planet is moving per day.
|
|
4
|
+
|
|
5
|
+
This is the building block for natal charts, transits, progressions, synastry, and virtually every astrological technique.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Quick Example
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { SwissEph } from '../index';
|
|
13
|
+
import { SE_SUN, SE_MOON, SE_MARS } from '../../constants';
|
|
14
|
+
|
|
15
|
+
const swe = new SwissEph();
|
|
16
|
+
|
|
17
|
+
// J2000.0 epoch (January 1, 2000 at 12:00 UT)
|
|
18
|
+
const jd = SwissEph.julianDay(2000, 1, 1, 12);
|
|
19
|
+
|
|
20
|
+
const sun = swe.calc(jd, SE_SUN);
|
|
21
|
+
console.log(`Sun longitude: ${sun.longitude.toFixed(4)}deg`);
|
|
22
|
+
// Sun longitude: 280.3706deg
|
|
23
|
+
|
|
24
|
+
const moon = swe.calc(jd, SE_MOON);
|
|
25
|
+
console.log(`Moon longitude: ${moon.longitude.toFixed(4)}deg`);
|
|
26
|
+
|
|
27
|
+
const mars = swe.calc(jd, SE_MARS);
|
|
28
|
+
console.log(`Mars longitude: ${mars.longitude.toFixed(4)}deg`);
|
|
29
|
+
console.log(`Mars speed: ${mars.longitudeSpeed.toFixed(4)} deg/day`);
|
|
30
|
+
|
|
31
|
+
swe.close();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Detailed Examples
|
|
37
|
+
|
|
38
|
+
### All classical planets at a given date
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { SwissEph } from '../index';
|
|
42
|
+
import {
|
|
43
|
+
SE_SUN, SE_MOON, SE_MERCURY, SE_VENUS, SE_MARS,
|
|
44
|
+
SE_JUPITER, SE_SATURN, SE_URANUS, SE_NEPTUNE, SE_PLUTO,
|
|
45
|
+
} from '../../constants';
|
|
46
|
+
|
|
47
|
+
const swe = new SwissEph();
|
|
48
|
+
const jd = SwissEph.julianDay(2024, 4, 8, 18.28); // 2024 Apr 8, ~18:17 UT
|
|
49
|
+
|
|
50
|
+
const planets = [
|
|
51
|
+
{ id: SE_SUN, name: 'Sun' },
|
|
52
|
+
{ id: SE_MOON, name: 'Moon' },
|
|
53
|
+
{ id: SE_MERCURY, name: 'Mercury' },
|
|
54
|
+
{ id: SE_VENUS, name: 'Venus' },
|
|
55
|
+
{ id: SE_MARS, name: 'Mars' },
|
|
56
|
+
{ id: SE_JUPITER, name: 'Jupiter' },
|
|
57
|
+
{ id: SE_SATURN, name: 'Saturn' },
|
|
58
|
+
{ id: SE_URANUS, name: 'Uranus' },
|
|
59
|
+
{ id: SE_NEPTUNE, name: 'Neptune' },
|
|
60
|
+
{ id: SE_PLUTO, name: 'Pluto' },
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
for (const p of planets) {
|
|
64
|
+
const pos = swe.calc(jd, p.id);
|
|
65
|
+
|
|
66
|
+
// Convert longitude to zodiac sign
|
|
67
|
+
const signs = ['Ari','Tau','Gem','Can','Leo','Vir','Lib','Sco','Sag','Cap','Aqu','Pis'];
|
|
68
|
+
const signIndex = Math.floor(pos.longitude / 30);
|
|
69
|
+
const degInSign = pos.longitude - signIndex * 30;
|
|
70
|
+
|
|
71
|
+
console.log(
|
|
72
|
+
`${p.name.padEnd(9)} ${degInSign.toFixed(2).padStart(6)}deg ${signs[signIndex]}` +
|
|
73
|
+
` speed: ${pos.longitudeSpeed.toFixed(4)} deg/day`
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
swe.close();
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Equatorial coordinates (Right Ascension and Declination)
|
|
81
|
+
|
|
82
|
+
Astronomers typically use equatorial coordinates rather than ecliptic. Pass `SEFLG_EQUATORIAL` to get Right Ascension (in degrees, 0-360) and Declination (in degrees, -90 to +90) instead of ecliptic longitude and latitude.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { SwissEph } from '../index';
|
|
86
|
+
import { SE_SUN, SEFLG_EQUATORIAL } from '../../constants';
|
|
87
|
+
|
|
88
|
+
const swe = new SwissEph();
|
|
89
|
+
const jd = SwissEph.julianDay(2024, 6, 21, 12);
|
|
90
|
+
|
|
91
|
+
const sun = swe.calc(jd, SE_SUN, SEFLG_EQUATORIAL);
|
|
92
|
+
|
|
93
|
+
// When SEFLG_EQUATORIAL is set:
|
|
94
|
+
// longitude -> Right Ascension (degrees, 0-360)
|
|
95
|
+
// latitude -> Declination (degrees, -90 to +90)
|
|
96
|
+
// distance -> distance in AU (same as ecliptic)
|
|
97
|
+
console.log(`Sun RA: ${sun.longitude.toFixed(4)} deg`);
|
|
98
|
+
console.log(`Sun Dec: ${sun.latitude.toFixed(4)} deg`);
|
|
99
|
+
|
|
100
|
+
// Convert RA from degrees to hours/minutes/seconds
|
|
101
|
+
const raHours = sun.longitude / 15;
|
|
102
|
+
const h = Math.floor(raHours);
|
|
103
|
+
const m = Math.floor((raHours - h) * 60);
|
|
104
|
+
const s = ((raHours - h) * 60 - m) * 60;
|
|
105
|
+
console.log(`Sun RA: ${h}h ${m}m ${s.toFixed(1)}s`);
|
|
106
|
+
|
|
107
|
+
swe.close();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Heliocentric positions
|
|
111
|
+
|
|
112
|
+
View planets from the Sun's perspective instead of from Earth. Useful for heliocentric astrology and astronomical research.
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { SwissEph } from '../index';
|
|
116
|
+
import { SE_MARS, SE_EARTH, SEFLG_HELCTR } from '../../constants';
|
|
117
|
+
|
|
118
|
+
const swe = new SwissEph();
|
|
119
|
+
const jd = SwissEph.julianDay(2024, 1, 1, 12);
|
|
120
|
+
|
|
121
|
+
// Heliocentric Mars (as seen from the Sun)
|
|
122
|
+
const mars = swe.calc(jd, SE_MARS, SEFLG_HELCTR);
|
|
123
|
+
console.log(`Mars heliocentric longitude: ${mars.longitude.toFixed(4)} deg`);
|
|
124
|
+
console.log(`Mars distance from Sun: ${mars.distance.toFixed(6)} AU`);
|
|
125
|
+
|
|
126
|
+
// Heliocentric Earth
|
|
127
|
+
const earth = swe.calc(jd, SE_EARTH, SEFLG_HELCTR);
|
|
128
|
+
console.log(`Earth heliocentric longitude: ${earth.longitude.toFixed(4)} deg`);
|
|
129
|
+
|
|
130
|
+
swe.close();
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Lunar nodes and Lilith
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
import { SwissEph } from '../index';
|
|
137
|
+
import { SE_MEAN_NODE, SE_TRUE_NODE, SE_MEAN_APOG, SE_OSCU_APOG } from '../../constants';
|
|
138
|
+
|
|
139
|
+
const swe = new SwissEph();
|
|
140
|
+
const jd = SwissEph.julianDay(2024, 1, 1, 12);
|
|
141
|
+
|
|
142
|
+
const meanNode = swe.calc(jd, SE_MEAN_NODE);
|
|
143
|
+
const trueNode = swe.calc(jd, SE_TRUE_NODE);
|
|
144
|
+
console.log(`Mean North Node: ${meanNode.longitude.toFixed(4)} deg`);
|
|
145
|
+
console.log(`True North Node: ${trueNode.longitude.toFixed(4)} deg`);
|
|
146
|
+
// The South Node is always 180 degrees opposite the North Node.
|
|
147
|
+
|
|
148
|
+
const meanLilith = swe.calc(jd, SE_MEAN_APOG);
|
|
149
|
+
const oscuLilith = swe.calc(jd, SE_OSCU_APOG);
|
|
150
|
+
console.log(`Mean Lilith (Black Moon): ${meanLilith.longitude.toFixed(4)} deg`);
|
|
151
|
+
console.log(`Osculating Lilith: ${oscuLilith.longitude.toFixed(4)} deg`);
|
|
152
|
+
|
|
153
|
+
swe.close();
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Chiron and the main asteroids
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { SwissEph } from '../index';
|
|
160
|
+
import { SE_CHIRON, SE_CERES, SE_PALLAS, SE_JUNO, SE_VESTA } from '../../constants';
|
|
161
|
+
|
|
162
|
+
const swe = new SwissEph();
|
|
163
|
+
const jd = SwissEph.julianDay(2024, 1, 1, 12);
|
|
164
|
+
|
|
165
|
+
const bodies = [
|
|
166
|
+
{ id: SE_CHIRON, name: 'Chiron' },
|
|
167
|
+
{ id: SE_CERES, name: 'Ceres' },
|
|
168
|
+
{ id: SE_PALLAS, name: 'Pallas' },
|
|
169
|
+
{ id: SE_JUNO, name: 'Juno' },
|
|
170
|
+
{ id: SE_VESTA, name: 'Vesta' },
|
|
171
|
+
];
|
|
172
|
+
|
|
173
|
+
for (const b of bodies) {
|
|
174
|
+
const pos = swe.calc(jd, b.id);
|
|
175
|
+
console.log(`${b.name.padEnd(8)} ${pos.longitude.toFixed(4)} deg`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
swe.close();
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Detecting retrograde motion
|
|
182
|
+
|
|
183
|
+
A planet is retrograde when its longitudinal speed is negative.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
import { SwissEph } from '../index';
|
|
187
|
+
import { SE_MERCURY } from '../../constants';
|
|
188
|
+
|
|
189
|
+
const swe = new SwissEph();
|
|
190
|
+
|
|
191
|
+
// Check Mercury's direction over several months
|
|
192
|
+
for (let month = 1; month <= 12; month++) {
|
|
193
|
+
const jd = SwissEph.julianDay(2024, month, 15, 12);
|
|
194
|
+
const pos = swe.calc(jd, SE_MERCURY);
|
|
195
|
+
const direction = pos.longitudeSpeed < 0 ? 'RETROGRADE' : 'direct';
|
|
196
|
+
console.log(`2024-${String(month).padStart(2,'0')}-15 Mercury speed: ${pos.longitudeSpeed.toFixed(4)} deg/day ${direction}`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
swe.close();
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Topocentric positions (observer on Earth's surface)
|
|
203
|
+
|
|
204
|
+
Geocentric positions are calculated from Earth's center. For the Moon especially, the difference from a specific location on Earth's surface (topocentric) can be up to about 1 degree.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { SwissEph } from '../index';
|
|
208
|
+
import { SE_MOON, SEFLG_TOPOCTR } from '../../constants';
|
|
209
|
+
|
|
210
|
+
// Set up the observer's location in the constructor
|
|
211
|
+
const swe = new SwissEph({
|
|
212
|
+
topo: { longitude: -73.9857, latitude: 40.7484, altitude: 10 }, // New York
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const jd = SwissEph.julianDay(2024, 1, 1, 12);
|
|
216
|
+
|
|
217
|
+
// Topocentric Moon
|
|
218
|
+
const moonTopo = swe.calc(jd, SE_MOON, SEFLG_TOPOCTR);
|
|
219
|
+
console.log(`Moon (topocentric): ${moonTopo.longitude.toFixed(4)} deg`);
|
|
220
|
+
|
|
221
|
+
// Compare with geocentric (no SEFLG_TOPOCTR)
|
|
222
|
+
const swe2 = new SwissEph();
|
|
223
|
+
const moonGeo = swe2.calc(jd, SE_MOON);
|
|
224
|
+
console.log(`Moon (geocentric): ${moonGeo.longitude.toFixed(4)} deg`);
|
|
225
|
+
console.log(`Difference: ${(moonTopo.longitude - moonGeo.longitude).toFixed(4)} deg`);
|
|
226
|
+
|
|
227
|
+
swe.close();
|
|
228
|
+
swe2.close();
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Sidereal positions
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import { SwissEph } from '../index';
|
|
235
|
+
import { SE_SUN, SE_SIDM_LAHIRI, SEFLG_SIDEREAL } from '../../constants';
|
|
236
|
+
|
|
237
|
+
const swe = new SwissEph({ siderealMode: SE_SIDM_LAHIRI });
|
|
238
|
+
const jd = SwissEph.julianDay(2024, 1, 15, 12);
|
|
239
|
+
|
|
240
|
+
// IMPORTANT: you must pass SEFLG_SIDEREAL in the flags to calc()
|
|
241
|
+
// Setting siderealMode in the constructor only configures which ayanamsa to use;
|
|
242
|
+
// it does NOT automatically add SEFLG_SIDEREAL to calc() calls.
|
|
243
|
+
const sun = swe.calc(jd, SE_SUN, SEFLG_SIDEREAL);
|
|
244
|
+
console.log(`Sun sidereal longitude (Lahiri): ${sun.longitude.toFixed(4)} deg`);
|
|
245
|
+
|
|
246
|
+
swe.close();
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## Deep Explanation
|
|
252
|
+
|
|
253
|
+
### What the return values mean
|
|
254
|
+
|
|
255
|
+
| Field | Description |
|
|
256
|
+
|-------------------|-----------------------------------------------------------------------------------------------|
|
|
257
|
+
| `longitude` | Position along the ecliptic (or RA if `SEFLG_EQUATORIAL`), in degrees 0-360 |
|
|
258
|
+
| `latitude` | Angular distance above/below the ecliptic (or Declination if `SEFLG_EQUATORIAL`), in degrees |
|
|
259
|
+
| `distance` | Distance in AU (astronomical units; 1 AU = ~149.6 million km). For the Moon, also in AU. |
|
|
260
|
+
| `longitudeSpeed` | Daily motion in longitude (degrees per day). Negative = retrograde. |
|
|
261
|
+
| `latitudeSpeed` | Daily motion in latitude (degrees per day). |
|
|
262
|
+
| `distanceSpeed` | Daily change in distance (AU per day). Negative = approaching. |
|
|
263
|
+
| `flags` | Flags actually used by the engine (may differ from your input if the engine fell back). |
|
|
264
|
+
|
|
265
|
+
### Available planets and bodies
|
|
266
|
+
|
|
267
|
+
| Constant | Value | Description |
|
|
268
|
+
|------------------|-------|---------------------------------------------------------------------|
|
|
269
|
+
| `SE_SUN` | 0 | The Sun |
|
|
270
|
+
| `SE_MOON` | 1 | The Moon |
|
|
271
|
+
| `SE_MERCURY` | 2 | Mercury |
|
|
272
|
+
| `SE_VENUS` | 3 | Venus |
|
|
273
|
+
| `SE_MARS` | 4 | Mars |
|
|
274
|
+
| `SE_JUPITER` | 5 | Jupiter |
|
|
275
|
+
| `SE_SATURN` | 6 | Saturn |
|
|
276
|
+
| `SE_URANUS` | 7 | Uranus |
|
|
277
|
+
| `SE_NEPTUNE` | 8 | Neptune |
|
|
278
|
+
| `SE_PLUTO` | 9 | Pluto |
|
|
279
|
+
| `SE_MEAN_NODE` | 10 | Mean Lunar Node (North Node / Rahu). Moves smoothly. |
|
|
280
|
+
| `SE_TRUE_NODE` | 11 | True (osculating) Lunar Node. Wobbles with lunar perturbations. |
|
|
281
|
+
| `SE_MEAN_APOG` | 12 | Mean Lunar Apogee (Black Moon Lilith). Smooth mean motion. |
|
|
282
|
+
| `SE_OSCU_APOG` | 13 | Osculating Lunar Apogee. True instantaneous value, wobbles. |
|
|
283
|
+
| `SE_EARTH` | 14 | Earth (only meaningful for heliocentric/barycentric calculations). |
|
|
284
|
+
| `SE_CHIRON` | 15 | Chiron (minor planet / centaur orbiting between Saturn and Uranus). |
|
|
285
|
+
| `SE_CERES` | 17 | Ceres (dwarf planet, largest body in the asteroid belt). |
|
|
286
|
+
| `SE_PALLAS` | 18 | Pallas (second-largest asteroid). |
|
|
287
|
+
| `SE_JUNO` | 19 | Juno (asteroid). |
|
|
288
|
+
| `SE_VESTA` | 20 | Vesta (second-most-massive asteroid). |
|
|
289
|
+
|
|
290
|
+
**Note on the South Node**: The Swiss Ephemeris only calculates the North Node. The South Node is always exactly 180 degrees opposite: `southNode = (northNode + 180) % 360`.
|
|
291
|
+
|
|
292
|
+
**Note on SE_EARTH**: Requesting SE_EARTH in normal geocentric mode is meaningless (you would be asking for Earth's position as seen from Earth). Use it with `SEFLG_HELCTR` (heliocentric) or `SEFLG_BARYCTR` (barycentric).
|
|
293
|
+
|
|
294
|
+
### Flag constants
|
|
295
|
+
|
|
296
|
+
Flags modify the calculation. They are combined with the bitwise OR operator (`|`). The wrapper automatically adds `SEFLG_SPEED` so you always get speed values.
|
|
297
|
+
|
|
298
|
+
| Constant | Value | Effect |
|
|
299
|
+
|--------------------|--------|----------------------------------------------------------------------------|
|
|
300
|
+
| `SEFLG_SPEED` | 256 | Compute speed (added automatically by wrapper). |
|
|
301
|
+
| `SEFLG_EQUATORIAL` | 2048 | Return Right Ascension / Declination instead of ecliptic longitude/lat. |
|
|
302
|
+
| `SEFLG_XYZ` | 4096 | Return Cartesian (X, Y, Z) instead of polar (lon, lat, dist). |
|
|
303
|
+
| `SEFLG_RADIANS` | 8192 | Return angles in radians instead of degrees. |
|
|
304
|
+
| `SEFLG_HELCTR` | 8 | Heliocentric position (as seen from the Sun). |
|
|
305
|
+
| `SEFLG_BARYCTR` | 16384 | Barycentric position (relative to solar system barycenter). |
|
|
306
|
+
| `SEFLG_TOPOCTR` | 32768 | Topocentric (from observer's location). Requires `topo` to be set. |
|
|
307
|
+
| `SEFLG_SIDEREAL` | 65536 | Sidereal zodiac. Requires `siderealMode` to be configured. |
|
|
308
|
+
| `SEFLG_TRUEPOS` | 16 | True/geometric position (no light-time correction). |
|
|
309
|
+
| `SEFLG_NOABERR` | 1024 | No aberration of light correction. |
|
|
310
|
+
| `SEFLG_NOGDEFL` | 512 | No gravitational deflection of light. |
|
|
311
|
+
| `SEFLG_J2000` | 32 | Refer positions to the J2000 equinox (not the equinox of date). |
|
|
312
|
+
| `SEFLG_NONUT` | 64 | No nutation (use mean equinox of date, not true equinox). |
|
|
313
|
+
|
|
314
|
+
You can combine flags:
|
|
315
|
+
|
|
316
|
+
```typescript
|
|
317
|
+
import { SEFLG_EQUATORIAL, SEFLG_TOPOCTR, SEFLG_SIDEREAL } from '../../constants';
|
|
318
|
+
|
|
319
|
+
// Sidereal equatorial topocentric position
|
|
320
|
+
const pos = swe.calc(jd, SE_SUN, SEFLG_EQUATORIAL | SEFLG_SIDEREAL | SEFLG_TOPOCTR);
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
### Understanding ecliptic longitude
|
|
324
|
+
|
|
325
|
+
Ecliptic longitude is measured along the ecliptic (the Sun's apparent path through the sky over a year). It starts at the **vernal equinox point** (0 degrees Aries in the tropical zodiac) and increases eastward through the zodiac signs:
|
|
326
|
+
|
|
327
|
+
| Degrees | Sign |
|
|
328
|
+
|-----------|-------------|
|
|
329
|
+
| 0 - 30 | Aries |
|
|
330
|
+
| 30 - 60 | Taurus |
|
|
331
|
+
| 60 - 90 | Gemini |
|
|
332
|
+
| 90 - 120 | Cancer |
|
|
333
|
+
| 120 - 150 | Leo |
|
|
334
|
+
| 150 - 180 | Virgo |
|
|
335
|
+
| 180 - 210 | Libra |
|
|
336
|
+
| 210 - 240 | Scorpio |
|
|
337
|
+
| 240 - 270 | Sagittarius |
|
|
338
|
+
| 270 - 300 | Capricorn |
|
|
339
|
+
| 300 - 330 | Aquarius |
|
|
340
|
+
| 330 - 360 | Pisces |
|
|
341
|
+
|
|
342
|
+
To convert absolute longitude to sign + degree within sign:
|
|
343
|
+
```typescript
|
|
344
|
+
const signIndex = Math.floor(longitude / 30); // 0 = Aries, 11 = Pisces
|
|
345
|
+
const degreeInSign = longitude - signIndex * 30; // 0.0 to 29.999...
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Understanding ecliptic latitude
|
|
349
|
+
|
|
350
|
+
Most planets stay very close to the ecliptic (latitude near 0). The Moon can reach about +/-5 degrees. Pluto can reach about +/-17 degrees. The Sun's ecliptic latitude is always essentially 0 (by definition, since the ecliptic is the Sun's apparent path).
|
|
351
|
+
|
|
352
|
+
### Time input: UT vs ET
|
|
353
|
+
|
|
354
|
+
The Julian Day number you pass to `calc()` is interpreted according to the `timeMode` set in the constructor:
|
|
355
|
+
|
|
356
|
+
- **`'ut'`** (default): Universal Time. This is clock time corrected for time zones. Use this for most astrological work.
|
|
357
|
+
- **`'et'`**: Ephemeris Time (also called Terrestrial Time / TT). This is the uniform time scale used internally by the ephemeris. It differs from UT by "delta-T", which is about 69 seconds in 2024.
|
|
358
|
+
|
|
359
|
+
For dates within a few centuries of the present, the difference between UT and ET is small and the library handles the conversion internally. For ancient or far-future dates, the distinction becomes significant.
|
|
360
|
+
|
|
361
|
+
### Edge cases
|
|
362
|
+
|
|
363
|
+
- **Speed is always included**: The wrapper adds `SEFLG_SPEED` automatically. You do not need to pass it.
|
|
364
|
+
- **Ephemeris fallback**: If you request `'swisseph'` or `'jpl'` but the ephemeris files are not loaded, the engine silently falls back to the Moshier analytical ephemeris. You can check the returned `flags` field to see which ephemeris was actually used.
|
|
365
|
+
- **Retrograde planets**: When `longitudeSpeed < 0`, the planet is retrograde (appearing to move backward through the zodiac from Earth's perspective). This is a normal geometric effect of orbital mechanics.
|
|
366
|
+
- **Mean vs True Node**: The mean node moves smoothly backward through the zodiac (~19.3 degrees/year). The true node oscillates around the mean with a period of about 173 days. Most astrologers use the mean node; Vedic astrology traditionally uses the true node (Rahu/Ketu).
|