26 real s = (_a - _c) * (_a + _c);
32 _kp2 = 0; _k2 = 1 - _kp2;
34 _kp2 = (_a - _b) * (_a + _b) / s;
35 _k2 = (_b - _c) * (_b + _c) / s;
37 _k = sqrt(_k2); _kp = sqrt(_kp2);
38 if (! (isfinite(_a) && isfinite(_b) && isfinite(_c) &&
39 _a >= _b && _b >= _c && _c >= 0 && _b > 0) )
43 _biaxial = _oblate || _prolate;
52 real ksum = _k2 + _kp2;
57 _a = _b * sqrt(1 + _e2 * _kp2);
58 _c = _b * sqrt(1 - _e2 * _k2);
59 if (! (isfinite(_a) && isfinite(_b) && isfinite(_c) &&
60 _a >= _b && _b >= _c && _c >= 0 && _b > 0) )
64 _biaxial = _oblate || _prolate;
68 vec3 rn{R[0] / _a, R[1] / _b, R[2] / _c};
70 R = {R[0] / ra, R[1] / ra, R[2] / ra};
77 uv = up[0] * V[0] + up[1] * V[1] + up[2] * V[2],
79 V = {V[0] - f * up[0], V[1] - f * up[1], V[2] - f * up[2]};
83 void Ellipsoid3::cart2toellipint(vec3 R,
Angle& bet,
Angle& omg, vec3 axes)
85 real a = axes[0],
b = axes[1],
c = axes[2];
86 real xi = R[0]/
a, eta = R[1]/
b, zeta = R[2]/
c,
90 if (fabs(R[0]) ==
a * _kp2 && R[1] == 0 && fabs(R[2]) ==
c * _k2)
92 real h = hypot(g, 2 * _k * _kp * eta),
98 so = copysign(sqrt( (h - g)/2 ) / _kp, eta);
101 cb = sqrt( (h + g)/2 ) / _k;
104 real tz = hypot(_k, _kp * so),
105 tx = hypot(_k * cb, _kp);
106 sb = tz == 0 ? -1 : zeta / tz;
107 co = tx == 0 ? 1 : xi / tx;
108 bet =
ang(sb, cb, 0,
true);
109 omg =
ang(so, co, 0,
true);
113 cart2toellipint(R, bet, omg, {_a, _b, _c});
118 real tz = hypot(_k, _kp * omg.
s()), tx = hypot(_k * bet.
c(), _kp);
120 if (tx == 0 || tz == 0 || !(bet.
c() == 0 && omg.
s() == 0)) {
124 vec3{-omg.
c() * bet.
s(), -omg.
s() * bet.
s(), tx * bet.
s()} :
126 vec3{tz, -bet.
s(), bet.
c()} :
127 vec3{-_a * _k2 * bet.
c() * bet.
s() * omg.
c() / tx,
128 -_b * bet.
s() * omg.
s(),
131 vec3{-omg.
s(), omg.
c(), tx} :
133 vec3{tz * omg.
c(), bet.
c() * omg.
c(), bet.
s() * omg.
c()} :
134 vec3{-_a * tx * omg.
s(),
135 _b * bet.
c() * omg.
c(),
136 _c * _kp2 * bet.
s() * omg.
c() * omg.
s() / tz});
137 normvec(N); normvec(E);
138 alp =
ang(V[0] * E[0] + V[1] * E[1] + V[2] * E[2],
139 V[0] * N[0] + V[1] * N[1] + V[2] * N[2], 0,
true);
142 real w = bet.
s() * omg.
c(),
143 upx = omg.
c() * tx/_a, upz = bet.
s() * tz/_c;
146 real s2a = -V[1] * w, c2a = (upz*V[0] - upx*V[2]) * w;
161 real flip = -bet.
s();
163 alp =
ang(flip * s2a, flip * (1 + c2a));
165 alp =
ang(flip * copysign(1 - c2a, s2a), flip * fabs(s2a));
177 real tx = hypot(_k * bet.
c(), _kp), tz = hypot(_k, _kp * omg.
s());
178 R = { _a * omg.
c() * tx,
179 _b * bet.
c() * omg.
s(),
186 real tx = hypot(_k * bet.
c(), _kp), tz = hypot(_k, _kp * omg.
s());
187 if (bet.
c() == 0 && omg.
s() == 0 && !(_k == 0 || _kp == 0)) {
189 real sa2 = 2 * alp.
s() * alp.
c(),
190 ca2 = (alp.
c() - alp.
s()) * (alp.
c() + alp.
s());
193 V = {_a*_k/_b * omg.
c() * ca2,
194 -omg.
c() * bet.
s() * sa2,
195 -_c*_kp/_b * bet.
s() * ca2};
200 real scb = signbit(bet.
c()) ? -1 : 1;
201 N = {-omg.
c() * bet.
s() * scb, -omg.
s() * bet.
s(), 0};
202 E = {-omg.
s() , omg.
c() * scb , 0};
203 }
else if (tz == 0) {
205 real sso = signbit(omg.
s()) ? -1 : 1;
206 N = {0, -bet.
s() * sso , bet.
c() };
207 E = {0, bet.
c() * omg.
c(), bet.
s() * omg.
c() * sso};
210 N = { -_a * _k2 * bet.
c() * bet.
s() * omg.
c() / tx,
211 -_b * bet.
s() * omg.
s(),
213 E = { -_a * tx * omg.
s(),
214 _b * bet.
c() * omg.
c(),
215 _c * _kp2 * bet.
s() * omg.
c() * omg.
s() / tz};
219 V = {alp.
c() * N[0] + alp.
s() * E[0],
220 alp.
c() * N[1] + alp.
s() * E[1],
221 alp.
c() * N[2] + alp.
s() * E[2]};
Header for GeographicLib::Triaxial::Ellipsoid3 class.
GeographicLib::Math::real real
static T Triaxial_Earth_b()
static T Triaxial_Earth_a()
static T Triaxial_Earth_c()
Exception handling for GeographicLib.
static void norm(T &x, T &y)
static T hypot3(T x, T y, T z)
void cart2toellip(vec3 R, Angle &bet, Angle &omg) const
static const Ellipsoid3 & Earth()
void elliptocart2(Angle bet, Angle omg, vec3 &R) const
std::array< Math::real, 3 > vec3
Namespace for operations on triaxial ellipsoids.
Namespace for GeographicLib.
AngleT< Math::real > Angle