@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,325 @@
|
|
|
1
|
+
# Heliocentric Crossings
|
|
2
|
+
|
|
3
|
+
A **heliocentric crossing** finds the exact moment when a planet reaches a specific **heliocentric longitude** -- that is, its position as seen from the Sun (not from Earth). In heliocentric coordinates, planets move smoothly and predictably along their orbits without the apparent retrograde loops and speed variations we see from Earth.
|
|
4
|
+
|
|
5
|
+
The `helioCrossing()` method finds the next Julian Day when a planet reaches a given heliocentric longitude, searching forward (or backward) from a starting date.
|
|
6
|
+
|
|
7
|
+
This is useful for:
|
|
8
|
+
- Tracking actual orbital positions of planets
|
|
9
|
+
- Computing synodic cycles (conjunctions as seen from the Sun)
|
|
10
|
+
- Orbital mechanics and mission planning
|
|
11
|
+
- Heliocentric astrology (a niche but established branch)
|
|
12
|
+
- Understanding the geometry behind retrograde motion
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Quick Example
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { SwissEph } from '../index';
|
|
20
|
+
import { SE_MARS } from '../../constants';
|
|
21
|
+
|
|
22
|
+
const swe = new SwissEph();
|
|
23
|
+
const startJd = SwissEph.julianDay(2025, 1, 1, 0);
|
|
24
|
+
|
|
25
|
+
// Find when Mars next reaches 0° heliocentric longitude (vernal equinox direction)
|
|
26
|
+
const result = swe.helioCrossing(SE_MARS, 0, startJd);
|
|
27
|
+
|
|
28
|
+
const d = SwissEph.fromJulianDay(result.jd);
|
|
29
|
+
console.log(`Mars crosses 0° heliocentric: ${d.year}-${String(d.month).padStart(2,'0')}-${String(Math.floor(d.day)).padStart(2,'0')}`);
|
|
30
|
+
|
|
31
|
+
swe.close();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Detailed Examples
|
|
37
|
+
|
|
38
|
+
### Tracking a planet's heliocentric ingresses through the zodiac
|
|
39
|
+
|
|
40
|
+
From the Sun's perspective, Mars takes about 687 days (1.88 years) to go around the full 360 degrees. We can find when it enters each 30-degree segment:
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { SwissEph } from '../index';
|
|
44
|
+
import { SE_MARS } from '../../constants';
|
|
45
|
+
|
|
46
|
+
const swe = new SwissEph();
|
|
47
|
+
let jd = SwissEph.julianDay(2025, 1, 1, 0);
|
|
48
|
+
|
|
49
|
+
const signs = [
|
|
50
|
+
'Aries', 'Taurus', 'Gemini', 'Cancer',
|
|
51
|
+
'Leo', 'Virgo', 'Libra', 'Scorpio',
|
|
52
|
+
'Sagittarius', 'Capricorn', 'Aquarius', 'Pisces',
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
console.log('Mars heliocentric sign ingresses (starting 2025):');
|
|
56
|
+
|
|
57
|
+
for (let i = 0; i < 12; i++) {
|
|
58
|
+
const lon = i * 30;
|
|
59
|
+
const result = swe.helioCrossing(SE_MARS, lon, jd);
|
|
60
|
+
const d = SwissEph.fromJulianDay(result.jd);
|
|
61
|
+
|
|
62
|
+
console.log(
|
|
63
|
+
` Mars enters ${signs[i].padEnd(12)} (${String(lon).padStart(3)}°): ` +
|
|
64
|
+
`${d.year}-${String(d.month).padStart(2,'0')}-${String(Math.floor(d.day)).padStart(2,'0')}`
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
jd = result.jd + 1; // advance past this crossing
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
swe.close();
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Comparing heliocentric and geocentric positions
|
|
74
|
+
|
|
75
|
+
One of the most instructive uses of heliocentric coordinates is understanding how geocentric retrograde motion arises. When Earth "overtakes" a slower outer planet, the planet appears to move backward (retrograde) in geocentric coordinates, even though heliocentrically it never stops or reverses.
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { SwissEph } from '../index';
|
|
79
|
+
import { SE_MARS, SEFLG_HELCTR } from '../../constants';
|
|
80
|
+
|
|
81
|
+
const swe = new SwissEph();
|
|
82
|
+
|
|
83
|
+
// Check Mars geocentric vs heliocentric over a period that includes retrograde
|
|
84
|
+
const startJd = SwissEph.julianDay(2025, 10, 1, 0);
|
|
85
|
+
|
|
86
|
+
console.log('Date Geocentric Speed Heliocentric Speed Retro?');
|
|
87
|
+
console.log('---------- ---------- -------- ------------ ------ ------');
|
|
88
|
+
|
|
89
|
+
for (let day = 0; day < 180; day += 10) {
|
|
90
|
+
const jd = startJd + day;
|
|
91
|
+
const d = SwissEph.fromJulianDay(jd);
|
|
92
|
+
|
|
93
|
+
const geo = swe.calc(jd, SE_MARS); // geocentric (default)
|
|
94
|
+
const helio = swe.calc(jd, SE_MARS, SEFLG_HELCTR); // heliocentric
|
|
95
|
+
|
|
96
|
+
const retrograde = geo.longitudeSpeed < 0 ? ' YES' : ' no';
|
|
97
|
+
|
|
98
|
+
console.log(
|
|
99
|
+
`${d.year}-${String(d.month).padStart(2,'0')}-${String(Math.floor(d.day)).padStart(2,'0')} ` +
|
|
100
|
+
`${geo.longitude.toFixed(2).padStart(8)}° ` +
|
|
101
|
+
`${geo.longitudeSpeed.toFixed(4).padStart(8)} ` +
|
|
102
|
+
` ${helio.longitude.toFixed(2).padStart(8)}° ` +
|
|
103
|
+
`${helio.longitudeSpeed.toFixed(4).padStart(6)} ` +
|
|
104
|
+
` ${retrograde}`
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
swe.close();
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Notice that the heliocentric speed is always positive (the planet never reverses in reality), while the geocentric speed can become negative during retrograde periods.
|
|
112
|
+
|
|
113
|
+
### Computing a synodic cycle heliocentrically
|
|
114
|
+
|
|
115
|
+
A **synodic cycle** is the time between two successive conjunctions of a planet with another body as seen from the Sun. The simplest case: how long between successive heliocentric conjunctions of Earth and Mars?
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { SwissEph } from '../index';
|
|
119
|
+
import { SE_EARTH } from '../../constants';
|
|
120
|
+
|
|
121
|
+
const swe = new SwissEph();
|
|
122
|
+
|
|
123
|
+
// First, find Earth's heliocentric longitude at a starting point
|
|
124
|
+
const jd1 = SwissEph.julianDay(2025, 1, 1, 0);
|
|
125
|
+
const earth1 = swe.calc(jd1, SE_EARTH, 256); // SEFLG_HELCTR = 256
|
|
126
|
+
|
|
127
|
+
// Find when Mars next reaches that same heliocentric longitude
|
|
128
|
+
// (this approximates the heliocentric conjunction)
|
|
129
|
+
const mars1 = swe.helioCrossing(4, earth1.longitude, jd1); // SE_MARS = 4
|
|
130
|
+
const d1 = SwissEph.fromJulianDay(mars1.jd);
|
|
131
|
+
console.log(`Mars-Earth heliocentric conjunction ~${d1.year}-${String(d1.month).padStart(2,'0')}-${String(Math.floor(d1.day)).padStart(2,'0')}`);
|
|
132
|
+
|
|
133
|
+
// Find the next one (~780 days later, the Mars synodic period)
|
|
134
|
+
const mars2 = swe.helioCrossing(4, earth1.longitude, mars1.jd + 700);
|
|
135
|
+
const d2 = SwissEph.fromJulianDay(mars2.jd);
|
|
136
|
+
console.log(`Next conjunction ~${d2.year}-${String(d2.month).padStart(2,'0')}-${String(Math.floor(d2.day)).padStart(2,'0')}`);
|
|
137
|
+
|
|
138
|
+
const synodicDays = mars2.jd - mars1.jd;
|
|
139
|
+
console.log(`Synodic period: ${synodicDays.toFixed(1)} days (${(synodicDays / 365.25).toFixed(2)} years)`);
|
|
140
|
+
// Mars synodic period is approximately 780 days (2.135 years)
|
|
141
|
+
|
|
142
|
+
swe.close();
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Searching backward in time
|
|
146
|
+
|
|
147
|
+
The `dir` parameter allows searching in the reverse direction:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { SwissEph } from '../index';
|
|
151
|
+
import { SE_JUPITER } from '../../constants';
|
|
152
|
+
|
|
153
|
+
const swe = new SwissEph();
|
|
154
|
+
const now = SwissEph.julianDay(2025, 6, 15, 0);
|
|
155
|
+
|
|
156
|
+
// Find the PREVIOUS time Jupiter was at 0° heliocentric (searching backward)
|
|
157
|
+
const prev = swe.helioCrossing(SE_JUPITER, 0, now, 0, -1);
|
|
158
|
+
const dp = SwissEph.fromJulianDay(prev.jd);
|
|
159
|
+
console.log(`Jupiter last crossed 0° helio: ${dp.year}-${String(dp.month).padStart(2,'0')}-${String(Math.floor(dp.day)).padStart(2,'0')}`);
|
|
160
|
+
|
|
161
|
+
// Find the NEXT time (searching forward, the default)
|
|
162
|
+
const next = swe.helioCrossing(SE_JUPITER, 0, now, 0, 0);
|
|
163
|
+
const dn = SwissEph.fromJulianDay(next.jd);
|
|
164
|
+
console.log(`Jupiter next crosses 0° helio: ${dn.year}-${String(dn.month).padStart(2,'0')}-${String(Math.floor(dn.day)).padStart(2,'0')}`);
|
|
165
|
+
|
|
166
|
+
const period = next.jd - prev.jd;
|
|
167
|
+
console.log(`Jupiter heliocentric period: ${(period / 365.25).toFixed(2)} years`);
|
|
168
|
+
// Should be close to 11.86 years
|
|
169
|
+
|
|
170
|
+
swe.close();
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### All outer planets: time to complete one heliocentric orbit
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { SwissEph } from '../index';
|
|
177
|
+
import {
|
|
178
|
+
SE_MARS, SE_JUPITER, SE_SATURN,
|
|
179
|
+
SE_URANUS, SE_NEPTUNE, SE_PLUTO,
|
|
180
|
+
} from '../../constants';
|
|
181
|
+
|
|
182
|
+
const swe = new SwissEph();
|
|
183
|
+
|
|
184
|
+
const planets = [
|
|
185
|
+
{ id: SE_MARS, name: 'Mars' },
|
|
186
|
+
{ id: SE_JUPITER, name: 'Jupiter' },
|
|
187
|
+
{ id: SE_SATURN, name: 'Saturn' },
|
|
188
|
+
{ id: SE_URANUS, name: 'Uranus' },
|
|
189
|
+
{ id: SE_NEPTUNE, name: 'Neptune' },
|
|
190
|
+
{ id: SE_PLUTO, name: 'Pluto' },
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
const now = SwissEph.julianDay(2025, 1, 1, 0);
|
|
194
|
+
|
|
195
|
+
for (const pl of planets) {
|
|
196
|
+
// Find when the planet crosses 0° going forward from now
|
|
197
|
+
const cross1 = swe.helioCrossing(pl.id, 0, now);
|
|
198
|
+
// Find the next crossing of 0° (one full orbit later)
|
|
199
|
+
const cross2 = swe.helioCrossing(pl.id, 0, cross1.jd + 30);
|
|
200
|
+
|
|
201
|
+
const periodDays = cross2.jd - cross1.jd;
|
|
202
|
+
const periodYears = periodDays / 365.25;
|
|
203
|
+
|
|
204
|
+
console.log(`${pl.name.padEnd(9)} orbital period: ${periodYears.toFixed(2)} years (${periodDays.toFixed(0)} days)`);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
swe.close();
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Deep Explanation
|
|
213
|
+
|
|
214
|
+
### Heliocentric vs. Geocentric Coordinates
|
|
215
|
+
|
|
216
|
+
**Geocentric** coordinates describe positions as seen from Earth. This is the traditional astronomical and astrological perspective. Geocentric positions include all the apparent effects of Earth's own orbital motion: retrograde loops, varying speeds, and the oscillation of inferior planets around the Sun.
|
|
217
|
+
|
|
218
|
+
**Heliocentric** coordinates describe positions as seen from the Sun (from the Greek "helios" = sun). From this viewpoint:
|
|
219
|
+
- All planets move in the same direction (counterclockwise as seen from above the ecliptic)
|
|
220
|
+
- Planets never go retrograde
|
|
221
|
+
- Orbital speeds are nearly constant (varying only due to orbital eccentricity)
|
|
222
|
+
- The geometry is much simpler -- it directly reflects the physical reality of the solar system
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
Geocentric view: Heliocentric view:
|
|
226
|
+
|
|
227
|
+
Mars appears to Mars moves steadily
|
|
228
|
+
loop backward in one direction
|
|
229
|
+
(retrograde) (no retrograde)
|
|
230
|
+
|
|
231
|
+
* * * * * * * * *
|
|
232
|
+
* * (smooth curve)
|
|
233
|
+
* *
|
|
234
|
+
* *
|
|
235
|
+
* *
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Why Retrograde is a Geocentric Illusion
|
|
239
|
+
|
|
240
|
+
Retrograde motion occurs because Earth orbits faster than the outer planets. When Earth "overtakes" an outer planet, that planet appears to drift backward against the background stars -- much like a slower car on the highway appears to move backward when you pass it.
|
|
241
|
+
|
|
242
|
+
Heliocentrically, no planet ever reverses direction. The heliocentric speed is always positive (for prograde orbits). This is why `helioCrossing()` gives clean, unambiguous results -- there is exactly one crossing of any longitude per orbit.
|
|
243
|
+
|
|
244
|
+
### Which Planets Can Use helioCrossing?
|
|
245
|
+
|
|
246
|
+
The `helioCrossing()` method works for any body that orbits the Sun:
|
|
247
|
+
|
|
248
|
+
| Planet | Works? | Orbital Period |
|
|
249
|
+
|--------|--------|---------------|
|
|
250
|
+
| Mercury | Yes | 0.24 years (88 days) |
|
|
251
|
+
| Venus | Yes | 0.62 years (225 days) |
|
|
252
|
+
| Earth | Yes (SE_EARTH = 14) | 1.00 year (365.25 days) |
|
|
253
|
+
| Mars | Yes | 1.88 years |
|
|
254
|
+
| Jupiter | Yes | 11.86 years |
|
|
255
|
+
| Saturn | Yes | 29.46 years |
|
|
256
|
+
| Uranus | Yes | 84.01 years |
|
|
257
|
+
| Neptune | Yes | 164.8 years |
|
|
258
|
+
| Pluto | Yes | 247.9 years |
|
|
259
|
+
| Chiron | Yes | ~50.7 years |
|
|
260
|
+
| Sun | No | The Sun IS the center in heliocentric coordinates |
|
|
261
|
+
| Moon | No | The Moon orbits Earth, not the Sun directly |
|
|
262
|
+
|
|
263
|
+
For the Moon, use `moonCrossing()` instead. For the Sun, use `sunCrossing()`.
|
|
264
|
+
|
|
265
|
+
### The `dir` Parameter
|
|
266
|
+
|
|
267
|
+
- `dir = 0` (default): Search **forward** in time from `jd`
|
|
268
|
+
- `dir = -1` (or any negative value): Search **backward** in time from `jd`
|
|
269
|
+
|
|
270
|
+
This is useful when you want to find, for example, the most recent time a planet was at a particular longitude.
|
|
271
|
+
|
|
272
|
+
### Synodic Periods
|
|
273
|
+
|
|
274
|
+
The **synodic period** is the time between successive conjunctions of two bodies as seen from a third (usually the Sun). For a planet and Earth:
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
Synodic period = 1 / |1/P_earth - 1/P_planet|
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Where P is the orbital period. Some examples:
|
|
281
|
+
| Planet | Synodic Period |
|
|
282
|
+
|--------|---------------|
|
|
283
|
+
| Mercury | 116 days |
|
|
284
|
+
| Venus | 584 days |
|
|
285
|
+
| Mars | 780 days (2.14 years) |
|
|
286
|
+
| Jupiter | 399 days (1.09 years) |
|
|
287
|
+
| Saturn | 378 days (1.04 years) |
|
|
288
|
+
|
|
289
|
+
### Heliocentric Astrology
|
|
290
|
+
|
|
291
|
+
Some astrologers use heliocentric charts alongside or instead of geocentric charts. In heliocentric astrology:
|
|
292
|
+
- The Sun is at the center (no Sun position in the chart)
|
|
293
|
+
- The Moon is not used (it orbits Earth, not the Sun)
|
|
294
|
+
- Earth replaces the Sun as a charted body
|
|
295
|
+
- There are no retrograde periods
|
|
296
|
+
- Aspects between planets reflect the actual geometric relationships in space
|
|
297
|
+
|
|
298
|
+
Proponents argue that heliocentric aspects represent the "objective" or "cosmic" energies, while geocentric aspects represent the "subjective" or "personal" experience of those energies.
|
|
299
|
+
|
|
300
|
+
### Precision and Edge Cases
|
|
301
|
+
|
|
302
|
+
The `helioCrossing()` function uses iterative numerical methods to find the exact crossing time. For planets with nearly circular orbits (Venus, Earth), convergence is quick and very precise. For planets with higher eccentricity (Mercury, Mars, Pluto), the function still converges but may take slightly more iterations internally.
|
|
303
|
+
|
|
304
|
+
For very slow planets (Neptune, Pluto), note that a single heliocentric crossing takes a very long time -- Pluto takes nearly 248 years for one orbit, so it crosses a given longitude only once in a human lifetime. The function handles this correctly but be aware that searching for the "next" crossing of a slow planet may return a date far in the future.
|
|
305
|
+
|
|
306
|
+
### API Details
|
|
307
|
+
|
|
308
|
+
```typescript
|
|
309
|
+
swe.helioCrossing(
|
|
310
|
+
planet: number, // Planet constant (SE_MARS, SE_JUPITER, etc.)
|
|
311
|
+
longitude: number, // Target heliocentric longitude in degrees (0-360)
|
|
312
|
+
jd: number, // Starting Julian Day
|
|
313
|
+
flags?: number, // Calculation flags (optional, default 0)
|
|
314
|
+
dir?: number // Search direction: 0 = forward (default), negative = backward
|
|
315
|
+
): CrossingResult
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Returns:**
|
|
319
|
+
```typescript
|
|
320
|
+
interface CrossingResult {
|
|
321
|
+
jd: number; // Julian Day of the crossing
|
|
322
|
+
}
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
The returned Julian Day can be converted to a calendar date with `SwissEph.fromJulianDay(result.jd)`.
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
# House Position
|
|
2
|
+
|
|
3
|
+
Once you have calculated the house cusps and a planet's ecliptic coordinates, the next natural question is: **which house does the planet fall in?** The `housePosition()` method answers this by returning a fractional house number. For example, a return value of `10.05` means the planet is in the 10th house, very near the beginning (cusp); `3.75` means the planet is three-quarters of the way through the 3rd house.
|
|
4
|
+
|
|
5
|
+
This is essential for chart interpretation -- the house a planet occupies tells you in which area of life that planet's energy is most active.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Quick Example
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
import { SwissEph } from '../index';
|
|
13
|
+
import { SE_SUN } from '../../constants';
|
|
14
|
+
|
|
15
|
+
const swe = new SwissEph();
|
|
16
|
+
|
|
17
|
+
const jd = SwissEph.julianDay(2000, 1, 1, 12);
|
|
18
|
+
const geo = { longitude: -0.1276, latitude: 51.5074 }; // London
|
|
19
|
+
|
|
20
|
+
// Step 1: Get house cusps (we need ARMC from the result)
|
|
21
|
+
const h = swe.houses(jd, geo, 'P'); // Placidus
|
|
22
|
+
|
|
23
|
+
// Step 2: Get the planet's ecliptic position
|
|
24
|
+
const sun = swe.calc(jd, SE_SUN);
|
|
25
|
+
|
|
26
|
+
// Step 3: Get the obliquity of the ecliptic
|
|
27
|
+
// (the ARMC and obliquity are needed for the house position calculation)
|
|
28
|
+
const eps = 23.4393; // approximate; for precision, compute from the engine
|
|
29
|
+
|
|
30
|
+
// Step 4: Find which house the Sun is in
|
|
31
|
+
const housePos = swe.housePosition(
|
|
32
|
+
h.armc, // ARMC (sidereal time in degrees)
|
|
33
|
+
geo.latitude, // geographic latitude
|
|
34
|
+
eps, // obliquity of the ecliptic
|
|
35
|
+
'P', // house system (must match what you used in houses())
|
|
36
|
+
sun.longitude, // planet's ecliptic longitude
|
|
37
|
+
sun.latitude // planet's ecliptic latitude
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const houseNumber = Math.floor(housePos);
|
|
41
|
+
console.log(`Sun is in house ${houseNumber} (exact position: ${housePos.toFixed(4)})`);
|
|
42
|
+
// Sun is in house 10 (exact position: 10.0536)
|
|
43
|
+
|
|
44
|
+
swe.close();
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Detailed Examples
|
|
50
|
+
|
|
51
|
+
### Complete workflow: all planets with their house positions
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
import { SwissEph } from '../index';
|
|
55
|
+
import {
|
|
56
|
+
SE_SUN, SE_MOON, SE_MERCURY, SE_VENUS, SE_MARS,
|
|
57
|
+
SE_JUPITER, SE_SATURN, SE_URANUS, SE_NEPTUNE, SE_PLUTO,
|
|
58
|
+
} from '../../constants';
|
|
59
|
+
|
|
60
|
+
const swe = new SwissEph();
|
|
61
|
+
|
|
62
|
+
const jd = SwissEph.julianDay(2024, 4, 8, 18.28);
|
|
63
|
+
const geo = { longitude: -104.0, latitude: 25.0 };
|
|
64
|
+
|
|
65
|
+
// Step 1: Get houses (Placidus)
|
|
66
|
+
const h = swe.houses(jd, geo, 'P');
|
|
67
|
+
|
|
68
|
+
// We need the obliquity. A good approximation for current dates:
|
|
69
|
+
const eps = 23.4393;
|
|
70
|
+
|
|
71
|
+
// Step 2: Calculate each planet and its house position
|
|
72
|
+
const planets = [
|
|
73
|
+
{ id: SE_SUN, name: 'Sun' },
|
|
74
|
+
{ id: SE_MOON, name: 'Moon' },
|
|
75
|
+
{ id: SE_MERCURY, name: 'Mercury' },
|
|
76
|
+
{ id: SE_VENUS, name: 'Venus' },
|
|
77
|
+
{ id: SE_MARS, name: 'Mars' },
|
|
78
|
+
{ id: SE_JUPITER, name: 'Jupiter' },
|
|
79
|
+
{ id: SE_SATURN, name: 'Saturn' },
|
|
80
|
+
{ id: SE_URANUS, name: 'Uranus' },
|
|
81
|
+
{ id: SE_NEPTUNE, name: 'Neptune' },
|
|
82
|
+
{ id: SE_PLUTO, name: 'Pluto' },
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
for (const p of planets) {
|
|
86
|
+
const pos = swe.calc(jd, p.id);
|
|
87
|
+
const hp = swe.housePosition(
|
|
88
|
+
h.armc, geo.latitude, eps, 'P',
|
|
89
|
+
pos.longitude, pos.latitude
|
|
90
|
+
);
|
|
91
|
+
const houseNum = Math.floor(hp);
|
|
92
|
+
const fraction = hp - houseNum;
|
|
93
|
+
const percent = (fraction * 100).toFixed(1);
|
|
94
|
+
|
|
95
|
+
console.log(
|
|
96
|
+
`${p.name.padEnd(9)} ` +
|
|
97
|
+
`lon: ${pos.longitude.toFixed(2).padStart(7)} ` +
|
|
98
|
+
`house: ${houseNum.toString().padStart(2)} ` +
|
|
99
|
+
`(${percent}% through the house)`
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
swe.close();
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Comparing house positions across different house systems
|
|
107
|
+
|
|
108
|
+
The same planet can fall in different houses depending on which house system you use:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { SwissEph } from '../index';
|
|
112
|
+
import { SE_MOON } from '../../constants';
|
|
113
|
+
|
|
114
|
+
const swe = new SwissEph();
|
|
115
|
+
|
|
116
|
+
const jd = SwissEph.julianDay(2024, 1, 1, 0);
|
|
117
|
+
const geo = { longitude: -73.9857, latitude: 40.7484 }; // New York
|
|
118
|
+
|
|
119
|
+
const moon = swe.calc(jd, SE_MOON);
|
|
120
|
+
const eps = 23.4393;
|
|
121
|
+
|
|
122
|
+
const systems = ['P', 'K', 'E', 'W', 'R', 'C', 'O', 'T'];
|
|
123
|
+
|
|
124
|
+
for (const sys of systems) {
|
|
125
|
+
const h = swe.houses(jd, geo, sys);
|
|
126
|
+
const hp = swe.housePosition(
|
|
127
|
+
h.armc, geo.latitude, eps, sys,
|
|
128
|
+
moon.longitude, moon.latitude
|
|
129
|
+
);
|
|
130
|
+
console.log(
|
|
131
|
+
`${swe.houseName(sys).padEnd(25)} Moon in house ${Math.floor(hp).toString().padStart(2)} (${hp.toFixed(3)})`
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
swe.close();
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Using obliquity from the engine
|
|
139
|
+
|
|
140
|
+
For maximum precision, compute the obliquity rather than using a constant. You can derive it from the engine by computing the ecliptic/nutation values:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { SwissEph } from '../index';
|
|
144
|
+
import { SE_SUN, SE_ECL_NUT } from '../../constants';
|
|
145
|
+
|
|
146
|
+
const swe = new SwissEph();
|
|
147
|
+
const jd = SwissEph.julianDay(2024, 1, 1, 12);
|
|
148
|
+
const geo = { longitude: -0.1276, latitude: 51.5074 };
|
|
149
|
+
|
|
150
|
+
// SE_ECL_NUT returns nutation and obliquity data:
|
|
151
|
+
// longitude = true obliquity of the ecliptic
|
|
152
|
+
// latitude = mean obliquity
|
|
153
|
+
const eclNut = swe.calc(jd, SE_ECL_NUT);
|
|
154
|
+
const trueObliquity = eclNut.longitude; // ~23.4362 deg for 2024
|
|
155
|
+
|
|
156
|
+
const h = swe.houses(jd, geo, 'P');
|
|
157
|
+
const sun = swe.calc(jd, SE_SUN);
|
|
158
|
+
|
|
159
|
+
const hp = swe.housePosition(
|
|
160
|
+
h.armc, geo.latitude, trueObliquity, 'P',
|
|
161
|
+
sun.longitude, sun.latitude
|
|
162
|
+
);
|
|
163
|
+
console.log(`Sun house position: ${hp.toFixed(4)} (using true obliquity ${trueObliquity.toFixed(4)} deg)`);
|
|
164
|
+
|
|
165
|
+
swe.close();
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Note**: `SE_ECL_NUT` has value `-1` and is a special "planet" number that returns ecliptic/nutation data instead of a planetary position.
|
|
169
|
+
|
|
170
|
+
### Interpreting the fractional house number
|
|
171
|
+
|
|
172
|
+
```typescript
|
|
173
|
+
// The house position is a floating-point number from 1.000 to 12.999...
|
|
174
|
+
|
|
175
|
+
const housePos = 7.333;
|
|
176
|
+
|
|
177
|
+
// Integer part = house number
|
|
178
|
+
const houseNumber = Math.floor(housePos);
|
|
179
|
+
// houseNumber = 7 (planet is in the 7th house)
|
|
180
|
+
|
|
181
|
+
// Fractional part = how far through the house (0.0 = at cusp, 1.0 = at next cusp)
|
|
182
|
+
const fraction = housePos - houseNumber;
|
|
183
|
+
// fraction = 0.333 (one-third of the way through the 7th house)
|
|
184
|
+
|
|
185
|
+
// Some astrologers divide houses into thirds:
|
|
186
|
+
// 0.00-0.33 = "early in the house" or "angular third"
|
|
187
|
+
// 0.33-0.67 = "middle of the house" or "succedent third"
|
|
188
|
+
// 0.67-1.00 = "late in the house" or "cadent third"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Deep Explanation
|
|
194
|
+
|
|
195
|
+
### Parameters explained
|
|
196
|
+
|
|
197
|
+
The `housePosition()` method requires five pieces of information:
|
|
198
|
+
|
|
199
|
+
| Parameter | Description |
|
|
200
|
+
|-----------|-------------------------------------------------------------------------------------------------|
|
|
201
|
+
| `armc` | ARMC (sidereal time expressed in degrees). Get this from the `armc` field of `houses()` result. ARMC = sidereal time in hours * 15. |
|
|
202
|
+
| `lat` | Geographic latitude of the observer in degrees. Positive = north, negative = south. |
|
|
203
|
+
| `eps` | Obliquity of the ecliptic in degrees. Approximately 23.44 degrees for current dates. For precision, compute using `SE_ECL_NUT`. |
|
|
204
|
+
| `system` | House system letter code (e.g., `'P'` for Placidus). Must match the system used when computing cusps. |
|
|
205
|
+
| `eclLon` | Planet's ecliptic longitude in degrees (0-360). |
|
|
206
|
+
| `eclLat` | Planet's ecliptic latitude in degrees. For the Sun this is essentially 0. For the Moon it can be up to ~5 degrees. For most planets it is small but nonzero. |
|
|
207
|
+
|
|
208
|
+
### The return value
|
|
209
|
+
|
|
210
|
+
The return value is a floating-point number:
|
|
211
|
+
- The integer part (1-12) is the house number.
|
|
212
|
+
- The fractional part (0.000 to 0.999...) indicates position within the house.
|
|
213
|
+
- The range is `1.0` to `12.999...` (never 13.0; after 12.999 it wraps to 1.0).
|
|
214
|
+
|
|
215
|
+
### Why ecliptic latitude matters
|
|
216
|
+
|
|
217
|
+
Most astrology software ignores ecliptic latitude when assigning house positions, effectively projecting every body onto the ecliptic (latitude = 0). This is acceptable for the Sun and inner planets (which stay very close to the ecliptic) but can matter for:
|
|
218
|
+
|
|
219
|
+
- **The Moon**: up to ~5 degrees of latitude
|
|
220
|
+
- **Pluto**: up to ~17 degrees of latitude
|
|
221
|
+
- **Asteroids**: highly inclined orbits
|
|
222
|
+
|
|
223
|
+
The Swiss Ephemeris `housePosition()` properly accounts for ecliptic latitude by converting the body's position through the house system's projection geometry. For the most accurate house placements, always pass the actual latitude.
|
|
224
|
+
|
|
225
|
+
If you want the traditional "projected onto the ecliptic" behavior, pass `0` for `eclLat`.
|
|
226
|
+
|
|
227
|
+
### House position vs. house cusp
|
|
228
|
+
|
|
229
|
+
These are different but related concepts:
|
|
230
|
+
|
|
231
|
+
- **House cusps** (`houses()`) give you the twelve boundary longitudes. They answer: "At what ecliptic degree does each house begin?"
|
|
232
|
+
- **House position** (`housePosition()`) gives you a planet's location within the house system. It answers: "Given this planet at this ecliptic longitude/latitude, which house is it in and how far through?"
|
|
233
|
+
|
|
234
|
+
You might think you could determine the house just by comparing the planet's longitude to the cusp longitudes. This works for simple systems (Equal, Whole Sign) but is incorrect for quadrant systems (Placidus, Koch, etc.) when the planet has nonzero ecliptic latitude. The `housePosition()` function handles the full 3D geometry correctly.
|
|
235
|
+
|
|
236
|
+
### Edge cases
|
|
237
|
+
|
|
238
|
+
**Circumpolar regions**: At high latitudes (near or beyond the Arctic/Antarctic circles), Placidus and Koch houses can become distorted or undefined. The `housePosition()` function may still return a value, but its astronomical meaning becomes questionable. Consider using Equal, Whole Sign, or Topocentric houses for locations beyond ~60 degrees latitude.
|
|
239
|
+
|
|
240
|
+
**Planets on a cusp**: If a planet's house position is very close to a whole number (e.g., 6.002 or 5.998), it is very near the cusp boundary. In practice, with a fractional position like 5.998, the planet is technically still in the 5th house but essentially at the 6th cusp. Different astrologers have different orb allowances for "conjunct the cusp."
|
|
241
|
+
|
|
242
|
+
**Consistency of system**: Always use the same house system letter code in both `houses()` (to get the ARMC and cusps) and `housePosition()`. Using mismatched systems will give incorrect results.
|
|
243
|
+
|
|
244
|
+
### Typical workflow summary
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
1. Choose a date/time and location
|
|
248
|
+
2. Compute Julian Day: jd = SwissEph.julianDay(...)
|
|
249
|
+
3. Compute house cusps: h = swe.houses(jd, geo, 'P')
|
|
250
|
+
4. Compute planet position: p = swe.calc(jd, SE_SUN)
|
|
251
|
+
5. Get obliquity: eps = 23.4393 (or compute via SE_ECL_NUT)
|
|
252
|
+
6. Get house position: hp = swe.housePosition(h.armc, geo.latitude, eps, 'P', p.longitude, p.latitude)
|
|
253
|
+
7. Interpret: Math.floor(hp) is the house number
|
|
254
|
+
```
|