geographiclib 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS +12 -0
- data/LICENSE +24 -0
- data/ext/geographiclib/Accumulator.cpp +23 -0
- data/ext/geographiclib/AlbersEqualArea.cpp +445 -0
- data/ext/geographiclib/AzimuthalEquidistant.cpp +41 -0
- data/ext/geographiclib/CassiniSoldner.cpp +89 -0
- data/ext/geographiclib/CircularEngine.cpp +96 -0
- data/ext/geographiclib/DMS.cpp +381 -0
- data/ext/geographiclib/Ellipsoid.cpp +125 -0
- data/ext/geographiclib/EllipticFunction.cpp +512 -0
- data/ext/geographiclib/GARS.cpp +122 -0
- data/ext/geographiclib/GeoCoords.cpp +175 -0
- data/ext/geographiclib/Geocentric.cpp +172 -0
- data/ext/geographiclib/Geodesic.cpp +1908 -0
- data/ext/geographiclib/GeodesicExact.cpp +927 -0
- data/ext/geographiclib/GeodesicExactC4.cpp +7879 -0
- data/ext/geographiclib/GeodesicLine.cpp +321 -0
- data/ext/geographiclib/GeodesicLineExact.cpp +289 -0
- data/ext/geographiclib/GeographicLib/Accumulator.hpp +184 -0
- data/ext/geographiclib/GeographicLib/AlbersEqualArea.hpp +312 -0
- data/ext/geographiclib/GeographicLib/AzimuthalEquidistant.hpp +139 -0
- data/ext/geographiclib/GeographicLib/CassiniSoldner.hpp +204 -0
- data/ext/geographiclib/GeographicLib/CircularEngine.hpp +195 -0
- data/ext/geographiclib/GeographicLib/Config.h +12 -0
- data/ext/geographiclib/GeographicLib/Constants.hpp +387 -0
- data/ext/geographiclib/GeographicLib/DMS.hpp +370 -0
- data/ext/geographiclib/GeographicLib/Ellipsoid.hpp +534 -0
- data/ext/geographiclib/GeographicLib/EllipticFunction.hpp +692 -0
- data/ext/geographiclib/GeographicLib/GARS.hpp +143 -0
- data/ext/geographiclib/GeographicLib/GeoCoords.hpp +544 -0
- data/ext/geographiclib/GeographicLib/Geocentric.hpp +267 -0
- data/ext/geographiclib/GeographicLib/Geodesic.hpp +970 -0
- data/ext/geographiclib/GeographicLib/GeodesicExact.hpp +862 -0
- data/ext/geographiclib/GeographicLib/GeodesicLine.hpp +701 -0
- data/ext/geographiclib/GeographicLib/GeodesicLineExact.hpp +667 -0
- data/ext/geographiclib/GeographicLib/Geohash.hpp +180 -0
- data/ext/geographiclib/GeographicLib/Geoid.hpp +472 -0
- data/ext/geographiclib/GeographicLib/Georef.hpp +160 -0
- data/ext/geographiclib/GeographicLib/Gnomonic.hpp +206 -0
- data/ext/geographiclib/GeographicLib/GravityCircle.hpp +301 -0
- data/ext/geographiclib/GeographicLib/GravityModel.hpp +520 -0
- data/ext/geographiclib/GeographicLib/LambertConformalConic.hpp +313 -0
- data/ext/geographiclib/GeographicLib/LocalCartesian.hpp +236 -0
- data/ext/geographiclib/GeographicLib/MGRS.hpp +355 -0
- data/ext/geographiclib/GeographicLib/MagneticCircle.hpp +178 -0
- data/ext/geographiclib/GeographicLib/MagneticModel.hpp +347 -0
- data/ext/geographiclib/GeographicLib/Math.hpp +920 -0
- data/ext/geographiclib/GeographicLib/NormalGravity.hpp +350 -0
- data/ext/geographiclib/GeographicLib/OSGB.hpp +249 -0
- data/ext/geographiclib/GeographicLib/PolarStereographic.hpp +150 -0
- data/ext/geographiclib/GeographicLib/PolygonArea.hpp +288 -0
- data/ext/geographiclib/GeographicLib/Rhumb.hpp +589 -0
- data/ext/geographiclib/GeographicLib/SphericalEngine.hpp +376 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic.hpp +354 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic1.hpp +281 -0
- data/ext/geographiclib/GeographicLib/SphericalHarmonic2.hpp +315 -0
- data/ext/geographiclib/GeographicLib/TransverseMercator.hpp +196 -0
- data/ext/geographiclib/GeographicLib/TransverseMercatorExact.hpp +254 -0
- data/ext/geographiclib/GeographicLib/UTMUPS.hpp +421 -0
- data/ext/geographiclib/GeographicLib/Utility.hpp +612 -0
- data/ext/geographiclib/Geohash.cpp +102 -0
- data/ext/geographiclib/Geoid.cpp +509 -0
- data/ext/geographiclib/Georef.cpp +135 -0
- data/ext/geographiclib/Gnomonic.cpp +85 -0
- data/ext/geographiclib/GravityCircle.cpp +129 -0
- data/ext/geographiclib/GravityModel.cpp +360 -0
- data/ext/geographiclib/LambertConformalConic.cpp +456 -0
- data/ext/geographiclib/LocalCartesian.cpp +62 -0
- data/ext/geographiclib/MGRS.cpp +461 -0
- data/ext/geographiclib/MagneticCircle.cpp +52 -0
- data/ext/geographiclib/MagneticModel.cpp +269 -0
- data/ext/geographiclib/Math.cpp +63 -0
- data/ext/geographiclib/NormalGravity.cpp +262 -0
- data/ext/geographiclib/OSGB.cpp +167 -0
- data/ext/geographiclib/PolarStereographic.cpp +108 -0
- data/ext/geographiclib/PolygonArea.cpp +204 -0
- data/ext/geographiclib/Rhumb.cpp +383 -0
- data/ext/geographiclib/SphericalEngine.cpp +477 -0
- data/ext/geographiclib/TransverseMercator.cpp +603 -0
- data/ext/geographiclib/TransverseMercatorExact.cpp +464 -0
- data/ext/geographiclib/UTMUPS.cpp +296 -0
- data/ext/geographiclib/Utility.cpp +61 -0
- data/ext/geographiclib/extconf.rb +3 -0
- data/ext/geographiclib/geographiclib.cpp +62 -0
- data/lib/geographiclib.rb +20 -0
- metadata +140 -0
@@ -0,0 +1,281 @@
|
|
1
|
+
/**
|
2
|
+
* \file SphericalHarmonic1.hpp
|
3
|
+
* \brief Header for GeographicLib::SphericalHarmonic1 class
|
4
|
+
*
|
5
|
+
* Copyright (c) Charles Karney (2011) <charles@karney.com> and licensed under
|
6
|
+
* the MIT/X11 License. For more information, see
|
7
|
+
* http://geographiclib.sourceforge.net/
|
8
|
+
**********************************************************************/
|
9
|
+
|
10
|
+
#if !defined(GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP)
|
11
|
+
#define GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP 1
|
12
|
+
|
13
|
+
#include <vector>
|
14
|
+
#include <GeographicLib/Constants.hpp>
|
15
|
+
#include <GeographicLib/SphericalEngine.hpp>
|
16
|
+
#include <GeographicLib/CircularEngine.hpp>
|
17
|
+
|
18
|
+
namespace GeographicLib {
|
19
|
+
|
20
|
+
/**
|
21
|
+
* \brief Spherical harmonic series with a correction to the coefficients
|
22
|
+
*
|
23
|
+
* This classes is similar to SphericalHarmonic, except that the coefficients
|
24
|
+
* <i>C</i><sub><i>nm</i></sub> are replaced by
|
25
|
+
* <i>C</i><sub><i>nm</i></sub> + \e tau <i>C'</i><sub><i>nm</i></sub> (and
|
26
|
+
* similarly for <i>S</i><sub><i>nm</i></sub>).
|
27
|
+
*
|
28
|
+
* Example of use:
|
29
|
+
* \include example-SphericalHarmonic1.cpp
|
30
|
+
**********************************************************************/
|
31
|
+
|
32
|
+
class GEOGRAPHICLIB_EXPORT SphericalHarmonic1 {
|
33
|
+
public:
|
34
|
+
/**
|
35
|
+
* Supported normalizations for associate Legendre polynomials.
|
36
|
+
**********************************************************************/
|
37
|
+
enum normalization {
|
38
|
+
/**
|
39
|
+
* Fully normalized associated Legendre polynomials. See
|
40
|
+
* SphericalHarmonic::FULL for documentation.
|
41
|
+
*
|
42
|
+
* @hideinitializer
|
43
|
+
**********************************************************************/
|
44
|
+
FULL = SphericalEngine::FULL,
|
45
|
+
/**
|
46
|
+
* Schmidt semi-normalized associated Legendre polynomials. See
|
47
|
+
* SphericalHarmonic::SCHMIDT for documentation.
|
48
|
+
*
|
49
|
+
* @hideinitializer
|
50
|
+
**********************************************************************/
|
51
|
+
SCHMIDT = SphericalEngine::SCHMIDT,
|
52
|
+
};
|
53
|
+
|
54
|
+
private:
|
55
|
+
typedef Math::real real;
|
56
|
+
SphericalEngine::coeff _c[2];
|
57
|
+
real _a;
|
58
|
+
unsigned _norm;
|
59
|
+
|
60
|
+
public:
|
61
|
+
/**
|
62
|
+
* Constructor with a full set of coefficients specified.
|
63
|
+
*
|
64
|
+
* @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>.
|
65
|
+
* @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>.
|
66
|
+
* @param[in] N the maximum degree and order of the sum
|
67
|
+
* @param[in] C1 the coefficients <i>C'</i><sub><i>nm</i></sub>.
|
68
|
+
* @param[in] S1 the coefficients <i>S'</i><sub><i>nm</i></sub>.
|
69
|
+
* @param[in] N1 the maximum degree and order of the correction
|
70
|
+
* coefficients <i>C'</i><sub><i>nm</i></sub> and
|
71
|
+
* <i>S'</i><sub><i>nm</i></sub>.
|
72
|
+
* @param[in] a the reference radius appearing in the definition of the
|
73
|
+
* sum.
|
74
|
+
* @param[in] norm the normalization for the associated Legendre
|
75
|
+
* polynomials, either SphericalHarmonic1::FULL (the default) or
|
76
|
+
* SphericalHarmonic1::SCHMIDT.
|
77
|
+
* @exception GeographicErr if \e N and \e N1 do not satisfy \e N ≥
|
78
|
+
* \e N1 ≥ −1.
|
79
|
+
* @exception GeographicErr if any of the vectors of coefficients is not
|
80
|
+
* large enough.
|
81
|
+
*
|
82
|
+
* See SphericalHarmonic for the way the coefficients should be stored.
|
83
|
+
*
|
84
|
+
* The class stores <i>pointers</i> to the first elements of \e C, \e S, \e
|
85
|
+
* C', and \e S'. These arrays should not be altered or destroyed during
|
86
|
+
* the lifetime of a SphericalHarmonic object.
|
87
|
+
**********************************************************************/
|
88
|
+
SphericalHarmonic1(const std::vector<real>& C,
|
89
|
+
const std::vector<real>& S,
|
90
|
+
int N,
|
91
|
+
const std::vector<real>& C1,
|
92
|
+
const std::vector<real>& S1,
|
93
|
+
int N1,
|
94
|
+
real a, unsigned norm = FULL)
|
95
|
+
: _a(a)
|
96
|
+
, _norm(norm) {
|
97
|
+
if (!(N1 <= N))
|
98
|
+
throw GeographicErr("N1 cannot be larger that N");
|
99
|
+
_c[0] = SphericalEngine::coeff(C, S, N);
|
100
|
+
_c[1] = SphericalEngine::coeff(C1, S1, N1);
|
101
|
+
}
|
102
|
+
|
103
|
+
/**
|
104
|
+
* Constructor with a subset of coefficients specified.
|
105
|
+
*
|
106
|
+
* @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>.
|
107
|
+
* @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>.
|
108
|
+
* @param[in] N the degree used to determine the layout of \e C and \e S.
|
109
|
+
* @param[in] nmx the maximum degree used in the sum. The sum over \e n is
|
110
|
+
* from 0 thru \e nmx.
|
111
|
+
* @param[in] mmx the maximum order used in the sum. The sum over \e m is
|
112
|
+
* from 0 thru min(\e n, \e mmx).
|
113
|
+
* @param[in] C1 the coefficients <i>C'</i><sub><i>nm</i></sub>.
|
114
|
+
* @param[in] S1 the coefficients <i>S'</i><sub><i>nm</i></sub>.
|
115
|
+
* @param[in] N1 the degree used to determine the layout of \e C' and \e
|
116
|
+
* S'.
|
117
|
+
* @param[in] nmx1 the maximum degree used for \e C' and \e S'.
|
118
|
+
* @param[in] mmx1 the maximum order used for \e C' and \e S'.
|
119
|
+
* @param[in] a the reference radius appearing in the definition of the
|
120
|
+
* sum.
|
121
|
+
* @param[in] norm the normalization for the associated Legendre
|
122
|
+
* polynomials, either SphericalHarmonic1::FULL (the default) or
|
123
|
+
* SphericalHarmonic1::SCHMIDT.
|
124
|
+
* @exception GeographicErr if the parameters do not satisfy \e N ≥ \e
|
125
|
+
* nmx ≥ \e mmx ≥ −1; \e N1 ≥ \e nmx1 ≥ \e mmx1 ≥
|
126
|
+
* −1; \e N ≥ \e N1; \e nmx ≥ \e nmx1; \e mmx ≥ \e mmx1.
|
127
|
+
* @exception GeographicErr if any of the vectors of coefficients is not
|
128
|
+
* large enough.
|
129
|
+
*
|
130
|
+
* The class stores <i>pointers</i> to the first elements of \e C, \e S, \e
|
131
|
+
* C', and \e S'. These arrays should not be altered or destroyed during
|
132
|
+
* the lifetime of a SphericalHarmonic object.
|
133
|
+
**********************************************************************/
|
134
|
+
SphericalHarmonic1(const std::vector<real>& C,
|
135
|
+
const std::vector<real>& S,
|
136
|
+
int N, int nmx, int mmx,
|
137
|
+
const std::vector<real>& C1,
|
138
|
+
const std::vector<real>& S1,
|
139
|
+
int N1, int nmx1, int mmx1,
|
140
|
+
real a, unsigned norm = FULL)
|
141
|
+
: _a(a)
|
142
|
+
, _norm(norm) {
|
143
|
+
if (!(nmx1 <= nmx))
|
144
|
+
throw GeographicErr("nmx1 cannot be larger that nmx");
|
145
|
+
if (!(mmx1 <= mmx))
|
146
|
+
throw GeographicErr("mmx1 cannot be larger that mmx");
|
147
|
+
_c[0] = SphericalEngine::coeff(C, S, N, nmx, mmx);
|
148
|
+
_c[1] = SphericalEngine::coeff(C1, S1, N1, nmx1, mmx1);
|
149
|
+
}
|
150
|
+
|
151
|
+
/**
|
152
|
+
* A default constructor so that the object can be created when the
|
153
|
+
* constructor for another object is initialized. This default object can
|
154
|
+
* then be reset with the default copy assignment operator.
|
155
|
+
**********************************************************************/
|
156
|
+
SphericalHarmonic1() {}
|
157
|
+
|
158
|
+
/**
|
159
|
+
* Compute a spherical harmonic sum with a correction term.
|
160
|
+
*
|
161
|
+
* @param[in] tau multiplier for correction coefficients \e C' and \e S'.
|
162
|
+
* @param[in] x cartesian coordinate.
|
163
|
+
* @param[in] y cartesian coordinate.
|
164
|
+
* @param[in] z cartesian coordinate.
|
165
|
+
* @return \e V the spherical harmonic sum.
|
166
|
+
*
|
167
|
+
* This routine requires constant memory and thus never throws
|
168
|
+
* an exception.
|
169
|
+
**********************************************************************/
|
170
|
+
Math::real operator()(real tau, real x, real y, real z) const {
|
171
|
+
real f[] = {1, tau};
|
172
|
+
real v = 0;
|
173
|
+
real dummy;
|
174
|
+
switch (_norm) {
|
175
|
+
case FULL:
|
176
|
+
v = SphericalEngine::Value<false, SphericalEngine::FULL, 2>
|
177
|
+
(_c, f, x, y, z, _a, dummy, dummy, dummy);
|
178
|
+
break;
|
179
|
+
case SCHMIDT:
|
180
|
+
v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 2>
|
181
|
+
(_c, f, x, y, z, _a, dummy, dummy, dummy);
|
182
|
+
break;
|
183
|
+
}
|
184
|
+
return v;
|
185
|
+
}
|
186
|
+
|
187
|
+
/**
|
188
|
+
* Compute a spherical harmonic sum with a correction term and its
|
189
|
+
* gradient.
|
190
|
+
*
|
191
|
+
* @param[in] tau multiplier for correction coefficients \e C' and \e S'.
|
192
|
+
* @param[in] x cartesian coordinate.
|
193
|
+
* @param[in] y cartesian coordinate.
|
194
|
+
* @param[in] z cartesian coordinate.
|
195
|
+
* @param[out] gradx \e x component of the gradient
|
196
|
+
* @param[out] grady \e y component of the gradient
|
197
|
+
* @param[out] gradz \e z component of the gradient
|
198
|
+
* @return \e V the spherical harmonic sum.
|
199
|
+
*
|
200
|
+
* This is the same as the previous function, except that the components of
|
201
|
+
* the gradients of the sum in the \e x, \e y, and \e z directions are
|
202
|
+
* computed. This routine requires constant memory and thus never throws
|
203
|
+
* an exception.
|
204
|
+
**********************************************************************/
|
205
|
+
Math::real operator()(real tau, real x, real y, real z,
|
206
|
+
real& gradx, real& grady, real& gradz) const {
|
207
|
+
real f[] = {1, tau};
|
208
|
+
real v = 0;
|
209
|
+
switch (_norm) {
|
210
|
+
case FULL:
|
211
|
+
v = SphericalEngine::Value<true, SphericalEngine::FULL, 2>
|
212
|
+
(_c, f, x, y, z, _a, gradx, grady, gradz);
|
213
|
+
break;
|
214
|
+
case SCHMIDT:
|
215
|
+
v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 2>
|
216
|
+
(_c, f, x, y, z, _a, gradx, grady, gradz);
|
217
|
+
break;
|
218
|
+
}
|
219
|
+
return v;
|
220
|
+
}
|
221
|
+
|
222
|
+
/**
|
223
|
+
* Create a CircularEngine to allow the efficient evaluation of several
|
224
|
+
* points on a circle of latitude at a fixed value of \e tau.
|
225
|
+
*
|
226
|
+
* @param[in] tau the multiplier for the correction coefficients.
|
227
|
+
* @param[in] p the radius of the circle.
|
228
|
+
* @param[in] z the height of the circle above the equatorial plane.
|
229
|
+
* @param[in] gradp if true the returned object will be able to compute the
|
230
|
+
* gradient of the sum.
|
231
|
+
* @exception std::bad_alloc if the memory for the CircularEngine can't be
|
232
|
+
* allocated.
|
233
|
+
* @return the CircularEngine object.
|
234
|
+
*
|
235
|
+
* SphericalHarmonic1::operator()() exchanges the order of the sums in the
|
236
|
+
* definition, i.e., ∑<sub><i>n</i> = 0..<i>N</i></sub>
|
237
|
+
* ∑<sub><i>m</i> = 0..<i>n</i></sub> becomes ∑<sub><i>m</i> =
|
238
|
+
* 0..<i>N</i></sub> ∑<sub><i>n</i> = <i>m</i>..<i>N</i></sub>.
|
239
|
+
* SphericalHarmonic1::Circle performs the inner sum over degree \e n
|
240
|
+
* (which entails about <i>N</i><sup>2</sup> operations). Calling
|
241
|
+
* CircularEngine::operator()() on the returned object performs the outer
|
242
|
+
* sum over the order \e m (about \e N operations).
|
243
|
+
*
|
244
|
+
* See SphericalHarmonic::Circle for an example of its use.
|
245
|
+
**********************************************************************/
|
246
|
+
CircularEngine Circle(real tau, real p, real z, bool gradp) const {
|
247
|
+
real f[] = {1, tau};
|
248
|
+
switch (_norm) {
|
249
|
+
case FULL:
|
250
|
+
return gradp ?
|
251
|
+
SphericalEngine::Circle<true, SphericalEngine::FULL, 2>
|
252
|
+
(_c, f, p, z, _a) :
|
253
|
+
SphericalEngine::Circle<false, SphericalEngine::FULL, 2>
|
254
|
+
(_c, f, p, z, _a);
|
255
|
+
break;
|
256
|
+
case SCHMIDT:
|
257
|
+
default: // To avoid compiler warnings
|
258
|
+
return gradp ?
|
259
|
+
SphericalEngine::Circle<true, SphericalEngine::SCHMIDT, 2>
|
260
|
+
(_c, f, p, z, _a) :
|
261
|
+
SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 2>
|
262
|
+
(_c, f, p, z, _a);
|
263
|
+
break;
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
/**
|
268
|
+
* @return the zeroth SphericalEngine::coeff object.
|
269
|
+
**********************************************************************/
|
270
|
+
const SphericalEngine::coeff& Coefficients() const
|
271
|
+
{ return _c[0]; }
|
272
|
+
/**
|
273
|
+
* @return the first SphericalEngine::coeff object.
|
274
|
+
**********************************************************************/
|
275
|
+
const SphericalEngine::coeff& Coefficients1() const
|
276
|
+
{ return _c[1]; }
|
277
|
+
};
|
278
|
+
|
279
|
+
} // namespace GeographicLib
|
280
|
+
|
281
|
+
#endif // GEOGRAPHICLIB_SPHERICALHARMONIC1_HPP
|
@@ -0,0 +1,315 @@
|
|
1
|
+
/**
|
2
|
+
* \file SphericalHarmonic2.hpp
|
3
|
+
* \brief Header for GeographicLib::SphericalHarmonic2 class
|
4
|
+
*
|
5
|
+
* Copyright (c) Charles Karney (2011-2012) <charles@karney.com> and licensed
|
6
|
+
* under the MIT/X11 License. For more information, see
|
7
|
+
* http://geographiclib.sourceforge.net/
|
8
|
+
**********************************************************************/
|
9
|
+
|
10
|
+
#if !defined(GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP)
|
11
|
+
#define GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP 1
|
12
|
+
|
13
|
+
#include <vector>
|
14
|
+
#include <GeographicLib/Constants.hpp>
|
15
|
+
#include <GeographicLib/SphericalEngine.hpp>
|
16
|
+
#include <GeographicLib/CircularEngine.hpp>
|
17
|
+
|
18
|
+
namespace GeographicLib {
|
19
|
+
|
20
|
+
/**
|
21
|
+
* \brief Spherical harmonic series with two corrections to the coefficients
|
22
|
+
*
|
23
|
+
* This classes is similar to SphericalHarmonic, except that the coefficients
|
24
|
+
* <i>C</i><sub><i>nm</i></sub> are replaced by
|
25
|
+
* <i>C</i><sub><i>nm</i></sub> + \e tau' <i>C'</i><sub><i>nm</i></sub> + \e
|
26
|
+
* tau'' <i>C''</i><sub><i>nm</i></sub> (and similarly for
|
27
|
+
* <i>S</i><sub><i>nm</i></sub>).
|
28
|
+
*
|
29
|
+
* Example of use:
|
30
|
+
* \include example-SphericalHarmonic2.cpp
|
31
|
+
**********************************************************************/
|
32
|
+
|
33
|
+
// Don't include the GEOGRPAHIC_EXPORT because this header-only class isn't
|
34
|
+
// used by any other classes in the library.
|
35
|
+
class /*GEOGRAPHICLIB_EXPORT*/ SphericalHarmonic2 {
|
36
|
+
public:
|
37
|
+
/**
|
38
|
+
* Supported normalizations for associate Legendre polynomials.
|
39
|
+
**********************************************************************/
|
40
|
+
enum normalization {
|
41
|
+
/**
|
42
|
+
* Fully normalized associated Legendre polynomials. See
|
43
|
+
* SphericalHarmonic::FULL for documentation.
|
44
|
+
*
|
45
|
+
* @hideinitializer
|
46
|
+
**********************************************************************/
|
47
|
+
FULL = SphericalEngine::FULL,
|
48
|
+
/**
|
49
|
+
* Schmidt semi-normalized associated Legendre polynomials. See
|
50
|
+
* SphericalHarmonic::SCHMIDT for documentation.
|
51
|
+
*
|
52
|
+
* @hideinitializer
|
53
|
+
**********************************************************************/
|
54
|
+
SCHMIDT = SphericalEngine::SCHMIDT,
|
55
|
+
};
|
56
|
+
|
57
|
+
private:
|
58
|
+
typedef Math::real real;
|
59
|
+
SphericalEngine::coeff _c[3];
|
60
|
+
real _a;
|
61
|
+
unsigned _norm;
|
62
|
+
|
63
|
+
public:
|
64
|
+
/**
|
65
|
+
* Constructor with a full set of coefficients specified.
|
66
|
+
*
|
67
|
+
* @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>.
|
68
|
+
* @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>.
|
69
|
+
* @param[in] N the maximum degree and order of the sum
|
70
|
+
* @param[in] C1 the coefficients <i>C'</i><sub><i>nm</i></sub>.
|
71
|
+
* @param[in] S1 the coefficients <i>S'</i><sub><i>nm</i></sub>.
|
72
|
+
* @param[in] N1 the maximum degree and order of the first correction
|
73
|
+
* coefficients <i>C'</i><sub><i>nm</i></sub> and
|
74
|
+
* <i>S'</i><sub><i>nm</i></sub>.
|
75
|
+
* @param[in] C2 the coefficients <i>C''</i><sub><i>nm</i></sub>.
|
76
|
+
* @param[in] S2 the coefficients <i>S''</i><sub><i>nm</i></sub>.
|
77
|
+
* @param[in] N2 the maximum degree and order of the second correction
|
78
|
+
* coefficients <i>C'</i><sub><i>nm</i></sub> and
|
79
|
+
* <i>S'</i><sub><i>nm</i></sub>.
|
80
|
+
* @param[in] a the reference radius appearing in the definition of the
|
81
|
+
* sum.
|
82
|
+
* @param[in] norm the normalization for the associated Legendre
|
83
|
+
* polynomials, either SphericalHarmonic2::FULL (the default) or
|
84
|
+
* SphericalHarmonic2::SCHMIDT.
|
85
|
+
* @exception GeographicErr if \e N and \e N1 do not satisfy \e N ≥
|
86
|
+
* \e N1 ≥ −1, and similarly for \e N2.
|
87
|
+
* @exception GeographicErr if any of the vectors of coefficients is not
|
88
|
+
* large enough.
|
89
|
+
*
|
90
|
+
* See SphericalHarmonic for the way the coefficients should be stored. \e
|
91
|
+
* N1 and \e N2 should satisfy \e N1 ≤ \e N and \e N2 ≤ \e N.
|
92
|
+
*
|
93
|
+
* The class stores <i>pointers</i> to the first elements of \e C, \e S, \e
|
94
|
+
* C', \e S', \e C'', and \e S''. These arrays should not be altered or
|
95
|
+
* destroyed during the lifetime of a SphericalHarmonic object.
|
96
|
+
**********************************************************************/
|
97
|
+
SphericalHarmonic2(const std::vector<real>& C,
|
98
|
+
const std::vector<real>& S,
|
99
|
+
int N,
|
100
|
+
const std::vector<real>& C1,
|
101
|
+
const std::vector<real>& S1,
|
102
|
+
int N1,
|
103
|
+
const std::vector<real>& C2,
|
104
|
+
const std::vector<real>& S2,
|
105
|
+
int N2,
|
106
|
+
real a, unsigned norm = FULL)
|
107
|
+
: _a(a)
|
108
|
+
, _norm(norm) {
|
109
|
+
if (!(N1 <= N && N2 <= N))
|
110
|
+
throw GeographicErr("N1 and N2 cannot be larger that N");
|
111
|
+
_c[0] = SphericalEngine::coeff(C, S, N);
|
112
|
+
_c[1] = SphericalEngine::coeff(C1, S1, N1);
|
113
|
+
_c[2] = SphericalEngine::coeff(C2, S2, N2);
|
114
|
+
}
|
115
|
+
|
116
|
+
/**
|
117
|
+
* Constructor with a subset of coefficients specified.
|
118
|
+
*
|
119
|
+
* @param[in] C the coefficients <i>C</i><sub><i>nm</i></sub>.
|
120
|
+
* @param[in] S the coefficients <i>S</i><sub><i>nm</i></sub>.
|
121
|
+
* @param[in] N the degree used to determine the layout of \e C and \e S.
|
122
|
+
* @param[in] nmx the maximum degree used in the sum. The sum over \e n is
|
123
|
+
* from 0 thru \e nmx.
|
124
|
+
* @param[in] mmx the maximum order used in the sum. The sum over \e m is
|
125
|
+
* from 0 thru min(\e n, \e mmx).
|
126
|
+
* @param[in] C1 the coefficients <i>C'</i><sub><i>nm</i></sub>.
|
127
|
+
* @param[in] S1 the coefficients <i>S'</i><sub><i>nm</i></sub>.
|
128
|
+
* @param[in] N1 the degree used to determine the layout of \e C' and \e
|
129
|
+
* S'.
|
130
|
+
* @param[in] nmx1 the maximum degree used for \e C' and \e S'.
|
131
|
+
* @param[in] mmx1 the maximum order used for \e C' and \e S'.
|
132
|
+
* @param[in] C2 the coefficients <i>C''</i><sub><i>nm</i></sub>.
|
133
|
+
* @param[in] S2 the coefficients <i>S''</i><sub><i>nm</i></sub>.
|
134
|
+
* @param[in] N2 the degree used to determine the layout of \e C'' and \e
|
135
|
+
* S''.
|
136
|
+
* @param[in] nmx2 the maximum degree used for \e C'' and \e S''.
|
137
|
+
* @param[in] mmx2 the maximum order used for \e C'' and \e S''.
|
138
|
+
* @param[in] a the reference radius appearing in the definition of the
|
139
|
+
* sum.
|
140
|
+
* @param[in] norm the normalization for the associated Legendre
|
141
|
+
* polynomials, either SphericalHarmonic2::FULL (the default) or
|
142
|
+
* SphericalHarmonic2::SCHMIDT.
|
143
|
+
* @exception GeographicErr if the parameters do not satisfy \e N ≥ \e
|
144
|
+
* nmx ≥ \e mmx ≥ −1; \e N1 ≥ \e nmx1 ≥ \e mmx1 ≥
|
145
|
+
* −1; \e N ≥ \e N1; \e nmx ≥ \e nmx1; \e mmx ≥ \e mmx1;
|
146
|
+
* and similarly for \e N2, \e nmx2, and \e mmx2.
|
147
|
+
* @exception GeographicErr if any of the vectors of coefficients is not
|
148
|
+
* large enough.
|
149
|
+
*
|
150
|
+
* The class stores <i>pointers</i> to the first elements of \e C, \e S, \e
|
151
|
+
* C', \e S', \e C'', and \e S''. These arrays should not be altered or
|
152
|
+
* destroyed during the lifetime of a SphericalHarmonic object.
|
153
|
+
**********************************************************************/
|
154
|
+
SphericalHarmonic2(const std::vector<real>& C,
|
155
|
+
const std::vector<real>& S,
|
156
|
+
int N, int nmx, int mmx,
|
157
|
+
const std::vector<real>& C1,
|
158
|
+
const std::vector<real>& S1,
|
159
|
+
int N1, int nmx1, int mmx1,
|
160
|
+
const std::vector<real>& C2,
|
161
|
+
const std::vector<real>& S2,
|
162
|
+
int N2, int nmx2, int mmx2,
|
163
|
+
real a, unsigned norm = FULL)
|
164
|
+
: _a(a)
|
165
|
+
, _norm(norm) {
|
166
|
+
if (!(nmx1 <= nmx && nmx2 <= nmx))
|
167
|
+
throw GeographicErr("nmx1 and nmx2 cannot be larger that nmx");
|
168
|
+
if (!(mmx1 <= mmx && mmx2 <= mmx))
|
169
|
+
throw GeographicErr("mmx1 and mmx2 cannot be larger that mmx");
|
170
|
+
_c[0] = SphericalEngine::coeff(C, S, N, nmx, mmx);
|
171
|
+
_c[1] = SphericalEngine::coeff(C1, S1, N1, nmx1, mmx1);
|
172
|
+
_c[2] = SphericalEngine::coeff(C2, S2, N2, nmx2, mmx2);
|
173
|
+
}
|
174
|
+
|
175
|
+
/**
|
176
|
+
* A default constructor so that the object can be created when the
|
177
|
+
* constructor for another object is initialized. This default object can
|
178
|
+
* then be reset with the default copy assignment operator.
|
179
|
+
**********************************************************************/
|
180
|
+
SphericalHarmonic2() {}
|
181
|
+
|
182
|
+
/**
|
183
|
+
* Compute a spherical harmonic sum with two correction terms.
|
184
|
+
*
|
185
|
+
* @param[in] tau1 multiplier for correction coefficients \e C' and \e S'.
|
186
|
+
* @param[in] tau2 multiplier for correction coefficients \e C'' and \e S''.
|
187
|
+
* @param[in] x cartesian coordinate.
|
188
|
+
* @param[in] y cartesian coordinate.
|
189
|
+
* @param[in] z cartesian coordinate.
|
190
|
+
* @return \e V the spherical harmonic sum.
|
191
|
+
*
|
192
|
+
* This routine requires constant memory and thus never throws an
|
193
|
+
* exception.
|
194
|
+
**********************************************************************/
|
195
|
+
Math::real operator()(real tau1, real tau2, real x, real y, real z)
|
196
|
+
const {
|
197
|
+
real f[] = {1, tau1, tau2};
|
198
|
+
real v = 0;
|
199
|
+
real dummy;
|
200
|
+
switch (_norm) {
|
201
|
+
case FULL:
|
202
|
+
v = SphericalEngine::Value<false, SphericalEngine::FULL, 3>
|
203
|
+
(_c, f, x, y, z, _a, dummy, dummy, dummy);
|
204
|
+
break;
|
205
|
+
case SCHMIDT:
|
206
|
+
v = SphericalEngine::Value<false, SphericalEngine::SCHMIDT, 3>
|
207
|
+
(_c, f, x, y, z, _a, dummy, dummy, dummy);
|
208
|
+
break;
|
209
|
+
}
|
210
|
+
return v;
|
211
|
+
}
|
212
|
+
|
213
|
+
/**
|
214
|
+
* Compute a spherical harmonic sum with two correction terms and its
|
215
|
+
* gradient.
|
216
|
+
*
|
217
|
+
* @param[in] tau1 multiplier for correction coefficients \e C' and \e S'.
|
218
|
+
* @param[in] tau2 multiplier for correction coefficients \e C'' and \e S''.
|
219
|
+
* @param[in] x cartesian coordinate.
|
220
|
+
* @param[in] y cartesian coordinate.
|
221
|
+
* @param[in] z cartesian coordinate.
|
222
|
+
* @param[out] gradx \e x component of the gradient
|
223
|
+
* @param[out] grady \e y component of the gradient
|
224
|
+
* @param[out] gradz \e z component of the gradient
|
225
|
+
* @return \e V the spherical harmonic sum.
|
226
|
+
*
|
227
|
+
* This is the same as the previous function, except that the components of
|
228
|
+
* the gradients of the sum in the \e x, \e y, and \e z directions are
|
229
|
+
* computed. This routine requires constant memory and thus never throws
|
230
|
+
* an exception.
|
231
|
+
**********************************************************************/
|
232
|
+
Math::real operator()(real tau1, real tau2, real x, real y, real z,
|
233
|
+
real& gradx, real& grady, real& gradz) const {
|
234
|
+
real f[] = {1, tau1, tau2};
|
235
|
+
real v = 0;
|
236
|
+
switch (_norm) {
|
237
|
+
case FULL:
|
238
|
+
v = SphericalEngine::Value<true, SphericalEngine::FULL, 3>
|
239
|
+
(_c, f, x, y, z, _a, gradx, grady, gradz);
|
240
|
+
break;
|
241
|
+
case SCHMIDT:
|
242
|
+
v = SphericalEngine::Value<true, SphericalEngine::SCHMIDT, 3>
|
243
|
+
(_c, f, x, y, z, _a, gradx, grady, gradz);
|
244
|
+
break;
|
245
|
+
}
|
246
|
+
return v;
|
247
|
+
}
|
248
|
+
|
249
|
+
/**
|
250
|
+
* Create a CircularEngine to allow the efficient evaluation of several
|
251
|
+
* points on a circle of latitude at fixed values of \e tau1 and \e tau2.
|
252
|
+
*
|
253
|
+
* @param[in] tau1 multiplier for correction coefficients \e C' and \e S'.
|
254
|
+
* @param[in] tau2 multiplier for correction coefficients \e C'' and \e S''.
|
255
|
+
* @param[in] p the radius of the circle.
|
256
|
+
* @param[in] z the height of the circle above the equatorial plane.
|
257
|
+
* @param[in] gradp if true the returned object will be able to compute the
|
258
|
+
* gradient of the sum.
|
259
|
+
* @exception std::bad_alloc if the memory for the CircularEngine can't be
|
260
|
+
* allocated.
|
261
|
+
* @return the CircularEngine object.
|
262
|
+
*
|
263
|
+
* SphericalHarmonic2::operator()() exchanges the order of the sums in the
|
264
|
+
* definition, i.e., ∑<sub><i>n</i> = 0..<i>N</i></sub>
|
265
|
+
* ∑<sub><i>m</i> = 0..<i>n</i></sub> becomes ∑<sub><i>m</i> =
|
266
|
+
* 0..<i>N</i></sub> ∑<sub><i>n</i> = <i>m</i>..<i>N</i></sub>..
|
267
|
+
* SphericalHarmonic2::Circle performs the inner sum over degree \e n
|
268
|
+
* (which entails about <i>N</i><sup>2</sup> operations). Calling
|
269
|
+
* CircularEngine::operator()() on the returned object performs the outer
|
270
|
+
* sum over the order \e m (about \e N operations).
|
271
|
+
*
|
272
|
+
* See SphericalHarmonic::Circle for an example of its use.
|
273
|
+
**********************************************************************/
|
274
|
+
CircularEngine Circle(real tau1, real tau2, real p, real z, bool gradp)
|
275
|
+
const {
|
276
|
+
real f[] = {1, tau1, tau2};
|
277
|
+
switch (_norm) {
|
278
|
+
case FULL:
|
279
|
+
return gradp ?
|
280
|
+
SphericalEngine::Circle<true, SphericalEngine::FULL, 3>
|
281
|
+
(_c, f, p, z, _a) :
|
282
|
+
SphericalEngine::Circle<false, SphericalEngine::FULL, 3>
|
283
|
+
(_c, f, p, z, _a);
|
284
|
+
break;
|
285
|
+
case SCHMIDT:
|
286
|
+
default: // To avoid compiler warnings
|
287
|
+
return gradp ?
|
288
|
+
SphericalEngine::Circle<true, SphericalEngine::SCHMIDT, 3>
|
289
|
+
(_c, f, p, z, _a) :
|
290
|
+
SphericalEngine::Circle<false, SphericalEngine::SCHMIDT, 3>
|
291
|
+
(_c, f, p, z, _a);
|
292
|
+
break;
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
296
|
+
/**
|
297
|
+
* @return the zeroth SphericalEngine::coeff object.
|
298
|
+
**********************************************************************/
|
299
|
+
const SphericalEngine::coeff& Coefficients() const
|
300
|
+
{ return _c[0]; }
|
301
|
+
/**
|
302
|
+
* @return the first SphericalEngine::coeff object.
|
303
|
+
**********************************************************************/
|
304
|
+
const SphericalEngine::coeff& Coefficients1() const
|
305
|
+
{ return _c[1]; }
|
306
|
+
/**
|
307
|
+
* @return the second SphericalEngine::coeff object.
|
308
|
+
**********************************************************************/
|
309
|
+
const SphericalEngine::coeff& Coefficients2() const
|
310
|
+
{ return _c[2]; }
|
311
|
+
};
|
312
|
+
|
313
|
+
} // namespace GeographicLib
|
314
|
+
|
315
|
+
#endif // GEOGRAPHICLIB_SPHERICALHARMONIC2_HPP
|