@interstellar-tools/equations 0.1.1

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 (78) hide show
  1. package/README.md +18 -0
  2. package/dist/__tests__/compute-angle.int.spec.d.ts +2 -0
  3. package/dist/__tests__/compute-angle.int.spec.d.ts.map +1 -0
  4. package/dist/__tests__/compute-angle.int.spec.js +62 -0
  5. package/dist/__tests__/compute-angle.int.spec.js.map +1 -0
  6. package/dist/__tests__/compute-mean-anomaly.int.spec.d.ts +2 -0
  7. package/dist/__tests__/compute-mean-anomaly.int.spec.d.ts.map +1 -0
  8. package/dist/__tests__/compute-mean-anomaly.int.spec.js +175 -0
  9. package/dist/__tests__/compute-mean-anomaly.int.spec.js.map +1 -0
  10. package/dist/__tests__/eccentric-to-true-anomaly.spec.d.ts +2 -0
  11. package/dist/__tests__/eccentric-to-true-anomaly.spec.d.ts.map +1 -0
  12. package/dist/__tests__/eccentric-to-true-anomaly.spec.js +33 -0
  13. package/dist/__tests__/eccentric-to-true-anomaly.spec.js.map +1 -0
  14. package/dist/__tests__/solve-kepler-bisection.spec.d.ts +2 -0
  15. package/dist/__tests__/solve-kepler-bisection.spec.d.ts.map +1 -0
  16. package/dist/__tests__/solve-kepler-bisection.spec.js +41 -0
  17. package/dist/__tests__/solve-kepler-bisection.spec.js.map +1 -0
  18. package/dist/__tests__/solve-kepler-high-eccentricity.spec.d.ts +2 -0
  19. package/dist/__tests__/solve-kepler-high-eccentricity.spec.d.ts.map +1 -0
  20. package/dist/__tests__/solve-kepler-high-eccentricity.spec.js +81 -0
  21. package/dist/__tests__/solve-kepler-high-eccentricity.spec.js.map +1 -0
  22. package/dist/__tests__/solve-kepler-newton-raphson.spec.d.ts +2 -0
  23. package/dist/__tests__/solve-kepler-newton-raphson.spec.d.ts.map +1 -0
  24. package/dist/__tests__/solve-kepler-newton-raphson.spec.js +50 -0
  25. package/dist/__tests__/solve-kepler-newton-raphson.spec.js.map +1 -0
  26. package/dist/__tests__/solve-kepler.int.spec.d.ts +2 -0
  27. package/dist/__tests__/solve-kepler.int.spec.d.ts.map +1 -0
  28. package/dist/__tests__/solve-kepler.int.spec.js +76 -0
  29. package/dist/__tests__/solve-kepler.int.spec.js.map +1 -0
  30. package/dist/__tests__/true-anomaly-to-mean-anomaly.int.spec.d.ts +2 -0
  31. package/dist/__tests__/true-anomaly-to-mean-anomaly.int.spec.d.ts.map +1 -0
  32. package/dist/__tests__/true-anomaly-to-mean-anomaly.int.spec.js +46 -0
  33. package/dist/__tests__/true-anomaly-to-mean-anomaly.int.spec.js.map +1 -0
  34. package/dist/__tests__/wrap-angle.spec.d.ts +2 -0
  35. package/dist/__tests__/wrap-angle.spec.d.ts.map +1 -0
  36. package/dist/__tests__/wrap-angle.spec.js +60 -0
  37. package/dist/__tests__/wrap-angle.spec.js.map +1 -0
  38. package/dist/compute-angle.d.ts +69 -0
  39. package/dist/compute-angle.d.ts.map +1 -0
  40. package/dist/compute-angle.js +79 -0
  41. package/dist/compute-angle.js.map +1 -0
  42. package/dist/compute-mean-anomaly.d.ts +47 -0
  43. package/dist/compute-mean-anomaly.d.ts.map +1 -0
  44. package/dist/compute-mean-anomaly.js +86 -0
  45. package/dist/compute-mean-anomaly.js.map +1 -0
  46. package/dist/eccentric-to-true-anomaly.d.ts +43 -0
  47. package/dist/eccentric-to-true-anomaly.d.ts.map +1 -0
  48. package/dist/eccentric-to-true-anomaly.js +63 -0
  49. package/dist/eccentric-to-true-anomaly.js.map +1 -0
  50. package/dist/index.d.ts +16 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +16 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/solve-kepler-bisection.d.ts +75 -0
  55. package/dist/solve-kepler-bisection.d.ts.map +1 -0
  56. package/dist/solve-kepler-bisection.js +94 -0
  57. package/dist/solve-kepler-bisection.js.map +1 -0
  58. package/dist/solve-kepler-high-eccentricity.d.ts +99 -0
  59. package/dist/solve-kepler-high-eccentricity.d.ts.map +1 -0
  60. package/dist/solve-kepler-high-eccentricity.js +150 -0
  61. package/dist/solve-kepler-high-eccentricity.js.map +1 -0
  62. package/dist/solve-kepler-newton-raphson.d.ts +87 -0
  63. package/dist/solve-kepler-newton-raphson.d.ts.map +1 -0
  64. package/dist/solve-kepler-newton-raphson.js +118 -0
  65. package/dist/solve-kepler-newton-raphson.js.map +1 -0
  66. package/dist/solve-kepler.d.ts +82 -0
  67. package/dist/solve-kepler.d.ts.map +1 -0
  68. package/dist/solve-kepler.js +99 -0
  69. package/dist/solve-kepler.js.map +1 -0
  70. package/dist/true-anomaly-to-mean-anomaly.d.ts +74 -0
  71. package/dist/true-anomaly-to-mean-anomaly.d.ts.map +1 -0
  72. package/dist/true-anomaly-to-mean-anomaly.js +91 -0
  73. package/dist/true-anomaly-to-mean-anomaly.js.map +1 -0
  74. package/dist/wrap-angle.d.ts +82 -0
  75. package/dist/wrap-angle.d.ts.map +1 -0
  76. package/dist/wrap-angle.js +97 -0
  77. package/dist/wrap-angle.js.map +1 -0
  78. package/package.json +58 -0
@@ -0,0 +1,16 @@
1
+ /**
2
+ *
3
+ * Here you will find a set of function that can assist you when calculating orbits, angles, solve for kelper or find true anomalies.
4
+ * @showCategories
5
+ * @module
6
+ */
7
+ export * from './compute-angle';
8
+ export * from './compute-mean-anomaly';
9
+ export * from './eccentric-to-true-anomaly';
10
+ export * from './solve-kepler-bisection';
11
+ export * from './solve-kepler-high-eccentricity';
12
+ export * from './solve-kepler-newton-raphson';
13
+ export * from './solve-kepler';
14
+ export * from './true-anomaly-to-mean-anomaly';
15
+ export * from './wrap-angle';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,iBAAiB,CAAC;AAEhC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,6BAA6B,CAAC;AAE5C,cAAc,0BAA0B,CAAC;AAEzC,cAAc,kCAAkC,CAAC;AAEjD,cAAc,+BAA+B,CAAC;AAE9C,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gCAAgC,CAAC;AAE/C,cAAc,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ /**
2
+ *
3
+ * Here you will find a set of function that can assist you when calculating orbits, angles, solve for kelper or find true anomalies.
4
+ * @showCategories
5
+ * @module
6
+ */
7
+ export * from './compute-angle';
8
+ export * from './compute-mean-anomaly';
9
+ export * from './eccentric-to-true-anomaly';
10
+ export * from './solve-kepler-bisection';
11
+ export * from './solve-kepler-high-eccentricity';
12
+ export * from './solve-kepler-newton-raphson';
13
+ export * from './solve-kepler';
14
+ export * from './true-anomaly-to-mean-anomaly';
15
+ export * from './wrap-angle';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,cAAc,iBAAiB,CAAC;AAEhC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,6BAA6B,CAAC;AAE5C,cAAc,0BAA0B,CAAC;AAEzC,cAAc,kCAAkC,CAAC;AAEjD,cAAc,+BAA+B,CAAC;AAE9C,cAAc,gBAAgB,CAAC;AAE/B,cAAc,gCAAgC,CAAC;AAE/C,cAAc,cAAc,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { Radians } from '@interstellar-tools/types';
2
+ /**
3
+ * Solves **Kepler's Equation** for the **Eccentric Anomaly** ($E$) using the **bisection method**
4
+ * when Newton-Raphson or other iterative solvers fail to converge.
5
+ *
6
+ * ---
7
+ *
8
+ * **Mathematical Explanation:**
9
+ *
10
+ * Kepler's equation for eccentric anomaly ($E$) is:
11
+ * $$
12
+ * M = E - e \sin(E)
13
+ * $$
14
+ * This equation cannot be solved analytically, and numerical methods must be used.
15
+ * When standard iterative solvers like **Newton-Raphson** fail due to poor convergence,
16
+ * the **bisection method** provides a robust alternative by performing a bracketed search.
17
+ *
18
+ * ---
19
+ *
20
+ * **Solving Strategy:**
21
+ * 1. **Initialize Bounds:**
22
+ * - The valid range for $E$ is **$[0, \pi]$** (as $E$ is symmetric around 0).
23
+ * - The midpoint $E_0$ is chosen as:
24
+ * $$
25
+ * E = \frac{E_{low} + E_{high}}{2}
26
+ * $$
27
+ *
28
+ * 2. **Bisection Iteration:**
29
+ * - Compute the function residual:
30
+ * $$
31
+ * F(E) = E - e \sin(E) - M
32
+ * $$
33
+ * - If $F(E)$ is sufficiently small (within tolerance), $E$ is returned as the solution.
34
+ * - Otherwise, the interval is **halved** by updating either:
35
+ * - The lower bound ($E_{low}$) if $F(E) < 0$
36
+ * - The upper bound ($E_{high}$) if $F(E) > 0$
37
+ *
38
+ * 3. **Convergence Check:**
39
+ * - The iteration stops when:
40
+ * $$
41
+ * |E_{n+1} - E_n| < \text{tolerance}
42
+ * $$
43
+ * (default tolerance is **1e-9**).
44
+ *
45
+ * ---
46
+ *
47
+ * **Performance Considerations:**
48
+ * - **Always converges**, unlike Newton-Raphson, which can fail for some initial guesses.
49
+ * - **Time complexity:** $O(\log N)$ due to the **logarithmic convergence** of bisection.
50
+ *
51
+ * ---
52
+ *
53
+ * @param {Radians} M - Mean anomaly ($M$) in **radians**.
54
+ * @param {number} e - Orbital eccentricity ($0 \leq e < 1$).
55
+ * @param {number} maxIter - Maximum number of **iterations** before failure.
56
+ * @param {number} tolerance - Convergence criterion for stopping the iteration.
57
+ * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (best approximation).
58
+ *
59
+ * ---
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * const M = Math.PI / 3; // 60 degrees in radians
64
+ * const e = 0.5; // Orbital eccentricity
65
+ * console.log(solveKeplerBisection(M, e, 50, 1e-9)); // Output: Eccentric anomaly in radians
66
+ * ```
67
+ *
68
+ * ---
69
+ *
70
+ * @see [Kepler's Equation (Wikipedia)](https://en.wikipedia.org/wiki/Kepler%27s_equation)
71
+ * @see [Bisection Method (Wikipedia)](https://en.wikipedia.org/wiki/Bisection_method)
72
+ * @category Solve for Kepler
73
+ */
74
+ export declare const solveKeplerBisection: (M: Radians, e: number, maxIter: number, tolerance: number) => Radians;
75
+ //# sourceMappingURL=solve-kepler-bisection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-kepler-bisection.d.ts","sourceRoot":"","sources":["../src/solve-kepler-bisection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,eAAO,MAAM,oBAAoB,GAC/B,GAAG,OAAO,EACV,GAAG,MAAM,EACT,SAAS,MAAM,EACf,WAAW,MAAM,KAChB,OAwBF,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Solves **Kepler's Equation** for the **Eccentric Anomaly** ($E$) using the **bisection method**
3
+ * when Newton-Raphson or other iterative solvers fail to converge.
4
+ *
5
+ * ---
6
+ *
7
+ * **Mathematical Explanation:**
8
+ *
9
+ * Kepler's equation for eccentric anomaly ($E$) is:
10
+ * $$
11
+ * M = E - e \sin(E)
12
+ * $$
13
+ * This equation cannot be solved analytically, and numerical methods must be used.
14
+ * When standard iterative solvers like **Newton-Raphson** fail due to poor convergence,
15
+ * the **bisection method** provides a robust alternative by performing a bracketed search.
16
+ *
17
+ * ---
18
+ *
19
+ * **Solving Strategy:**
20
+ * 1. **Initialize Bounds:**
21
+ * - The valid range for $E$ is **$[0, \pi]$** (as $E$ is symmetric around 0).
22
+ * - The midpoint $E_0$ is chosen as:
23
+ * $$
24
+ * E = \frac{E_{low} + E_{high}}{2}
25
+ * $$
26
+ *
27
+ * 2. **Bisection Iteration:**
28
+ * - Compute the function residual:
29
+ * $$
30
+ * F(E) = E - e \sin(E) - M
31
+ * $$
32
+ * - If $F(E)$ is sufficiently small (within tolerance), $E$ is returned as the solution.
33
+ * - Otherwise, the interval is **halved** by updating either:
34
+ * - The lower bound ($E_{low}$) if $F(E) < 0$
35
+ * - The upper bound ($E_{high}$) if $F(E) > 0$
36
+ *
37
+ * 3. **Convergence Check:**
38
+ * - The iteration stops when:
39
+ * $$
40
+ * |E_{n+1} - E_n| < \text{tolerance}
41
+ * $$
42
+ * (default tolerance is **1e-9**).
43
+ *
44
+ * ---
45
+ *
46
+ * **Performance Considerations:**
47
+ * - **Always converges**, unlike Newton-Raphson, which can fail for some initial guesses.
48
+ * - **Time complexity:** $O(\log N)$ due to the **logarithmic convergence** of bisection.
49
+ *
50
+ * ---
51
+ *
52
+ * @param {Radians} M - Mean anomaly ($M$) in **radians**.
53
+ * @param {number} e - Orbital eccentricity ($0 \leq e < 1$).
54
+ * @param {number} maxIter - Maximum number of **iterations** before failure.
55
+ * @param {number} tolerance - Convergence criterion for stopping the iteration.
56
+ * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (best approximation).
57
+ *
58
+ * ---
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * const M = Math.PI / 3; // 60 degrees in radians
63
+ * const e = 0.5; // Orbital eccentricity
64
+ * console.log(solveKeplerBisection(M, e, 50, 1e-9)); // Output: Eccentric anomaly in radians
65
+ * ```
66
+ *
67
+ * ---
68
+ *
69
+ * @see [Kepler's Equation (Wikipedia)](https://en.wikipedia.org/wiki/Kepler%27s_equation)
70
+ * @see [Bisection Method (Wikipedia)](https://en.wikipedia.org/wiki/Bisection_method)
71
+ * @category Solve for Kepler
72
+ */
73
+ export const solveKeplerBisection = (M, e, maxIter, tolerance) => {
74
+ let E_low = 0;
75
+ let E_high = Math.PI;
76
+ let E = (E_low + E_high) / 2;
77
+ let iter = 0;
78
+ while (iter < maxIter) {
79
+ const F = E - e * Math.sin(E) - M;
80
+ if (Math.abs(F) < tolerance) {
81
+ return E; // Converged
82
+ }
83
+ if (F > 0) {
84
+ E_high = E;
85
+ }
86
+ else {
87
+ E_low = E;
88
+ }
89
+ E = (E_low + E_high) / 2;
90
+ iter++;
91
+ }
92
+ return E; // Best approximation
93
+ };
94
+ //# sourceMappingURL=solve-kepler-bisection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-kepler-bisection.js","sourceRoot":"","sources":["../src/solve-kepler-bisection.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,CAAU,EACV,CAAS,EACT,OAAe,EACf,SAAiB,EACR,EAAE;IACX,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC;IACrB,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,OAAO,IAAI,GAAG,OAAO,EAAE,CAAC;QACtB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,EAAE,CAAC;YAC5B,OAAO,CAAC,CAAC,CAAC,YAAY;QACxB,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,MAAM,GAAG,CAAC,CAAC;QACb,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;QAED,CAAC,GAAG,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,EAAE,CAAC;IACT,CAAC;IAED,OAAO,CAAC,CAAC,CAAC,qBAAqB;AACjC,CAAC,CAAC"}
@@ -0,0 +1,99 @@
1
+ import { Radians } from '@interstellar-tools/types';
2
+ /**
3
+ * Solves **Kepler's Equation** for the **Eccentric Anomaly** ($E$) in highly eccentric orbits
4
+ * ($e > 0.9$) using an iterative numerical approach.
5
+ *
6
+ * ---
7
+ *
8
+ * **Mathematical Explanation:**
9
+ *
10
+ * Kepler's equation for eccentric anomaly ($E$) is:
11
+ *
12
+ * ![solve-kelper-high-eccentricity-elliptical-orbit](https://raw.githubusercontent.com/phun-ky/interstellar/b607daf8e014128a6dceb3cf8d522676f06bc233/public/solve-kelper-high-eccentricity-elliptical-orbit.svg)
13
+ *
14
+ * $$
15
+ * M = E - e \sin(E) \quad \text{(for elliptical orbits, } 0 < e < 1\text{)}
16
+ * $$
17
+ *
18
+ * ![solve-kepler-high-eccentricity-hyperbolic-orbit](https://raw.githubusercontent.com/phun-ky/interstellar/b607daf8e014128a6dceb3cf8d522676f06bc233/public/solve-kepler-high-eccentricity-hyperbolic-orbit.svg)
19
+ *
20
+ * $$
21
+ * M = e \sinh(E) - E \quad \text{(for hyperbolic orbits, } e > 1\text{)}
22
+ * $$
23
+ *
24
+ * For orbits with **high eccentricity** ($e \approx 1$), standard Newton-Raphson solvers struggle
25
+ * due to extreme changes in orbital velocity near perihelion. Instead, we apply a **fixed-point iteration**
26
+ * method that is more stable for these cases.
27
+ *
28
+ * ---
29
+ *
30
+ * **Solving Strategy:**
31
+ * 1. **Initial Guess:**
32
+ * - The solver starts with $E_0 = M$ and refines using:
33
+ * $$
34
+ * E_0 = M \pm \frac{e \sin(M)}{1 - e \cos(M)}
35
+ * $$
36
+ *
37
+ * 2. **Iterative Refinement:**
38
+ * - The method updates $E$ using:
39
+ * $$
40
+ * \Delta E = \frac{E - e \sin(E) - M}{1 - e \cos(E)}
41
+ * $$
42
+ * for elliptical orbits.
43
+ *
44
+ * $$
45
+ * \Delta E = \frac{e \sinh(E) - E - M}{e \cosh(E) - 1}
46
+ * $$
47
+ * for hyperbolic orbits.
48
+ *
49
+ * - Iteration stops when:
50
+ * $$
51
+ * |E_{n+1} - E_n| < \text{tolerance}
52
+ * $$
53
+ * (default tolerance is **1e-9**).
54
+ *
55
+ * 3. **Angle Wrapping (Elliptical Only):**
56
+ * - The result is wrapped using `wrapAngle()` for consistency.
57
+ *
58
+ * ---
59
+ *
60
+ * **Performance Considerations:**
61
+ * - **Typically converges in fewer than 10 iterations for $e > 0.9$.**
62
+ * - **Time complexity:** $O(1)$ for standard convergence.
63
+ *
64
+ * ---
65
+ *
66
+ * @param {Radians} M - Mean anomaly ($M$) in **radians**.
67
+ * @param {number} e - Orbital eccentricity ($e > 0.9$ for high-eccentricity orbits).
68
+ * @param {number} [maxIter=Math.max(300, Math.floor(5 + 3 * Math.log(1 + Math.abs(M))))] - Maximum number of **iterations** before failure.
69
+ * @param {number} [tolerance=1e-9] - Convergence criterion for stopping the iteration.
70
+ * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (wrapped to $[-\pi, \pi]$ for elliptical orbits).
71
+ *
72
+ * ---
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * import { solveKeplerHighEccentricity } from './solve-kepler';
77
+ *
78
+ * const M = Math.PI / 4; // 45 degrees in radians
79
+ * const e = 0.95; // High orbital eccentricity
80
+ * const result = solveKeplerHighEccentricity(M, e);
81
+ * console.log(result); // Output: Eccentric anomaly in radians
82
+ * ```
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * // Hyperbolic orbit example (e > 1)
87
+ * const M_hyperbolic = 2.0; // Mean anomaly for hyperbolic orbit
88
+ * const e_hyperbolic = 1.2; // Hyperbolic eccentricity
89
+ * console.log(solveKeplerHighEccentricity(M_hyperbolic, e_hyperbolic));
90
+ * ```
91
+ *
92
+ * ---
93
+ *
94
+ * @see [Kepler's Equation (Wikipedia)](https://en.wikipedia.org/wiki/Kepler%27s_equation)
95
+ * @see [Hyperbolic Anomaly (Wikipedia)](https://en.wikipedia.org/wiki/Hyperbolic_trajectory#Hyperbolic_anomaly)
96
+ * @category Solve for Kepler
97
+ */
98
+ export declare const solveKeplerHighEccentricity: (M: Radians, e: number, maxIter?: number, tolerance?: number) => Radians;
99
+ //# sourceMappingURL=solve-kepler-high-eccentricity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-kepler-high-eccentricity.d.ts","sourceRoot":"","sources":["../src/solve-kepler-high-eccentricity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAIpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+FG;AACH,eAAO,MAAM,2BAA2B,GACtC,GAAG,OAAO,EACV,GAAG,MAAM,EACT,gBAAsE,EACtE,kBAAgB,KACf,OAgEF,CAAC"}
@@ -0,0 +1,150 @@
1
+ import { wrapAngle } from './wrap-angle';
2
+ /**
3
+ * Solves **Kepler's Equation** for the **Eccentric Anomaly** ($E$) in highly eccentric orbits
4
+ * ($e > 0.9$) using an iterative numerical approach.
5
+ *
6
+ * ---
7
+ *
8
+ * **Mathematical Explanation:**
9
+ *
10
+ * Kepler's equation for eccentric anomaly ($E$) is:
11
+ *
12
+ * ![solve-kelper-high-eccentricity-elliptical-orbit](https://raw.githubusercontent.com/phun-ky/interstellar/b607daf8e014128a6dceb3cf8d522676f06bc233/public/solve-kelper-high-eccentricity-elliptical-orbit.svg)
13
+ *
14
+ * $$
15
+ * M = E - e \sin(E) \quad \text{(for elliptical orbits, } 0 < e < 1\text{)}
16
+ * $$
17
+ *
18
+ * ![solve-kepler-high-eccentricity-hyperbolic-orbit](https://raw.githubusercontent.com/phun-ky/interstellar/b607daf8e014128a6dceb3cf8d522676f06bc233/public/solve-kepler-high-eccentricity-hyperbolic-orbit.svg)
19
+ *
20
+ * $$
21
+ * M = e \sinh(E) - E \quad \text{(for hyperbolic orbits, } e > 1\text{)}
22
+ * $$
23
+ *
24
+ * For orbits with **high eccentricity** ($e \approx 1$), standard Newton-Raphson solvers struggle
25
+ * due to extreme changes in orbital velocity near perihelion. Instead, we apply a **fixed-point iteration**
26
+ * method that is more stable for these cases.
27
+ *
28
+ * ---
29
+ *
30
+ * **Solving Strategy:**
31
+ * 1. **Initial Guess:**
32
+ * - The solver starts with $E_0 = M$ and refines using:
33
+ * $$
34
+ * E_0 = M \pm \frac{e \sin(M)}{1 - e \cos(M)}
35
+ * $$
36
+ *
37
+ * 2. **Iterative Refinement:**
38
+ * - The method updates $E$ using:
39
+ * $$
40
+ * \Delta E = \frac{E - e \sin(E) - M}{1 - e \cos(E)}
41
+ * $$
42
+ * for elliptical orbits.
43
+ *
44
+ * $$
45
+ * \Delta E = \frac{e \sinh(E) - E - M}{e \cosh(E) - 1}
46
+ * $$
47
+ * for hyperbolic orbits.
48
+ *
49
+ * - Iteration stops when:
50
+ * $$
51
+ * |E_{n+1} - E_n| < \text{tolerance}
52
+ * $$
53
+ * (default tolerance is **1e-9**).
54
+ *
55
+ * 3. **Angle Wrapping (Elliptical Only):**
56
+ * - The result is wrapped using `wrapAngle()` for consistency.
57
+ *
58
+ * ---
59
+ *
60
+ * **Performance Considerations:**
61
+ * - **Typically converges in fewer than 10 iterations for $e > 0.9$.**
62
+ * - **Time complexity:** $O(1)$ for standard convergence.
63
+ *
64
+ * ---
65
+ *
66
+ * @param {Radians} M - Mean anomaly ($M$) in **radians**.
67
+ * @param {number} e - Orbital eccentricity ($e > 0.9$ for high-eccentricity orbits).
68
+ * @param {number} [maxIter=Math.max(300, Math.floor(5 + 3 * Math.log(1 + Math.abs(M))))] - Maximum number of **iterations** before failure.
69
+ * @param {number} [tolerance=1e-9] - Convergence criterion for stopping the iteration.
70
+ * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (wrapped to $[-\pi, \pi]$ for elliptical orbits).
71
+ *
72
+ * ---
73
+ *
74
+ * @example
75
+ * ```ts
76
+ * import { solveKeplerHighEccentricity } from './solve-kepler';
77
+ *
78
+ * const M = Math.PI / 4; // 45 degrees in radians
79
+ * const e = 0.95; // High orbital eccentricity
80
+ * const result = solveKeplerHighEccentricity(M, e);
81
+ * console.log(result); // Output: Eccentric anomaly in radians
82
+ * ```
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * // Hyperbolic orbit example (e > 1)
87
+ * const M_hyperbolic = 2.0; // Mean anomaly for hyperbolic orbit
88
+ * const e_hyperbolic = 1.2; // Hyperbolic eccentricity
89
+ * console.log(solveKeplerHighEccentricity(M_hyperbolic, e_hyperbolic));
90
+ * ```
91
+ *
92
+ * ---
93
+ *
94
+ * @see [Kepler's Equation (Wikipedia)](https://en.wikipedia.org/wiki/Kepler%27s_equation)
95
+ * @see [Hyperbolic Anomaly (Wikipedia)](https://en.wikipedia.org/wiki/Hyperbolic_trajectory#Hyperbolic_anomaly)
96
+ * @category Solve for Kepler
97
+ */
98
+ export const solveKeplerHighEccentricity = (M, e, maxIter = Math.max(300, Math.floor(5 + 3 * Math.log(1 + Math.abs(M)))), tolerance = 1e-9) => {
99
+ if (e < 0) {
100
+ throw new RangeError(`Invalid eccentricity: ${e}. Must be e ≥ 0.`);
101
+ }
102
+ let E;
103
+ // Use a more accurate initial guess for highly eccentric orbits
104
+ if (M < 0) {
105
+ E = M - (e * Math.sin(M)) / (1 - e * Math.cos(M));
106
+ }
107
+ else {
108
+ E = M + (e * Math.sin(M)) / (1 - e * Math.cos(M));
109
+ }
110
+ let delta = 1;
111
+ let iter = 0;
112
+ let lastValidE = E;
113
+ while (Math.abs(delta) > tolerance && iter < maxIter) {
114
+ let fE;
115
+ let dfE;
116
+ // **Elliptical Orbit (0.9 < e < 1)**
117
+ if (e < 1) {
118
+ fE = E - e * Math.sin(E) - M;
119
+ dfE = 1 - e * Math.cos(E);
120
+ }
121
+ // **Hyperbolic Orbit (e > 1)**
122
+ else {
123
+ const sinhE = Math.sinh(E);
124
+ const coshE = Math.cosh(E);
125
+ fE = e * sinhE - E - M;
126
+ dfE = e * coshE - 1;
127
+ }
128
+ // **Prevent divide-by-zero issues**
129
+ dfE = Math.max(Math.abs(dfE), 1e-6) * Math.sign(dfE);
130
+ delta = fE / dfE;
131
+ // **Clamp delta to prevent large jumps**
132
+ delta = Math.sign(delta) * Math.min(Math.abs(delta), 0.5);
133
+ E -= delta;
134
+ iter++;
135
+ if (!isNaN(E) && isFinite(E)) {
136
+ lastValidE = E;
137
+ }
138
+ // **Clamp extreme values to prevent divergence**
139
+ if (Math.abs(E) > 100) {
140
+ E = 100 * Math.sign(E);
141
+ break;
142
+ }
143
+ }
144
+ // **Wrap angles to the range [-π, π] for elliptical orbits**
145
+ if (e < 1) {
146
+ lastValidE = wrapAngle(lastValidE);
147
+ }
148
+ return lastValidE;
149
+ };
150
+ //# sourceMappingURL=solve-kepler-high-eccentricity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-kepler-high-eccentricity.js","sourceRoot":"","sources":["../src/solve-kepler-high-eccentricity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ import { Radians } from '@interstellar-tools/types';
2
+ /**
3
+ * Solves **Kepler's Equation** for the **Eccentric Anomaly** ($E$) using the **Newton-Raphson method**
4
+ * with Householder acceleration for fast convergence.
5
+ *
6
+ * ---
7
+ *
8
+ * **Mathematical Explanation:**
9
+ *
10
+ * Kepler's equation relates the **mean anomaly** ($M$), the **eccentric anomaly** ($E$),
11
+ * and the **orbital eccentricity** ($e$) as:
12
+ * $$
13
+ * M = E - e \sin(E)
14
+ * $$
15
+ * Since this equation **cannot be solved algebraically**, iterative numerical methods are required.
16
+ *
17
+ * ---
18
+ *
19
+ * **Solving Strategy:**
20
+ * 1. **Handle Special Cases:**
21
+ * - If the orbit is **circular** ($e = 0$), then $E = M$ directly.
22
+ * - If the orbit is **nearly parabolic** ($e \geq 0.97$), a special approximation is used.
23
+ * - If **eccentricity is out of range** ($e < 0$ or $e \geq 1$), a `RangeError` is thrown.
24
+ *
25
+ * 2. **Initial Approximation:**
26
+ * - **For small eccentricities ($e < 0.8$):** $E_0 = M$.
27
+ * - **For moderate eccentricities ($0.8 \leq e < 0.97$):** $E_0 = M + e \sin(M) (1 + e \cos(M))$.
28
+ * - **For nearly parabolic orbits ($e \geq 0.97$):** $E_0 = \frac{6M}{e}$.
29
+ *
30
+ * 3. **Newton-Raphson Iteration with Householder Acceleration:**
31
+ * - The **Newton-Raphson method** iterates using:
32
+ * $$
33
+ * E_{n+1} = E_n - \frac{f(E_n)}{f'(E_n)}
34
+ * $$
35
+ * where:
36
+ * - $f(E) = E - e \sin(E) - M$
37
+ * - $f'(E) = 1 - e \cos(E)$
38
+ *
39
+ * - **Householder acceleration** refines the correction:
40
+ * $$
41
+ * \Delta E = \frac{f(E)}{f'(E)} \left( 1 - \frac{1}{2} \frac{f''(E)}{f'(E)} \Delta E \right)^{-1}
42
+ * $$
43
+ *
44
+ * 4. **Convergence Check:**
45
+ * - The iteration stops when:
46
+ * $$
47
+ * |E_{n+1} - E_n| < \text{tolerance}
48
+ * $$
49
+ * (default tolerance is **1e-9**).
50
+ *
51
+ * 5. **Failure Handling:**
52
+ * - If the method **does not converge**, `NaN` is returned, signaling that a fallback method should be used.
53
+ *
54
+ * ---
55
+ *
56
+ * **Performance Considerations:**
57
+ * - **Typically converges in 4-5 iterations for most eccentricities.**
58
+ * - **Time complexity:** $O(1)$ for Newton-Raphson.
59
+ *
60
+ * ---
61
+ *
62
+ * @param {Radians} M - Mean anomaly ($M$) in **radians**.
63
+ * @param {number} e - Orbital eccentricity ($0 \leq e < 1$).
64
+ * @param {number} maxIter - Maximum number of **iterations** before failure.
65
+ * @param {number} tolerance - Convergence criterion for stopping the iteration.
66
+ * @returns {Radians} The **eccentric anomaly** ($E$) in **radians** (or `NaN` if the method fails).
67
+ *
68
+ * @throws {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError | RangeError} If the **eccentricity ($e$) is invalid** ($e < 0$ or $e \geq 1$).
69
+ *
70
+ * ---
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * const M = Math.PI / 4; // 45 degrees in radians
75
+ * const e = 0.1; // Orbital eccentricity
76
+ * console.log(solveKeplerNewtonRaphson(M, e, 50, 1e-9)); // Output: Eccentric anomaly in radians
77
+ * ```
78
+ *
79
+ * ---
80
+ *
81
+ * @see [Kepler's Equation (Wikipedia)](https://en.wikipedia.org/wiki/Kepler%27s_equation)
82
+ * @see [Newton-Raphson Method (Wikipedia)](https://en.wikipedia.org/wiki/Newton%27s_method)
83
+ * @see [Eccentric Anomaly (Wikipedia)](https://en.wikipedia.org/wiki/Mean_anomaly#Eccentric_anomaly)
84
+ * @category Solve for Kepler
85
+ */
86
+ export declare const solveKeplerNewtonRaphson: (M: Radians, e: number, maxIter: number, tolerance: number) => Radians;
87
+ //# sourceMappingURL=solve-kepler-newton-raphson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solve-kepler-newton-raphson.d.ts","sourceRoot":"","sources":["../src/solve-kepler-newton-raphson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmFG;AACH,eAAO,MAAM,wBAAwB,GACnC,GAAG,OAAO,EACV,GAAG,MAAM,EACT,SAAS,MAAM,EACf,WAAW,MAAM,KAChB,OAwCF,CAAC"}