35 # pragma warning (disable: 4701 4127) 43 : maxit2_(maxit1_ +
Math::digits() + 10)
47 , tiny_(sqrt(numeric_limits<real>::min()))
48 , tol0_(numeric_limits<real>::epsilon())
54 , tolb_(tol0_ * tol2_)
55 , xthresh_(1000 * tol2_)
60 , _ep2(_e2 /
Math::sq(_f1))
71 (_f > 0 ?
Math::asinh(sqrt(_ep2)) : atan(sqrt(-_e2))) /
83 , _etol2(0.1 * tol2_ /
84 sqrt( max(real(0.001), abs(_f)) * min(real(1), 1 - _f/2) / 2 ))
99 Math::real GeodesicExact::CosSeries(real sinx, real cosx,
100 const real c[],
int n) {
107 ar = 2 * (cosx - sinx) * (cosx + sinx),
108 y0 = n & 1 ? *--c : 0, y1 = 0;
113 y1 = ar * y0 - y1 + *--c;
114 y0 = ar * y1 - y0 + *--c;
116 return cosx * (y0 - y1);
120 unsigned caps)
const {
125 bool arcmode, real s12_a12,
127 real& lat2, real& lon2, real& azi2,
128 real& s12, real& m12,
129 real& M12, real& M21,
135 GenPosition(arcmode, s12_a12, outmask,
136 lat2, lon2, azi2, s12, m12, M12, M21, S12);
141 bool arcmode, real s12_a12,
142 unsigned caps)
const {
150 caps, arcmode, s12_a12);
155 unsigned caps)
const {
161 unsigned caps)
const {
165 Math::real GeodesicExact::GenInverse(real lat1, real lon1,
166 real lat2, real lon2,
167 unsigned outmask, real& s12,
168 real& salp1, real& calp1,
169 real& salp2, real& calp2,
170 real& m12, real& M12, real& M21,
177 int lonsign = lon12 >= 0 ? 1 : -1;
195 int swapp = abs(lat1) < abs(lat2) ? -1 : 1;
201 int latsign = lat1 < 0 ? 1 : -1;
216 real sbet1, cbet1, sbet2, cbet2, s12x, m12x;
224 Math::norm(sbet1, cbet1); cbet1 = max(tiny_, cbet1);
228 Math::norm(sbet2, cbet2); cbet2 = max(tiny_, cbet2);
238 if (cbet1 < -sbet1) {
240 sbet2 = sbet2 < 0 ? sbet1 : -sbet1;
242 if (abs(sbet2) == -sbet1)
247 dn1 = (_f >= 0 ? sqrt(1 + _ep2 *
Math::sq(sbet1)) :
248 sqrt(1 - _e2 *
Math::sq(cbet1)) / _f1),
249 dn2 = (_f >= 0 ? sqrt(1 + _ep2 *
Math::sq(sbet2)) :
250 sqrt(1 - _e2 *
Math::sq(cbet2)) / _f1);
254 bool meridian = lat1 == -90 || slam12 == 0;
261 calp1 = clam12; salp1 = slam12;
262 calp2 = 1; salp2 = 0;
266 ssig1 = sbet1, csig1 = calp1 * cbet1,
267 ssig2 = sbet2, csig2 = calp2 * cbet2;
270 sig12 = atan2(max(real(0), csig1 * ssig2 - ssig1 * csig2),
271 csig1 * csig2 + ssig1 * ssig2);
274 Lengths(E, sig12, ssig1, csig1, dn1, ssig2, csig2, dn2,
276 s12x, m12x, dummy, M12, M21);
285 if (sig12 < 1 || m12x >= 0) {
287 if (sig12 < 3 * tiny_)
288 sig12 = m12x = s12x = 0;
298 real omg12 = 0, somg12 = 2, comg12 = 0;
301 (_f <= 0 || lon12s >= _f * 180)) {
304 calp1 = calp2 = 0; salp1 = salp2 = 1;
306 sig12 = omg12 = lam12 / _f1;
307 m12x = _b * sin(sig12);
309 M12 = M21 = cos(sig12);
312 }
else if (!meridian) {
319 sig12 = InverseStart(E, sbet1, cbet1, dn1, sbet2, cbet2, dn2,
320 lam12, slam12, clam12,
321 salp1, calp1, salp2, calp2, dnm);
325 s12x = sig12 * _b * dnm;
326 m12x =
Math::sq(dnm) * _b * sin(sig12 / dnm);
328 M12 = M21 = cos(sig12 / dnm);
330 omg12 = lam12 / (_f1 * dnm);
346 real ssig1 = 0, csig1 = 0, ssig2 = 0, csig2 = 0;
349 real salp1a = tiny_, calp1a = 1, salp1b = tiny_, calp1b = -1;
350 for (
bool tripn =
false, tripb =
false;
375 real v = Lambda12(sbet1, cbet1, dn1, sbet2, cbet2, dn2, salp1, calp1,
377 salp2, calp2, sig12, ssig1, csig1, ssig2, csig2,
378 E, somg12, comg12, numit < maxit1_, dv);
380 if (tripb || !(abs(v) >= (tripn ? 8 : 1) * tol0_))
break;
382 if (v > 0 && (numit > maxit1_ || calp1/salp1 > calp1b/salp1b))
383 { salp1b = salp1; calp1b = calp1; }
384 else if (v < 0 && (numit > maxit