@interstellar-tools/equations 1.0.0 → 1.1.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.
Files changed (57) hide show
  1. package/dist/categories/helpers/misc.d.ts +18 -0
  2. package/dist/categories/helpers/misc.d.ts.map +1 -1
  3. package/dist/categories/helpers/misc.js +24 -0
  4. package/dist/categories/helpers/misc.js.map +1 -1
  5. package/dist/categories/manoeuvres/burn-time.d.ts +63 -0
  6. package/dist/categories/manoeuvres/burn-time.d.ts.map +1 -0
  7. package/dist/categories/manoeuvres/burn-time.js +87 -0
  8. package/dist/categories/manoeuvres/burn-time.js.map +1 -0
  9. package/dist/categories/manoeuvres/gravity-loss.d.ts +48 -0
  10. package/dist/categories/manoeuvres/gravity-loss.d.ts.map +1 -0
  11. package/dist/categories/manoeuvres/gravity-loss.js +74 -0
  12. package/dist/categories/manoeuvres/gravity-loss.js.map +1 -0
  13. package/dist/categories/manoeuvres/initial-mass-for-delta-v.d.ts +60 -0
  14. package/dist/categories/manoeuvres/initial-mass-for-delta-v.d.ts.map +1 -0
  15. package/dist/categories/manoeuvres/initial-mass-for-delta-v.js +79 -0
  16. package/dist/categories/manoeuvres/initial-mass-for-delta-v.js.map +1 -0
  17. package/dist/categories/manoeuvres/mass-flow-rate.d.ts +57 -0
  18. package/dist/categories/manoeuvres/mass-flow-rate.d.ts.map +1 -0
  19. package/dist/categories/manoeuvres/mass-flow-rate.js +73 -0
  20. package/dist/categories/manoeuvres/mass-flow-rate.js.map +1 -0
  21. package/dist/categories/manoeuvres/rocket-thrust.d.ts +48 -0
  22. package/dist/categories/manoeuvres/rocket-thrust.d.ts.map +1 -0
  23. package/dist/categories/manoeuvres/rocket-thrust.js +62 -0
  24. package/dist/categories/manoeuvres/rocket-thrust.js.map +1 -0
  25. package/dist/categories/manoeuvres/thrust-to-weight.d.ts +57 -0
  26. package/dist/categories/manoeuvres/thrust-to-weight.d.ts.map +1 -0
  27. package/dist/categories/manoeuvres/thrust-to-weight.js +73 -0
  28. package/dist/categories/manoeuvres/thrust-to-weight.js.map +1 -0
  29. package/dist/categories/orbits/elements-to-state.d.ts +61 -0
  30. package/dist/categories/orbits/elements-to-state.d.ts.map +1 -0
  31. package/dist/categories/orbits/elements-to-state.js +107 -0
  32. package/dist/categories/orbits/elements-to-state.js.map +1 -0
  33. package/dist/categories/orbits/inclination-from-launch-azimuth.d.ts +64 -0
  34. package/dist/categories/orbits/inclination-from-launch-azimuth.d.ts.map +1 -0
  35. package/dist/categories/orbits/inclination-from-launch-azimuth.js +76 -0
  36. package/dist/categories/orbits/inclination-from-launch-azimuth.js.map +1 -0
  37. package/dist/categories/orbits/launch-azimuth-for-inclination.d.ts +71 -0
  38. package/dist/categories/orbits/launch-azimuth-for-inclination.d.ts.map +1 -0
  39. package/dist/categories/orbits/launch-azimuth-for-inclination.js +87 -0
  40. package/dist/categories/orbits/launch-azimuth-for-inclination.js.map +1 -0
  41. package/dist/categories/orbits/rotating-launch-azimuth.d.ts +49 -0
  42. package/dist/categories/orbits/rotating-launch-azimuth.d.ts.map +1 -0
  43. package/dist/categories/orbits/rotating-launch-azimuth.js +65 -0
  44. package/dist/categories/orbits/rotating-launch-azimuth.js.map +1 -0
  45. package/dist/categories/orbits/state-to-elements.d.ts +82 -0
  46. package/dist/categories/orbits/state-to-elements.d.ts.map +1 -0
  47. package/dist/categories/orbits/state-to-elements.js +131 -0
  48. package/dist/categories/orbits/state-to-elements.js.map +1 -0
  49. package/dist/categories/orbits/surface-rotation-speed.d.ts +61 -0
  50. package/dist/categories/orbits/surface-rotation-speed.d.ts.map +1 -0
  51. package/dist/categories/orbits/surface-rotation-speed.js +74 -0
  52. package/dist/categories/orbits/surface-rotation-speed.js.map +1 -0
  53. package/dist/index.d.ts +12 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +12 -0
  56. package/dist/index.js.map +1 -1
  57. package/package.json +1 -1
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Compute the **thrust** of a rocket engine from its exhaust, including the pressure term.
3
+ *
4
+ * $$
5
+ * F = \dot m\, v_e + (p_e - p_a)\, A_e
6
+ * $$
7
+ *
8
+ * Where:
9
+ * - $ \dot m $ is the mass flow rate (kg/s)
10
+ * - $ v_e $ is the exhaust velocity at the nozzle exit (m/s)
11
+ * - $ p_e $ is the pressure at the nozzle exit (Pa)
12
+ * - $ p_a $ is the ambient pressure (Pa), 0 in vacuum
13
+ * - $ A_e $ is the nozzle exit area (m²)
14
+ *
15
+ * **Units**
16
+ * - Inputs: `mDot` in **kg/s**, `ve` in **m/s**, `pe` and `pa` in **Pa**, `Ae` in **m²**.
17
+ * - Output: $ F $ in **N**.
18
+ *
19
+ * ::: info Notes
20
+ *
21
+ * - The same engine gives more thrust in vacuum than at sea level: $ p_a $ pushes back on the nozzle exit.
22
+ * - A nozzle with $ p_e < p_a $ is over-expanded, and the pressure term reduces the thrust.
23
+ * - With $ p_e = p_a $ the thrust is $ \dot m\, v_e $, and $ v_e $ equals $ I_{sp}\, g_0 $.
24
+ *
25
+ * :::
26
+ *
27
+ * @param mDot - Mass flow rate $ \dot m $ in **kg/s** (finite, >= 0).
28
+ * @param ve - Exhaust velocity $ v_e $ in **m/s** (finite, >= 0).
29
+ * @param pe - Nozzle exit pressure $ p_e $ in **Pa** (finite, >= 0).
30
+ * @param pa - Ambient pressure $ p_a $ in **Pa** (finite, >= 0).
31
+ * @param Ae - Nozzle exit area $ A_e $ in **m²** (finite, >= 0).
32
+ * @returns Thrust $ F $ in **N**. Can be negative for a badly over-expanded nozzle with little flow.
33
+ * @throws {TypeError} If any input is not a finite number.
34
+ * @throws {RangeError} If any input is negative.
35
+ * @group Manoeuvres
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * // 250 kg/s at 3000 m/s, exit at 70 kPa through a 1.2 m² nozzle
40
+ * const vacuum = rocketThrust(250, 3000, 70_000, 0, 1.2); // 834 000 N
41
+ * const seaLevel = rocketThrust(250, 3000, 70_000, 101_325, 1.2); // ≈ 712 410 N
42
+ * ```
43
+ *
44
+ * @see {@link massFlowRate}
45
+ * @see https://en.wikipedia.org/wiki/Rocket_engine_nozzle Rocket engine nozzle (thrust equation)
46
+ */
47
+ export declare const rocketThrust: (mDot: number, ve: number, pe: number, pa: number, Ae: number) => number;
48
+ //# sourceMappingURL=rocket-thrust.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rocket-thrust.d.ts","sourceRoot":"","sources":["../../../src/categories/manoeuvres/rocket-thrust.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,eAAO,MAAM,YAAY,GACvB,MAAM,MAAM,EACZ,IAAI,MAAM,EACV,IAAI,MAAM,EACV,IAAI,MAAM,EACV,IAAI,MAAM,KACT,MAeF,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Compute the **thrust** of a rocket engine from its exhaust, including the pressure term.
3
+ *
4
+ * $$
5
+ * F = \dot m\, v_e + (p_e - p_a)\, A_e
6
+ * $$
7
+ *
8
+ * Where:
9
+ * - $ \dot m $ is the mass flow rate (kg/s)
10
+ * - $ v_e $ is the exhaust velocity at the nozzle exit (m/s)
11
+ * - $ p_e $ is the pressure at the nozzle exit (Pa)
12
+ * - $ p_a $ is the ambient pressure (Pa), 0 in vacuum
13
+ * - $ A_e $ is the nozzle exit area (m²)
14
+ *
15
+ * **Units**
16
+ * - Inputs: `mDot` in **kg/s**, `ve` in **m/s**, `pe` and `pa` in **Pa**, `Ae` in **m²**.
17
+ * - Output: $ F $ in **N**.
18
+ *
19
+ * ::: info Notes
20
+ *
21
+ * - The same engine gives more thrust in vacuum than at sea level: $ p_a $ pushes back on the nozzle exit.
22
+ * - A nozzle with $ p_e < p_a $ is over-expanded, and the pressure term reduces the thrust.
23
+ * - With $ p_e = p_a $ the thrust is $ \dot m\, v_e $, and $ v_e $ equals $ I_{sp}\, g_0 $.
24
+ *
25
+ * :::
26
+ *
27
+ * @param mDot - Mass flow rate $ \dot m $ in **kg/s** (finite, >= 0).
28
+ * @param ve - Exhaust velocity $ v_e $ in **m/s** (finite, >= 0).
29
+ * @param pe - Nozzle exit pressure $ p_e $ in **Pa** (finite, >= 0).
30
+ * @param pa - Ambient pressure $ p_a $ in **Pa** (finite, >= 0).
31
+ * @param Ae - Nozzle exit area $ A_e $ in **m²** (finite, >= 0).
32
+ * @returns Thrust $ F $ in **N**. Can be negative for a badly over-expanded nozzle with little flow.
33
+ * @throws {TypeError} If any input is not a finite number.
34
+ * @throws {RangeError} If any input is negative.
35
+ * @group Manoeuvres
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * // 250 kg/s at 3000 m/s, exit at 70 kPa through a 1.2 m² nozzle
40
+ * const vacuum = rocketThrust(250, 3000, 70_000, 0, 1.2); // 834 000 N
41
+ * const seaLevel = rocketThrust(250, 3000, 70_000, 101_325, 1.2); // ≈ 712 410 N
42
+ * ```
43
+ *
44
+ * @see {@link massFlowRate}
45
+ * @see https://en.wikipedia.org/wiki/Rocket_engine_nozzle Rocket engine nozzle (thrust equation)
46
+ */
47
+ export const rocketThrust = (mDot, ve, pe, pa, Ae) => {
48
+ for (const [name, v] of [
49
+ ['mDot', mDot],
50
+ ['ve', ve],
51
+ ['pe', pe],
52
+ ['pa', pa],
53
+ ['Ae', Ae]
54
+ ]) {
55
+ if (!Number.isFinite(v))
56
+ throw new TypeError(`${name} must be a finite number. Received: ${v}`);
57
+ if (v < 0)
58
+ throw new RangeError(`${name} must be >= 0. Received: ${v}`);
59
+ }
60
+ return mDot * ve + (pe - pa) * Ae;
61
+ };
62
+ //# sourceMappingURL=rocket-thrust.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rocket-thrust.js","sourceRoot":"","sources":["../../../src/categories/manoeuvres/rocket-thrust.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,IAAY,EACZ,EAAU,EACV,EAAU,EACV,EAAU,EACV,EAAU,EACF,EAAE;IACV,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI;QACtB,CAAC,MAAM,EAAE,IAAI,CAAC;QACd,CAAC,IAAI,EAAE,EAAE,CAAC;QACV,CAAC,IAAI,EAAE,EAAE,CAAC;QACV,CAAC,IAAI,EAAE,EAAE,CAAC;QACV,CAAC,IAAI,EAAE,EAAE,CAAC;KACF,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YACrB,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,uCAAuC,CAAC,EAAE,CAAC,CAAC;QAEzE,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM,IAAI,UAAU,CAAC,GAAG,IAAI,4BAA4B,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,OAAO,IAAI,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;AACpC,CAAC,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Compute the **thrust-to-weight ratio** of a vehicle in a gravity field.
3
+ *
4
+ * $$
5
+ * \frac{T}{W} = \frac{F}{m\, g}
6
+ * $$
7
+ *
8
+ * Where:
9
+ * - $ F $ is the thrust (N)
10
+ * - $ m $ is the vehicle's mass (kg)
11
+ * - $ g $ is the local gravitational acceleration (m/s²)
12
+ *
13
+ * **Units**
14
+ * - Inputs: `F` in **N**, `m` in **kg**, `g` in **m/s²**.
15
+ * - Output: dimensionless ratio.
16
+ *
17
+ * ::: info Notes
18
+ *
19
+ * - A vehicle can only lift off vertically when $ T/W > 1 $.
20
+ * - Use the local $ g $, e.g. $ \mu / r^2 $ for the body you're on, not standard gravity.
21
+ * - The ratio grows during a burn as propellant is used up; pass the current mass.
22
+ *
23
+ * :::
24
+ *
25
+ * ::: practice Apollo 11's lunar module, leaving the Moon
26
+ *
27
+ * **1.94**
28
+ *
29
+ * _Ascent stage at liftoff, in the Moon's 1.62 m/s² gravity_
30
+ *
31
+ * On Earth the same stage would manage only 0.32: too little to lift off.
32
+ *
33
+ * ```ts
34
+ * thrustToWeight(15_409, 4888, 1.624); // ≈ 1.94
35
+ * ```
36
+ *
37
+ * :::
38
+ *
39
+ * @param F - Thrust $ F $ in **N** (finite, >= 0).
40
+ * @param m - Mass $ m $ in **kg** (finite, > 0).
41
+ * @param g - Local gravitational acceleration $ g $ in **m/s²** (finite, > 0).
42
+ * @returns Thrust-to-weight ratio (dimensionless).
43
+ * @throws {TypeError} If any input is not a finite number.
44
+ * @throws {RangeError} If `F < 0`, `m <= 0` or `g <= 0`.
45
+ * @group Manoeuvres
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * // A 2000 kg lander with a 45 kN engine on Mars (g ≈ 3.71 m/s²)
50
+ * const tw = thrustToWeight(45_000, 2000, 3.71);
51
+ * // tw ≈ 6.06
52
+ * ```
53
+ *
54
+ * @see {@link massFlowRate}
55
+ */
56
+ export declare const thrustToWeight: (F: number, m: number, g: number) => number;
57
+ //# sourceMappingURL=thrust-to-weight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thrust-to-weight.d.ts","sourceRoot":"","sources":["../../../src/categories/manoeuvres/thrust-to-weight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,eAAO,MAAM,cAAc,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,KAAG,MAiBhE,CAAC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Compute the **thrust-to-weight ratio** of a vehicle in a gravity field.
3
+ *
4
+ * $$
5
+ * \frac{T}{W} = \frac{F}{m\, g}
6
+ * $$
7
+ *
8
+ * Where:
9
+ * - $ F $ is the thrust (N)
10
+ * - $ m $ is the vehicle's mass (kg)
11
+ * - $ g $ is the local gravitational acceleration (m/s²)
12
+ *
13
+ * **Units**
14
+ * - Inputs: `F` in **N**, `m` in **kg**, `g` in **m/s²**.
15
+ * - Output: dimensionless ratio.
16
+ *
17
+ * ::: info Notes
18
+ *
19
+ * - A vehicle can only lift off vertically when $ T/W > 1 $.
20
+ * - Use the local $ g $, e.g. $ \mu / r^2 $ for the body you're on, not standard gravity.
21
+ * - The ratio grows during a burn as propellant is used up; pass the current mass.
22
+ *
23
+ * :::
24
+ *
25
+ * ::: practice Apollo 11's lunar module, leaving the Moon
26
+ *
27
+ * **1.94**
28
+ *
29
+ * _Ascent stage at liftoff, in the Moon's 1.62 m/s² gravity_
30
+ *
31
+ * On Earth the same stage would manage only 0.32: too little to lift off.
32
+ *
33
+ * ```ts
34
+ * thrustToWeight(15_409, 4888, 1.624); // ≈ 1.94
35
+ * ```
36
+ *
37
+ * :::
38
+ *
39
+ * @param F - Thrust $ F $ in **N** (finite, >= 0).
40
+ * @param m - Mass $ m $ in **kg** (finite, > 0).
41
+ * @param g - Local gravitational acceleration $ g $ in **m/s²** (finite, > 0).
42
+ * @returns Thrust-to-weight ratio (dimensionless).
43
+ * @throws {TypeError} If any input is not a finite number.
44
+ * @throws {RangeError} If `F < 0`, `m <= 0` or `g <= 0`.
45
+ * @group Manoeuvres
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * // A 2000 kg lander with a 45 kN engine on Mars (g ≈ 3.71 m/s²)
50
+ * const tw = thrustToWeight(45_000, 2000, 3.71);
51
+ * // tw ≈ 6.06
52
+ * ```
53
+ *
54
+ * @see {@link massFlowRate}
55
+ */
56
+ export const thrustToWeight = (F, m, g) => {
57
+ for (const [name, v] of [
58
+ ['F', F],
59
+ ['m', m],
60
+ ['g', g]
61
+ ]) {
62
+ if (!Number.isFinite(v))
63
+ throw new TypeError(`${name} must be a finite number. Received: ${v}`);
64
+ }
65
+ if (F < 0)
66
+ throw new RangeError(`F must be >= 0. Received: ${F}`);
67
+ if (m <= 0)
68
+ throw new RangeError(`m must be > 0. Received: ${m}`);
69
+ if (g <= 0)
70
+ throw new RangeError(`g must be > 0. Received: ${g}`);
71
+ return F / (m * g);
72
+ };
73
+ //# sourceMappingURL=thrust-to-weight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thrust-to-weight.js","sourceRoot":"","sources":["../../../src/categories/manoeuvres/thrust-to-weight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAU,EAAE;IACxE,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI;QACtB,CAAC,GAAG,EAAE,CAAC,CAAC;QACR,CAAC,GAAG,EAAE,CAAC,CAAC;QACR,CAAC,GAAG,EAAE,CAAC,CAAC;KACA,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YACrB,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,uCAAuC,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,6BAA6B,CAAC,EAAE,CAAC,CAAC;IAElE,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC;IAElE,IAAI,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,UAAU,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC;IAElE,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACrB,CAAC,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { ClassicalElementsInterface, StateVectorInterface } from '@interstellar-tools/types';
2
+ /**
3
+ * Convert the six **classical orbital elements** to a **state vector** (position and velocity).
4
+ *
5
+ * In the perifocal frame, with $ p = a(1 - e^2) $:
6
+ *
7
+ * $$
8
+ * \mathbf r_{PQW} = \frac{p}{1 + e\cos\nu}\begin{pmatrix}\cos\nu \\ \sin\nu \\ 0\end{pmatrix}, \quad
9
+ * \mathbf v_{PQW} = \sqrt{\frac{\mu}{p}}\begin{pmatrix}-\sin\nu \\ e + \cos\nu \\ 0\end{pmatrix}
10
+ * $$
11
+ *
12
+ * then rotated into the inertial frame:
13
+ *
14
+ * $$
15
+ * \mathbf r = R_3(\Omega)\,R_1(i)\,R_3(\omega)\,\mathbf r_{PQW}, \quad
16
+ * \mathbf v = R_3(\Omega)\,R_1(i)\,R_3(\omega)\,\mathbf v_{PQW}
17
+ * $$
18
+ *
19
+ * **Units**
20
+ * - Inputs: `a` in **m**, `e` dimensionless, angles in **radians**, `mu` in **m³/s²**.
21
+ * - Output: `r` in **m**, `v` in **m/s**.
22
+ *
23
+ * ::: info Notes
24
+ *
25
+ * - The inverse of {@link stateToElements}, including its conventions for circular and equatorial orbits.
26
+ * - Elliptic orbits need $ a > 0 $ and hyperbolic ones $ a < 0 $. A parabolic orbit ($ e = 1 $) has no finite $ a $, so it isn't supported.
27
+ * - On a hyperbola, only true anomalies with $ 1 + e\cos\nu > 0 $ exist: the body never reaches the asymptotes.
28
+ *
29
+ * :::
30
+ *
31
+ * @param elements - The classical orbital elements.
32
+ * @param mu - Gravitational parameter $ \mu $ in **m³/s²** (finite, > 0).
33
+ * @returns The position `r` in **m** and velocity `v` in **m/s**.
34
+ * @throws {TypeError} If any input is not a finite number.
35
+ * @throws {RangeError} If `mu <= 0`, `e < 0`, `e = 1`, `i` is outside [0, π], `a` has the wrong sign for `e`, or `nu` is beyond a hyperbola's asymptotes.
36
+ * @group Orbits
37
+ *
38
+ * @example
39
+ * ```ts
40
+ * import type { Radians } from '@interstellar-tools/types';
41
+ *
42
+ * // A circular, equatorial orbit at 7000 km, a quarter of the way round
43
+ * const { r, v } = elementsToState(
44
+ * {
45
+ * a: 7_000_000,
46
+ * e: 0,
47
+ * i: 0 as Radians,
48
+ * raan: 0 as Radians,
49
+ * argp: 0 as Radians,
50
+ * nu: (Math.PI / 2) as Radians
51
+ * },
52
+ * 3.986004418e14
53
+ * );
54
+ * // r ≈ [0, 7 000 000, 0] m, v ≈ [-7546, 0, 0] m/s
55
+ * ```
56
+ *
57
+ * @see {@link stateToElements}
58
+ * @see https://en.wikipedia.org/wiki/Perifocal_coordinate_system Perifocal coordinate system
59
+ */
60
+ export declare const elementsToState: (elements: ClassicalElementsInterface, mu: number) => StateVectorInterface;
61
+ //# sourceMappingURL=elements-to-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elements-to-state.d.ts","sourceRoot":"","sources":["../../../src/categories/orbits/elements-to-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,0BAA0B,EAC1B,oBAAoB,EAErB,MAAM,2BAA2B,CAAC;AAOnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDG;AACH,eAAO,MAAM,eAAe,GAC1B,UAAU,0BAA0B,EACpC,IAAI,MAAM,KACT,oBA4DF,CAAC"}
@@ -0,0 +1,107 @@
1
+ import { applyMatrix3 } from '../helpers/apply-matrix-3.js';
2
+ import { matMul3 } from '../helpers/mat-mul3.js';
3
+ import { rot1 } from '../helpers/rot-1.js';
4
+ import { rot3 } from '../helpers/rot-3.js';
5
+ /**
6
+ * Convert the six **classical orbital elements** to a **state vector** (position and velocity).
7
+ *
8
+ * In the perifocal frame, with $ p = a(1 - e^2) $:
9
+ *
10
+ * $$
11
+ * \mathbf r_{PQW} = \frac{p}{1 + e\cos\nu}\begin{pmatrix}\cos\nu \\ \sin\nu \\ 0\end{pmatrix}, \quad
12
+ * \mathbf v_{PQW} = \sqrt{\frac{\mu}{p}}\begin{pmatrix}-\sin\nu \\ e + \cos\nu \\ 0\end{pmatrix}
13
+ * $$
14
+ *
15
+ * then rotated into the inertial frame:
16
+ *
17
+ * $$
18
+ * \mathbf r = R_3(\Omega)\,R_1(i)\,R_3(\omega)\,\mathbf r_{PQW}, \quad
19
+ * \mathbf v = R_3(\Omega)\,R_1(i)\,R_3(\omega)\,\mathbf v_{PQW}
20
+ * $$
21
+ *
22
+ * **Units**
23
+ * - Inputs: `a` in **m**, `e` dimensionless, angles in **radians**, `mu` in **m³/s²**.
24
+ * - Output: `r` in **m**, `v` in **m/s**.
25
+ *
26
+ * ::: info Notes
27
+ *
28
+ * - The inverse of {@link stateToElements}, including its conventions for circular and equatorial orbits.
29
+ * - Elliptic orbits need $ a > 0 $ and hyperbolic ones $ a < 0 $. A parabolic orbit ($ e = 1 $) has no finite $ a $, so it isn't supported.
30
+ * - On a hyperbola, only true anomalies with $ 1 + e\cos\nu > 0 $ exist: the body never reaches the asymptotes.
31
+ *
32
+ * :::
33
+ *
34
+ * @param elements - The classical orbital elements.
35
+ * @param mu - Gravitational parameter $ \mu $ in **m³/s²** (finite, > 0).
36
+ * @returns The position `r` in **m** and velocity `v` in **m/s**.
37
+ * @throws {TypeError} If any input is not a finite number.
38
+ * @throws {RangeError} If `mu <= 0`, `e < 0`, `e = 1`, `i` is outside [0, π], `a` has the wrong sign for `e`, or `nu` is beyond a hyperbola's asymptotes.
39
+ * @group Orbits
40
+ *
41
+ * @example
42
+ * ```ts
43
+ * import type { Radians } from '@interstellar-tools/types';
44
+ *
45
+ * // A circular, equatorial orbit at 7000 km, a quarter of the way round
46
+ * const { r, v } = elementsToState(
47
+ * {
48
+ * a: 7_000_000,
49
+ * e: 0,
50
+ * i: 0 as Radians,
51
+ * raan: 0 as Radians,
52
+ * argp: 0 as Radians,
53
+ * nu: (Math.PI / 2) as Radians
54
+ * },
55
+ * 3.986004418e14
56
+ * );
57
+ * // r ≈ [0, 7 000 000, 0] m, v ≈ [-7546, 0, 0] m/s
58
+ * ```
59
+ *
60
+ * @see {@link stateToElements}
61
+ * @see https://en.wikipedia.org/wiki/Perifocal_coordinate_system Perifocal coordinate system
62
+ */
63
+ export const elementsToState = (elements, mu) => {
64
+ const { a, e, i, raan, argp, nu } = elements;
65
+ for (const [name, x] of [
66
+ ['a', a],
67
+ ['e', e],
68
+ ['i', i],
69
+ ['raan', raan],
70
+ ['argp', argp],
71
+ ['nu', nu],
72
+ ['mu', mu]
73
+ ]) {
74
+ if (!Number.isFinite(x))
75
+ throw new TypeError(`${name} must be a finite number. Received: ${x}`);
76
+ }
77
+ if (mu <= 0)
78
+ throw new RangeError(`mu must be > 0. Received: ${mu}`);
79
+ if (e < 0)
80
+ throw new RangeError(`e must be >= 0. Received: ${e}`);
81
+ if (Math.abs(e - 1) < 1e-12)
82
+ throw new RangeError('Parabolic orbits (e = 1) are not supported: they have no finite semi-major axis.');
83
+ if (i < 0 || i > Math.PI)
84
+ throw new RangeError(`i must be in [0, π]. Received: ${i}`);
85
+ if (e < 1 && a <= 0)
86
+ throw new RangeError(`a must be > 0 for an elliptic orbit. Received: a=${a}, e=${e}`);
87
+ if (e > 1 && a >= 0)
88
+ throw new RangeError(`a must be < 0 for a hyperbolic orbit. Received: a=${a}, e=${e}`);
89
+ const p = a * (1 - e * e);
90
+ const denominator = 1 + e * Math.cos(nu);
91
+ if (denominator <= 0)
92
+ throw new RangeError(`nu is beyond the hyperbola's asymptotes (1 + e cos nu <= 0). Received: nu=${nu}, e=${e}`);
93
+ const rPqw = [
94
+ (p * Math.cos(nu)) / denominator,
95
+ (p * Math.sin(nu)) / denominator,
96
+ 0
97
+ ];
98
+ const speed = Math.sqrt(mu / p);
99
+ const vPqw = [
100
+ -speed * Math.sin(nu),
101
+ speed * (e + Math.cos(nu)),
102
+ 0
103
+ ];
104
+ const Q = matMul3(matMul3(rot3(raan), rot1(i)), rot3(argp));
105
+ return { r: applyMatrix3(Q, rPqw), v: applyMatrix3(Q, vPqw) };
106
+ };
107
+ //# sourceMappingURL=elements-to-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elements-to-state.js","sourceRoot":"","sources":["../../../src/categories/orbits/elements-to-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { Radians } from '@interstellar-tools/types';
2
+ /**
3
+ * Compute the **inclination** of the orbit reached by launching from a latitude on an azimuth.
4
+ *
5
+ * $$
6
+ * \cos i = \cos\varphi \,\sin\beta
7
+ * $$
8
+ *
9
+ * Where:
10
+ * - $ i $ is the orbit's inclination (rad)
11
+ * - $ \varphi $ is the geocentric latitude of the point (rad)
12
+ * - $ \beta $ is the inertial azimuth or heading at that point, clockwise from north (rad)
13
+ *
14
+ * **Units**
15
+ * - Inputs: `lat` and `azimuth` in **radians**.
16
+ * - Output: $ i $ in **radians**, in [0, π].
17
+ *
18
+ * ::: info Notes
19
+ *
20
+ * - `lat` is the **geocentric** latitude. Published latitudes are usually geodetic, which on Earth differ by up to 0.19°, and the inclination by about as much. Convert first (see [#186](https://github.com/phun-ky/interstellar-tools/issues/186)).
21
+ * - The relation holds at every point of the ground track, not only at launch: an orbit never reaches a latitude higher than its inclination.
22
+ * - Launching due east ($ \beta = 90° $) gives the lowest inclination a site can reach without a plane change: its own latitude.
23
+ * - Azimuths between 180° and 360° head west, into retrograde orbits ($ i > 90° $).
24
+ * - `azimuth` is inertial. A rocket's azimuth over the ground differs, because the pad is moving east; see {@link rotatingLaunchAzimuth}.
25
+ *
26
+ * :::
27
+ *
28
+ * ::: practice Apollo 11, entering Earth orbit
29
+ *
30
+ * **32.52°**
31
+ *
32
+ * _At orbit insertion: 32.497° N geocentric, heading 88.848°_
33
+ *
34
+ * The flown parking orbit was inclined 32.521°. Apollo 11 entered orbit near the northernmost point of its track, heading almost due east. With the published geodetic latitude, 32.672°, the result would be 32.69°.
35
+ *
36
+ * ```ts
37
+ * inclinationFromLaunchAzimuth(toRad(32.497), toRad(88.848)); // ≈ 32.52°
38
+ * ```
39
+ *
40
+ * :::
41
+ *
42
+ * @param lat - Geocentric latitude $ \varphi $ in **radians** (finite, in [-π/2, π/2]).
43
+ * @param azimuth - Inertial azimuth $ \beta $ in **radians**, clockwise from north (finite).
44
+ * @returns Inclination $ i $ in **radians**, in [0, π].
45
+ * @throws {TypeError} If any input is not a finite number.
46
+ * @throws {RangeError} If `lat` is outside [-π/2, π/2].
47
+ * @group Orbits
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * import type { Radians } from '@interstellar-tools/types';
52
+ *
53
+ * const toRad = (deg: number) => ((deg * Math.PI) / 180) as Radians;
54
+ *
55
+ * // Baikonur (45.97° N), launching north-east at 63°
56
+ * const i = inclinationFromLaunchAzimuth(toRad(45.97), toRad(63));
57
+ * // i ≈ 51.7°
58
+ * ```
59
+ *
60
+ * @see {@link launchAzimuthForInclination}
61
+ * @see https://en.wikipedia.org/wiki/Launch_azimuth Launch azimuth
62
+ */
63
+ export declare const inclinationFromLaunchAzimuth: (lat: Radians, azimuth: Radians) => Radians;
64
+ //# sourceMappingURL=inclination-from-launch-azimuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inclination-from-launch-azimuth.d.ts","sourceRoot":"","sources":["../../../src/categories/orbits/inclination-from-launch-azimuth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,eAAO,MAAM,4BAA4B,GACvC,KAAK,OAAO,EACZ,SAAS,OAAO,KACf,OAgBF,CAAC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Compute the **inclination** of the orbit reached by launching from a latitude on an azimuth.
3
+ *
4
+ * $$
5
+ * \cos i = \cos\varphi \,\sin\beta
6
+ * $$
7
+ *
8
+ * Where:
9
+ * - $ i $ is the orbit's inclination (rad)
10
+ * - $ \varphi $ is the geocentric latitude of the point (rad)
11
+ * - $ \beta $ is the inertial azimuth or heading at that point, clockwise from north (rad)
12
+ *
13
+ * **Units**
14
+ * - Inputs: `lat` and `azimuth` in **radians**.
15
+ * - Output: $ i $ in **radians**, in [0, π].
16
+ *
17
+ * ::: info Notes
18
+ *
19
+ * - `lat` is the **geocentric** latitude. Published latitudes are usually geodetic, which on Earth differ by up to 0.19°, and the inclination by about as much. Convert first (see [#186](https://github.com/phun-ky/interstellar-tools/issues/186)).
20
+ * - The relation holds at every point of the ground track, not only at launch: an orbit never reaches a latitude higher than its inclination.
21
+ * - Launching due east ($ \beta = 90° $) gives the lowest inclination a site can reach without a plane change: its own latitude.
22
+ * - Azimuths between 180° and 360° head west, into retrograde orbits ($ i > 90° $).
23
+ * - `azimuth` is inertial. A rocket's azimuth over the ground differs, because the pad is moving east; see {@link rotatingLaunchAzimuth}.
24
+ *
25
+ * :::
26
+ *
27
+ * ::: practice Apollo 11, entering Earth orbit
28
+ *
29
+ * **32.52°**
30
+ *
31
+ * _At orbit insertion: 32.497° N geocentric, heading 88.848°_
32
+ *
33
+ * The flown parking orbit was inclined 32.521°. Apollo 11 entered orbit near the northernmost point of its track, heading almost due east. With the published geodetic latitude, 32.672°, the result would be 32.69°.
34
+ *
35
+ * ```ts
36
+ * inclinationFromLaunchAzimuth(toRad(32.497), toRad(88.848)); // ≈ 32.52°
37
+ * ```
38
+ *
39
+ * :::
40
+ *
41
+ * @param lat - Geocentric latitude $ \varphi $ in **radians** (finite, in [-π/2, π/2]).
42
+ * @param azimuth - Inertial azimuth $ \beta $ in **radians**, clockwise from north (finite).
43
+ * @returns Inclination $ i $ in **radians**, in [0, π].
44
+ * @throws {TypeError} If any input is not a finite number.
45
+ * @throws {RangeError} If `lat` is outside [-π/2, π/2].
46
+ * @group Orbits
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * import type { Radians } from '@interstellar-tools/types';
51
+ *
52
+ * const toRad = (deg: number) => ((deg * Math.PI) / 180) as Radians;
53
+ *
54
+ * // Baikonur (45.97° N), launching north-east at 63°
55
+ * const i = inclinationFromLaunchAzimuth(toRad(45.97), toRad(63));
56
+ * // i ≈ 51.7°
57
+ * ```
58
+ *
59
+ * @see {@link launchAzimuthForInclination}
60
+ * @see https://en.wikipedia.org/wiki/Launch_azimuth Launch azimuth
61
+ */
62
+ export const inclinationFromLaunchAzimuth = (lat, azimuth) => {
63
+ for (const [name, v] of [
64
+ ['lat', lat],
65
+ ['azimuth', azimuth]
66
+ ]) {
67
+ if (!Number.isFinite(v))
68
+ throw new TypeError(`${name} must be a finite number. Received: ${v}`);
69
+ }
70
+ if (Math.abs(lat) > Math.PI / 2)
71
+ throw new RangeError(`lat must be in [-π/2, π/2]. Received: ${lat}`);
72
+ // Clamp against rounding just outside [-1, 1]
73
+ const cosI = Math.min(1, Math.max(-1, Math.cos(lat) * Math.sin(azimuth)));
74
+ return Math.acos(cosI);
75
+ };
76
+ //# sourceMappingURL=inclination-from-launch-azimuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inclination-from-launch-azimuth.js","sourceRoot":"","sources":["../../../src/categories/orbits/inclination-from-launch-azimuth.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAC1C,GAAY,EACZ,OAAgB,EACP,EAAE;IACX,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI;QACtB,CAAC,KAAK,EAAE,GAAG,CAAC;QACZ,CAAC,SAAS,EAAE,OAAO,CAAC;KACZ,EAAE,CAAC;QACX,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YACrB,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,uCAAuC,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC;QAC7B,MAAM,IAAI,UAAU,CAAC,yCAAyC,GAAG,EAAE,CAAC,CAAC;IAEvE,8CAA8C;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAE1E,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAY,CAAC;AACpC,CAAC,CAAC"}
@@ -0,0 +1,71 @@
1
+ import type { Radians } from '@interstellar-tools/types';
2
+ export interface LaunchAzimuthsInterface {
3
+ /** Azimuth for the ascending pass: heading north, in [0, π/2] or [3π/2, 2π) */
4
+ northbound: Radians;
5
+ /** Azimuth for the descending pass: heading south, in [π/2, 3π/2] */
6
+ southbound: Radians;
7
+ }
8
+ /**
9
+ * Compute the **inertial launch azimuths** that reach an inclination from a latitude.
10
+ *
11
+ * $$
12
+ * \sin\beta = \frac{\cos i}{\cos\varphi}
13
+ * $$
14
+ *
15
+ * Where:
16
+ * - $ \beta $ is the inertial azimuth, clockwise from north (rad)
17
+ * - $ i $ is the target inclination (rad)
18
+ * - $ \varphi $ is the geocentric launch latitude (rad)
19
+ *
20
+ * Two azimuths reach every reachable inclination: one heading north ($ \beta $) and one heading south ($ \pi - \beta $).
21
+ *
22
+ * **Units**
23
+ * - Inputs: `lat` and `i` in **radians**.
24
+ * - Output: both azimuths in **radians**, in [0, 2π).
25
+ *
26
+ * ::: info Notes
27
+ *
28
+ * - `lat` is the **geocentric** latitude. Published latitudes are usually geodetic, which on Earth differ by up to 0.19°, and the inclination by about as much. Convert first (see [#186](https://github.com/phun-ky/interstellar-tools/issues/186)).
29
+ * - A site can only reach inclinations between $ |\varphi| $ and $ \pi - |\varphi| $ directly. Anything else needs a plane change, or a dogleg during ascent.
30
+ * - The azimuths are inertial. Over the ground, the rocket flies a slightly different heading; see {@link rotatingLaunchAzimuth}.
31
+ * - At $ i = |\varphi| $ the two solutions meet, due east (or due west for retrograde orbits).
32
+ *
33
+ * :::
34
+ *
35
+ * ::: practice To the ISS from Cape Canaveral
36
+ *
37
+ * **44.9°**
38
+ *
39
+ * _Inertial azimuth from Pad 39A, 28.447° N geocentric, to an orbit inclined 51.64°_
40
+ *
41
+ * Over the ground the rocket flies 42.7°, because the pad is already moving east at 409 m/s.
42
+ *
43
+ * ```ts
44
+ * launchAzimuthForInclination(toRad(28.447), toRad(51.64)).northbound; // ≈ 44.9°
45
+ * ```
46
+ *
47
+ * :::
48
+ *
49
+ * @param lat - Geocentric launch latitude $ \varphi $ in **radians** (finite, in (-π/2, π/2)).
50
+ * @param i - Target inclination $ i $ in **radians** (finite, in [0, π]).
51
+ * @returns The northbound and southbound inertial azimuths, in **radians**.
52
+ * @throws {TypeError} If any input is not a finite number.
53
+ * @throws {RangeError} If `lat` is not in (-π/2, π/2), `i` is not in [0, π], or `i` can't be reached from `lat` (`i < |lat|` or `i > π - |lat|`).
54
+ * @group Orbits
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * import type { Radians } from '@interstellar-tools/types';
59
+ *
60
+ * const toRad = (deg: number) => ((deg * Math.PI) / 180) as Radians;
61
+ *
62
+ * // A sun-synchronous orbit (97.8°) from Vandenberg (34.7° N)
63
+ * const { southbound } = launchAzimuthForInclination(toRad(34.7), toRad(97.8));
64
+ * // southbound ≈ 189.5°: south, slightly west
65
+ * ```
66
+ *
67
+ * @see {@link inclinationFromLaunchAzimuth}
68
+ * @see https://en.wikipedia.org/wiki/Launch_azimuth Launch azimuth
69
+ */
70
+ export declare const launchAzimuthForInclination: (lat: Radians, i: Radians) => LaunchAzimuthsInterface;
71
+ //# sourceMappingURL=launch-azimuth-for-inclination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-azimuth-for-inclination.d.ts","sourceRoot":"","sources":["../../../src/categories/orbits/launch-azimuth-for-inclination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAIzD,MAAM,WAAW,uBAAuB;IACtC,+EAA+E;IAC/E,UAAU,EAAE,OAAO,CAAC;IACpB,qEAAqE;IACrE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AACH,eAAO,MAAM,2BAA2B,GACtC,KAAK,OAAO,EACZ,GAAG,OAAO,KACT,uBA8BF,CAAC"}