14 namespace GeographicLib {
24 real& s12, real& azi12)
const {
27 psi1 = _ell.IsometricLatitude(lat1),
28 psi2 = _ell.IsometricLatitude(lat2),
32 real dmudpsi = DIsometricToRectifying(psi2 *
Math::degree(),
34 s12 = h * dmudpsi * _ell.QuarterMeridian() / 90;
38 {
return RhumbLine(*
this, lat1, lon1, azi12, _exact); }
41 real& lat2, real& lon2)
const
42 { Line(lat1, lon1, azi12).Position(s12, lat2, lon2); }
48 return d ? (ei.
E(x) - ei.
E(y)) / d : 1;
64 real sx = sin(x), sy = sin(y), cx = cos(x), cy = cos(y);
65 real Dt = Dsin(x, y) * (sx + sy) /
66 ((cx + cy) * (sx * ei.
Delta(sy, cy) + sy * ei.
Delta(sx, cx))),
67 t = d * Dt, Dsz = 2 * Dt / (1 + t*t),
68 sz = d * Dsz, cz = (1 - t) * (1 + t) / (1 + t*t);
69 return ((sz ? ei.
E(sz, cz, ei.
Delta(sz, cz)) / sz : 1)
70 - ei.
k2() * sx * sy) * Dsz;
75 phix = latx *
Math::degree(), tbetx = _ell._f1 * tano(phix),
76 phiy = laty *
Math::degree(), tbety = _ell._f1 * tano(phiy);
77 return (
Math::pi()/2) * _ell._b * _ell._f1 * DE(atan(tbetx), atan(tbety))
78 * Dtan(phix, phiy) * Datan(tbetx, tbety) / _ell.QuarterMeridian();
85 return Dasinh(tx, ty) * Dtan(phix, phiy)
86 - Deatanhe(sin(phix), sin(phiy)) * Dsin(phix, phiy);
120 real p = x + y, d = x - y,
121 cp = cos(p), cd = cos(d),
122 sp = sin(p), sd = d ? sin(d)/d : 1,
123 m = 2 * cp * cd, s = sp * sd;
125 const real a[4] = {m, -s * d * d, -4 * s, m};
126 real ba[4] = {0, 0, 0, 0};
127 real bb[4] = {0, 0, 0, 0};
130 if (n > 0) b0[0] = b0[3] = c[n];
131 for (
int j = n - 1; j > 0; --j) {
134 b0[0] = a[0] * b1[0] + a[1] * b1[2] - b0[0] + c[j];
135 b0[1] = a[0] * b1[1] + a[1] * b1[3] - b0[1];
136 b0[2] = a[2] * b1[0] + a[3] * b1[2] - b0[2];
137 b0[3] = a[2] * b1[1] + a[3] * b1[3] - b0[3] + c[j];
139 b1[0] = sp * cd; b1[2] = 2 * sd * cp;
142 s = b0[2] * b1[0] + b0[3] * b1[2];
147 return 1 + SinSeries(chix, chiy,
148 _ell.ConformalToRectifyingCoeffs(), tm_maxord);
152 return 1 - SinSeries(mux, muy,
153 _ell.RectifyingToConformalCoeffs(), tm_maxord);
159 latx = _ell.InverseIsometricLatitude(psix/
Math::degree()),
160 laty = _ell.InverseIsometricLatitude(psiy/
Math::degree());
161 return DRectifying(latx, laty) / DIsometric(latx, laty);
163 return DConformalToRectifying(gd(psix), gd(psiy)) * Dgd(psix, psiy);
168 latx = _ell.InverseRectifyingLatitude(mux/
Math::degree()),
169 laty = _ell.InverseRectifyingLatitude(muy/
Math::degree());
171 DIsometric(latx, laty) / DRectifying(latx, laty) :
172 Dgdinv(_ell.ConformalLatitude(latx) * Math::degree(),
173 _ell.ConformalLatitude(laty) * Math::degree()) *
174 DRectifyingToConformal(mux, muy);
177 RhumbLine::RhumbLine(
const Rhumb& rh,
real lat1,
real lon1,
real azi12,
182 , _lon1(Math::AngNormalize(lon1))
183 , _azi12(Math::AngNormalize(azi12))
186 _salp = azi12 == -180 ? 0 : sin(alp12);
187 _calp = abs(azi12) == 90 ? 0 : cos(alp12);
188 _mu1 = _rh._ell.RectifyingLatitude(lat1);
189 _psi1 = _rh._ell.IsometricLatitude(lat1);
190 _r1 = _rh._ell.CircleRadius(lat1);
197 if (abs(mu2) <= 90) {
200 real psi12 = _rh.DRectifyingToIsometric( mu2 *
Math::degree(),
202 lon2 = _salp * psi12 / _calp;