1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.orbits;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.util.FastMath;
21 import org.hipparchus.util.SinCos;
22 import org.orekit.errors.OrekitIllegalArgumentException;
23 import org.orekit.errors.OrekitMessages;
24 import org.orekit.utils.PVCoordinates;
25
26
27
28
29
30
31
32 public class EquinoctialParametersConverter {
33
34
35 private final double mu;
36
37
38
39
40
41 public EquinoctialParametersConverter(final double mu) {
42 this.mu = mu;
43 }
44
45
46
47
48
49
50
51 public EquinoctialParameters toParameters(final PVCoordinates cartesian, final PositionAngleType positionAngleType) {
52
53 final Vector3D pvP = cartesian.getPosition();
54 final Vector3D pvV = cartesian.getVelocity();
55 final double r2 = pvP.getNorm2Sq();
56 final double r = FastMath.sqrt(r2);
57 final double V2 = pvV.getNorm2Sq();
58 final double rV2OnMu = r * V2 / mu;
59
60
61 final double a = r / (2 - rV2OnMu);
62
63 if (a <= 0.) {
64 throw new OrekitIllegalArgumentException(OrekitMessages.HYPERBOLIC_ORBIT_NOT_HANDLED_AS,
65 getClass().getName());
66 }
67
68
69 final Vector3D w = cartesian.getMomentum().normalize();
70 final double d = 1.0 / (1 + w.getZ());
71 final double hx = -d * w.getY();
72 final double hy = d * w.getX();
73
74
75 final double cLv = (pvP.getX() - d * pvP.getZ() * w.getX()) / r;
76 final double sLv = (pvP.getY() - d * pvP.getZ() * w.getY()) / r;
77 final double lV = FastMath.atan2(sLv, cLv);
78
79
80 final double eSE = Vector3D.dotProduct(pvP, pvV) / FastMath.sqrt(mu * a);
81 final double eCE = rV2OnMu - 1;
82 final double e2 = eCE * eCE + eSE * eSE;
83 final double f = eCE - e2;
84 final double g = FastMath.sqrt(1 - e2) * eSE;
85 final double ex = a * (f * cLv + g * sLv) / r;
86 final double ey = a * (f * sLv - g * cLv) / r;
87
88 final EquinoctialParameters elements = new EquinoctialParameters(a, ex, ey, hx, hy, lV, PositionAngleType.TRUE);
89 return positionAngleType == PositionAngleType.TRUE ? elements : elements.withPositionAngleType(positionAngleType);
90 }
91
92
93
94
95
96
97 public PVCoordinates toCartesian(final EquinoctialParameters elements) {
98
99 final double a = elements.a();
100 final double ex = elements.ex();
101 final double ey = elements.ey();
102 final double hx = elements.hx();
103 final double hy = elements.hy();
104 final double lE = elements.positionAngleType() == PositionAngleType.ECCENTRIC ? elements.longitudeArgument() :
105 elements.withPositionAngleType(PositionAngleType.ECCENTRIC).longitudeArgument();
106
107
108 final double hx2 = hx * hx;
109 final double hy2 = hy * hy;
110 final double factH = 1. / (1 + hx2 + hy2);
111
112
113 final double ux = (1 + hx2 - hy2) * factH;
114 final double uy = 2 * hx * hy * factH;
115 final double uz = -2 * hy * factH;
116
117 final double vx = uy;
118 final double vy = (1 - hx2 + hy2) * factH;
119 final double vz = 2 * hx * factH;
120
121
122 final double exey = ex * ey;
123 final double ex2 = ex * ex;
124 final double ey2 = ey * ey;
125 final double e2 = ex2 + ey2;
126 final double eta = 1 + FastMath.sqrt(1 - e2);
127 final double beta = 1. / eta;
128
129
130 final SinCos scLe = FastMath.sinCos(lE);
131 final double cLe = scLe.cos();
132 final double sLe = scLe.sin();
133 final double exCeyS = ex * cLe + ey * sLe;
134
135
136 final double x = a * ((1 - beta * ey2) * cLe + beta * exey * sLe - ex);
137 final double y = a * ((1 - beta * ex2) * sLe + beta * exey * cLe - ey);
138
139 final double factor = FastMath.sqrt(mu / a) / (1 - exCeyS);
140 final double xdot = factor * (-sLe + beta * ey * exCeyS);
141 final double ydot = factor * ( cLe - beta * ex * exCeyS);
142
143 final Vector3D position =
144 new Vector3D(x * ux + y * vx, x * uy + y * vy, x * uz + y * vz);
145 final Vector3D velocity =
146 new Vector3D(xdot * ux + ydot * vx, xdot * uy + ydot * vy, xdot * uz + ydot * vz);
147 return new PVCoordinates(position, velocity);
148 }
149 }