GeographicLib
2.6
Toggle main menu visibility
Loading...
Searching...
No Matches
Ellipsoid3.hpp
Go to the documentation of this file.
1
/**
2
* \file Ellipsoid3.hpp
3
* \brief Header for GeographicLib::Triaxial::Ellipsoid3 class
4
*
5
* Copyright (c) Charles Karney (2024-2025) <karney@alum.mit.edu> and licensed
6
* under the MIT/X11 License. For more information, see
7
* https://geographiclib.sourceforge.io/
8
**********************************************************************/
9
10
#if !defined(GEOGRAPHICLIB_ELLIPSOID3_HPP)
11
#define GEOGRAPHICLIB_ELLIPSOID3_HPP 1
12
13
#include <iostream>
14
#include <array>
15
#include <
GeographicLib/Constants.hpp
>
16
#include <
GeographicLib/Angle.hpp
>
17
18
namespace
GeographicLib
{
19
/**
20
* \brief Namespace for operations on triaxial ellipsoids
21
*
22
* The algorithms on triaxial ellipsoids are, for the most part, distinct
23
* from those in the rest of %GeographicLib, which deal with biaxial
24
* ellipsoids; it is therefore convenient to put them in a distinct
25
* namespace. In order to minimize the change of name clashes, the classes
26
* in the namespace include "3" in their names. The header files are
27
* included via GeographicLib/Triaxial/Class.hpp.
28
**********************************************************************/
29
namespace
Triaxial
{
30
/**
31
* \brief A triaxial ellipsoid.
32
*
33
* The class holds the basic information about a triaxial ellipoid
34
* given by
35
* \f[ S(\mathbf R) =
36
* \frac{X^2}{a^2} + \frac{Y^2}{b^2} + \frac{Z^2}{c^2} - 1 = 0, \f]
37
* where the semiaxes satisfy \f$ a \ge b \ge c > 0\f$.
38
* It is useful to characterize the shape of the ellipsoid by
39
* \f[
40
* \begin{align}
41
* e &= \frac{\sqrt{a^2-c^2}}b,\\
42
* k &= \frac{\sqrt{b^2-c^2}}{\sqrt{a^2-c^2}},\\
43
* k' &= \frac{\sqrt{a^2-b^2}}{\sqrt{a^2-c^2}};
44
* \end{align}
45
* \f]
46
* note that \f$k^2 + k'^2 = 1\f$. The spherical limit \f$ e\rightarrow 0
47
* \f$ is nonuniform since the values of \f$k\f$ and \f$k'\f$ depend on how
48
* the limit is taken. In this cases, it's convenient to specify the
49
* ellipsoid in terms of these parameters. The semiaxes are related to these
50
* parameters by
51
* \f[
52
* [a,b,c] = b \bigl[ \sqrt{1 + e^2k'^2}, 1, \sqrt{1 - e^2k^2} \bigr].
53
* \f]
54
*
55
* Positions on the ellipsoid are given in term so the ellipsoidal latitude
56
* \f$\beta\f$ and the ellipsoidal longitude \f$\omega\f$ which are defined
57
* by
58
* \f[
59
* \mathbf R = \begin{bmatrix}
60
* a \cos\omega \sqrt{k^2\cos^2\beta + k'^2} \\
61
* b \cos\beta \sin\omega \\
62
* c \sin\beta \sqrt{k^2 + k'^2\sin^2\omega}
63
* \end{bmatrix}.
64
* \f]
65
* Headings are given by the direction \f$ \alpha \f$ measured clockwise from
66
* a line of constant \f$ \omega \f$. Conversions between Cartesian and
67
* elliopsoidal coordinates is provided by cart2toellip() and elliptocart2().
68
*
69
* The ellipsoid coordinates "cover" the ellipsoid twice; the replacement
70
* \f[
71
* \begin{align}
72
* \omega & \rightarrow -\omega,\\
73
* \beta & \rightarrow \pi-\beta,\\
74
* \alpha & \rightarrow \pi+\alpha,
75
* \end{align}
76
* \f]
77
* leaves the position and direction unchanged; see AngNorm(),
78
*
79
* Example of use:
80
* \include example-Ellipsoid3.cpp
81
**********************************************************************/
82
class
GEOGRAPHICLIB_EXPORT
Ellipsoid3
{
83
public
:
84
/**
85
* A type to hold three-dimentional positions and directions in Cartesian
86
* coordinates.
87
**********************************************************************/
88
using
vec3
= std::array<Math::real, 3>;
89
private
:
90
/// \cond SKIP
91
friend
class
Cartesian3
;
// For access to cart2toellipint normvec
92
friend
class
Geodesic3
;
// For Flip
93
/// \endcond
94
using
real =
Math::real
;
95
using
ang =
Angle
;
96
static
void
normvec(
vec3
& R) {
97
real h =
Math::hypot3
(R[0], R[1], R[2]);
98
// No checking for h = 0. Result will be NaNs
99
R[0] /= h; R[1] /= h; R[2] /= h;
100
}
101
static
void
Flip(
ang
& bet,
ang
& omg,
ang
& alp) {
102
bet.
reflect
(
false
,
true
);
103
omg.
reflect
(
true
);
104
alp.
reflect
(
true
,
true
);
105
}
106
real
_a, _b, _c;
// semi-axes
107
real
_e2, _k2, _kp2, _k, _kp;
108
bool
_oblate, _prolate, _biaxial;
109
void
cart2toellipint(vec3 R,
ang
& bet,
ang
& omg, vec3 axes)
const
;
110
/**
111
* @return \e k the oblateness parameter.
112
**********************************************************************/
113
real
k()
const
{
return
_k; }
114
/**
115
* @return \e kp the prolateness parameter.
116
**********************************************************************/
117
real
kp()
const
{
return
_kp; }
118
/**
119
* @return whether the ellipsoid is oblate.
120
*
121
* This is determined by the condition kp2() == 0.
122
**********************************************************************/
123
bool
oblate()
const
{
return
_oblate; }
124
/**
125
* @return whether the ellipsoid is prolate.
126
*
127
* This is determined by the condition k2() == 0.
128
**********************************************************************/
129
bool
prolate()
const
{
return
_prolate; }
130
/**
131
* @return whether the ellipsoid is oblate or prolate.
132
**********************************************************************/
133
bool
biaxial()
const
{
return
_biaxial; }
134
public
:
135
/**
136
* The default constructor for a unit sphere in the oblate limit.
137
**********************************************************************/
138
Ellipsoid3();
139
/**
140
* An ellipsoid specified by its semiaxes.
141
*
142
* @param[in] a the major semiaxis.
143
* @param[in] b the median semiaxis.
144
* @param[in] c the minor semiaxis.
145
* @exception GeographicErr if the required ordering is semiaxes is
146
* violated.
147
*
148
* The semiaxes must satisfy \e a ≥ \e b ≥ \e c > 0.
149
* If \e a = \e c (a sphere), then the oblate limit is taken.
150
**********************************************************************/
151
Ellipsoid3(
real
a,
real
b,
real
c);
152
/**
153
* An ellipsoid specified by its median semiaxis and shape.
154
*
155
* @param[in] b the middle semi-axis.
156
* @param[in] e2 the eccentricity squared \f$e^2 = (a^2 - c^2)/b^2\f$.
157
* @param[in] k2 the oblateness parameter squared \f$k^2 = (b^2 - c^2) /
158
* (a^2 - c^2)\f$.
159
* @param[in] kp2 the prolateness parameter squared \f$k'^2= (a^2 - b^2) /
160
* (a^2 - c^2)\f$.
161
* @exception GeographicErr if the required ordering is semiaxes is
162
* violated.
163
*
164
* This form of the constructor is important when the eccentricity is small
165
* and giving \e e2 allows for more precision.
166
*
167
* In the case of a sphere with \e e2 = 0, this constructor distinguishes
168
* between and "oblate sphere" (\e k2 = 1), a "prolate sphere" (\e k2 = 0),
169
* and a "triaxial sphere" (\e k2 &isin (0,1)). These distinctions matter
170
* when ellipsoidal coordinates are used.
171
*
172
* \note The constructor normalizes \e k2 and \e kp2 so that \e k2 + \e kp2
173
* = 1.
174
**********************************************************************/
175
Ellipsoid3(
real
b,
real
e2,
real
k2,
real
kp2);
176
/** \name Inspector functions
177
**********************************************************************/
178
///@{
179
/**
180
* @return \e a the major semiaxeis.
181
**********************************************************************/
182
real
a
()
const
{
return
_a; }
183
/**
184
* @return \e b the median semiaxeis.
185
**********************************************************************/
186
real
b
()
const
{
return
_b; }
187
/**
188
* @return \e c the minor semiaxeis.
189
**********************************************************************/
190
real
c
()
const
{
return
_c; }
191
/**
192
* @return \e e2 the eccentricity squared.
193
**********************************************************************/
194
real
e2
()
const
{
return
_e2; }
195
/**
196
* @return \e k2 the oblateness parameter squared.
197
**********************************************************************/
198
real
k2
()
const
{
return
_k2; }
199
/**
200
* @return \e kp2 the prolateness parameter squared.
201
**********************************************************************/
202
real
kp2
()
const
{
return
_kp2; }
203
///@}
204
/** \name Normalizing functions
205
**********************************************************************/
206
///@{
207
/**
208
* Scale a position to ensure it lies on the ellipsoid
209
*
210
* @param[inout] R the position.
211
*
212
* The components of \e R are scaled so that it lies on the ellipsoid. The
213
* resulting position is not in general the closest point on the ellipsoid.
214
* Use Cartesian3::carttocart2() for that.
215
**********************************************************************/
216
void
Norm(vec3& R)
const
;
217
/**
218
* Scale a position and direction to the ellipsoid
219
*
220
* @param[inout] R the position.
221
* @param[inout] V the position.
222
*
223
* The components of \e R are scaled so that it lies on the ellipsoid. Then
224
* \e V is projected to be tangent to the surface and is normalized to a
225
* unit vector.
226
**********************************************************************/
227
void
Norm(vec3& R, vec3& V)
const
;
228
/**
229
* Set the sheet for coordinates.
230
*
231
* @param[inout] bet the ellipsoidal latitude.
232
* @param[inout] omg the ellipsoidal longitude.
233
* @param[inout] alp the heading.
234
* @param[in] alt if true switch to the alternate sheet.
235
* @return whether the coordinates were changed.
236
*
237
* If alt = false (the default), the conventional sheet is used switching
238
* the values of \e bet, \e omg, and \e alp, so that \e bet ∈
239
* [-π/2, &pi/2].
240
*
241
* If alt = true, the alternate sheet is used switching the values of \e
242
* bet, \e omg, and \e alp, so that \e omg ∈ [0, π].
243
*
244
* This routine does not change \e n (the number of turns) for the
245
* coordinates.
246
**********************************************************************/
247
static
bool
AngNorm
(
Angle
& bet,
Angle
& omg,
Angle
& alp,
bool
alt =
false
) {
248
using
std::signbit;
249
// If !alt, put bet in [-pi/2,pi/2]
250
// If alt, put omg in [0, pi]
251
bool
flip = alt ? signbit(omg.
s
()) : signbit(bet.
c
());
252
if
(flip)
253
Flip(bet, omg, alp);
254
return
flip;
255
}
256
/**
257
* Set the sheet for coordinates.
258
*
259
* @param[inout] bet the ellipsoidal latitude.
260
* @param[inout] omg the ellipsoidal longitude.
261
* @param[in] alt if true switch to the alternate sheet.
262
* @return whether the coordinated were changed.
263
*
264
* This acts precisely the same and AngNorm(Angle&, Angle&, Angle&, bool)
265
* except that \e alp is omitted.
266
**********************************************************************/
267
static
bool
AngNorm
(
Angle
& bet,
Angle
& omg,
bool
alt =
false
) {
268
using
std::signbit;
269
// If !alt, put bet in [-pi/2,pi/2]
270
// If alt, put omg in [0, pi]
271
bool
flip = alt ? signbit(omg.
s
()) : signbit(bet.
c
());
272
if
(flip) {
273
ang alp;
274
Flip(bet, omg, alp);
275
}
276
return
flip;
277
}
278
///@}
279
/** \name Coordinate conversions.
280
**********************************************************************/
281
///@{
282
/**
283
* Convert a Cartesian position to ellipsoidal coordinates.
284
*
285
* @param[in] R the Cartesian position.
286
* @param[out] bet the ellipsoidal latitude.
287
* @param[out] omg the ellipsoidal longitude.
288
*
289
* \note \e R must lie on the surface of the ellipsoid. The "2" in "cart2"
290
* is used to emphasize this.
291
**********************************************************************/
292
void
cart2toellip(vec3 R,
Angle
& bet,
Angle
& omg)
const
;
293
/**
294
* Convert a Cartesian position and direction to ellipsoidal coordinates.
295
*
296
* @param[in] R the Cartesian position.
297
* @param[in] V the Cartesian direction.
298
* @param[out] bet the ellipsoidal latitude.
299
* @param[out] omg the ellipsoidal longitude.
300
* @param[out] alp the azimuth.
301
*
302
* \note \e R must lie on the surface of the ellipsoid and \e V must be
303
* tangent to the surface at that point. The "2" in "cart2" is used to
304
* emphasize this.
305
**********************************************************************/
306
void
cart2toellip(vec3 R, vec3 V,
307
Angle
& bet,
Angle
& omg,
Angle
& alp)
const
;
308
/**
309
* Convert an ellipsoid position and Cartesian direction to a heading.
310
*
311
* @param[in] bet the ellipsoidal latitude.
312
* @param[in] omg the ellipsoidal longitude.
313
* @param[in] V the Cartesian direction.
314
* @param[out] alp the azimuth.
315
*
316
* This is a variant of cart2toellip(vec3, vec3, Angle&, Angle&, Angle&)
317
* where \e bet and \e omg are used to ensure that the correct sheet is
318
* used in determining \e alp.
319
*
320
* \note \e V must be tangent to the surface of the ellipsoid. The "2" in
321
* "cart2" is used to emphasize this.
322
**********************************************************************/
323
void
cart2toellip(
Angle
bet,
Angle
omg,
324
vec3 V,
Angle
& alp)
const
;
325
/**
326
* Convert ellipsoidal coordinates to a Cartesian position.
327
*
328
* @param[in] bet the ellipsoidal latitude.
329
* @param[in] omg the ellipsoidal longitude.
330
* @param[out] R the Cartesian position.
331
**********************************************************************/
332
void
elliptocart2(
Angle
bet,
Angle
omg, vec3& R)
const
;
333
/**
334
* Convert coordinates and heading to a Cartesian position and direction.
335
*
336
* @param[in] bet the ellipsoidal latitude.
337
* @param[in] omg the ellipsoidal longitude.
338
* @param[in] alp the azimuth.
339
* @param[out] R the Cartesian position.
340
* @param[out] V the Cartesian direction.
341
**********************************************************************/
342
void
elliptocart2(
Angle
bet,
Angle
omg,
Angle
alp,
343
vec3& R, vec3& V)
const
;
344
///@}
345
/**
346
* A global instantiation of Ellipsoid3 with the parameters for the
347
* Earth.
348
**********************************************************************/
349
static
const
Ellipsoid3
& Earth();
350
351
};
352
353
}
// namespace Triaxial
354
}
// namespace GeographicLib
355
356
#endif
// GEOGRAPHICLIB_TRIAXIAL_HPP
Angle.hpp
Header for the GeographicLib::AngleT class.
Constants.hpp
Header for GeographicLib::Constants class.
GEOGRAPHICLIB_EXPORT
#define GEOGRAPHICLIB_EXPORT
Definition
Constants.hpp:59
ang
GeographicLib::Angle ang
Definition
Geod3Solve.cpp:26
real
GeographicLib::Math::real real
Definition
Geod3Solve.cpp:25
GeographicLib::AngleT::c
T c() const
Definition
Angle.hpp:153
GeographicLib::AngleT::s
T s() const
Definition
Angle.hpp:149
GeographicLib::AngleT::reflect
AngleT & reflect(bool flips, bool flipc=false, bool swapp=false)
Definition
Angle.hpp:696
GeographicLib::Math::hypot3
static T hypot3(T x, T y, T z)
Definition
Math.cpp:285
GeographicLib::Math::real
double real
Definition
Math.hpp:115
GeographicLib::Triaxial::Cartesian3
Transformations between Cartesian and triaxial coordinates.
Definition
Cartesian3.hpp:94
GeographicLib::Triaxial::Ellipsoid3
A triaxial ellipsoid.
Definition
Ellipsoid3.hpp:82
GeographicLib::Triaxial::Ellipsoid3::k2
real k2() const
Definition
Ellipsoid3.hpp:198
GeographicLib::Triaxial::Ellipsoid3::b
real b() const
Definition
Ellipsoid3.hpp:186
GeographicLib::Triaxial::Ellipsoid3::AngNorm
static bool AngNorm(Angle &bet, Angle &omg, Angle &alp, bool alt=false)
Definition
Ellipsoid3.hpp:247
GeographicLib::Triaxial::Ellipsoid3::Ellipsoid3
Ellipsoid3()
Definition
Ellipsoid3.cpp:17
GeographicLib::Triaxial::Ellipsoid3::AngNorm
static bool AngNorm(Angle &bet, Angle &omg, bool alt=false)
Definition
Ellipsoid3.hpp:267
GeographicLib::Triaxial::Ellipsoid3::kp2
real kp2() const
Definition
Ellipsoid3.hpp:202
GeographicLib::Triaxial::Ellipsoid3::c
real c() const
Definition
Ellipsoid3.hpp:190
GeographicLib::Triaxial::Ellipsoid3::vec3
std::array< Math::real, 3 > vec3
Definition
Ellipsoid3.hpp:88
GeographicLib::Triaxial::Ellipsoid3::e2
real e2() const
Definition
Ellipsoid3.hpp:194
GeographicLib::Triaxial::Ellipsoid3::a
real a() const
Definition
Ellipsoid3.hpp:182
GeographicLib::Triaxial::Geodesic3
The solution of the geodesic problem for a triaxial ellipsoid.
Definition
Geodesic3.hpp:65
GeographicLib::Triaxial
Namespace for operations on triaxial ellipsoids.
Definition
Cartesian3.cpp:13
GeographicLib
Namespace for GeographicLib.
Definition
Accumulator.cpp:12
GeographicLib::Angle
AngleT< Math::real > Angle
Definition
Angle.hpp:760
include
GeographicLib
Triaxial
Ellipsoid3.hpp
Generated by
1.17.0