/// <inheritdoc /> protected override void OnInverse(double[] xy, double[] lp, int startIndex, int numPoints) { for (int i = startIndex; i < startIndex + numPoints; i++) { int phi = i * 2 + PHI; int lam = i * 2 + LAMBDA; int x = i * 2 + X; int y = i * 2 + Y; double cz1 = Math.Cos(Proj.Hypot(xy[y], xy[x] + _hz0)); double cz2 = Math.Cos(Proj.Hypot(xy[y], xy[x] - _hz0)); double s = cz1 + cz2; double d = cz1 - cz2; lp[lam] = -Math.Atan2(d, (s * _thz0)); lp[phi] = Proj.Aacos(Proj.Hypot(_thz0 * s, d) * _rhshz0); if (xy[y] < 0) { lp[phi] = -lp[phi]; } /* lam--phi now in system relative to P1--P2 base equator */ double sp = Math.Sin(lp[phi]); double cp = Math.Cos(lp[phi]); lp[phi] = Proj.Aasin(_sa * sp + _ca * cp * (s = Math.Cos(lp[lam] -= _lp))); lp[lam] = Math.Atan2(cp * Math.Sin(lp[lam]), _sa * cp * s - _ca * sp) + _lamc; } }
/// <inheritdoc /> protected override void SphericalInverse(double[] xy, double[] lp, int startIndex, int numPoints) { for (int i = startIndex; i < startIndex + numPoints; i++) { int phi = i * 2 + PHI; int lam = i * 2 + LAMBDA; int x = i * 2 + X; int y = i * 2 + Y; double cRh; if ((cRh = Proj.Hypot(xy[x], xy[y])) > Math.PI) { if (cRh - EPS10 > Math.PI) { lp[phi] = double.NaN; lp[lam] = double.NaN; continue; //throw new ProjectionException(20); } cRh = Math.PI; } else if (cRh < EPS10) { lp[phi] = Phi0; lp[lam] = 0; return; } if (_mode == Modes.Oblique || _mode == Modes.Equitorial) { double sinc = Math.Sin(cRh); double cosc = Math.Cos(cRh); if (_mode == Modes.Equitorial) { lp[phi] = Proj.Aasin(xy[y] * sinc / cRh); xy[x] *= sinc; xy[y] = cosc * cRh; } else { lp[phi] = Proj.Aasin(cosc * _sinph0 + xy[y] * sinc * _cosph0 / cRh); xy[y] = (cosc - _sinph0 * Math.Sin(lp[phi])) * cRh; xy[x] *= sinc * _cosph0; } lp[lam] = xy[y] == 0 ? 0 : Math.Atan2(xy[x], xy[y]); } else if (_mode == Modes.NorthPole) { lp[phi] = HALF_PI - cRh; lp[lam] = Math.Atan2(xy[x], -xy[y]); } else { lp[phi] = cRh - HALF_PI; lp[lam] = Math.Atan2(xy[x], xy[y]); } } }
/// <inheritdoc /> protected override void EllipticalInverse(double[] xy, double[] lp, int startIndex, int numPoints) { if (_isGuam) { GuamInverse(xy, lp, startIndex, numPoints); } for (int i = startIndex; i < startIndex + numPoints; i++) { int phi = i * 2 + PHI; int lam = i * 2 + LAMBDA; int x = i * 2 + X; int y = i * 2 + Y; double c; if ((c = Proj.Hypot(xy[x], xy[y])) < EPS10) { lp[phi] = Phi0; lp[lam] = 0; continue; } if (_mode == Modes.Oblique || _mode == Modes.Equitorial) { double az; double cosAz = Math.Cos(az = Math.Atan2(xy[x], xy[y])); double t = _cosph0 * cosAz; double b = Es * t / OneEs; double a = -b * t; b *= 3 * (1 - a) * _sinph0; double d = c / _n1; double e = d * (1 - d * d * (a * (1 + a) / 6 + b * (1 + 3 * a) * d / 24)); double f = 1 - e * e * (a / 2 + b * e / 6); double psi = Proj.Aasin(_sinph0 * Math.Cos(e) + t * Math.Sin(e)); lp[lam] = Proj.Aasin(Math.Sin(az) * Math.Sin(e) / Math.Cos(psi)); if ((t = Math.Abs(psi)) < EPS10) { lp[phi] = 0; } else if (Math.Abs(t - HALF_PI) < 0) { lp[phi] = HALF_PI; } else { lp[phi] = Math.Atan((1 - Es * f * _sinph0 / Math.Sin(psi)) * Math.Tan(psi) / OneEs); } } else { /* Polar */ lp[phi] = Proj.InvMlfn(_mode == Modes.NorthPole ? _mp - c : _mp + c, Es, _en); lp[lam] = Math.Atan2(xy[x], _mode == Modes.NorthPole ? -xy[y] : xy[y]); } } }
/// <inheritdoc /> protected override void OnInverse(double[] xy, double[] lp, int startIndex, int numPoints) { for (int i = startIndex; i < startIndex + numPoints; i++) { int phi = i * 2 + PHI; int lam = i * 2 + LAMBDA; int x = i * 2 + X; int y = i * 2 + Y; lp[phi] = Proj.Aasin(xy[y] / _cY); lp[lam] = xy[x] / (_cX * Math.Cos(lp[phi])); lp[phi] += lp[phi]; lp[phi] = Proj.Aasin((lp[phi] + Math.Sin(lp[phi])) / _cP); } }
/// <inheritdoc /> protected override void OnInverse(double[] xy, double[] lp, int startIndex, int numPoints) { for (int i = startIndex; i < startIndex + numPoints; i++) { int phi = i * 2 + PHI; int lam = i * 2 + LAMBDA; int x = i * 2 + X; int y = i * 2 + Y; double c; lp[phi] = Proj.Aasin(xy[y] / CY); lp[lam] = xy[x] / (CX * (1 + (c = Math.Cos(lp[phi])))); lp[phi] = Proj.Aasin((lp[phi] + Math.Sin(lp[phi]) * (c + 2)) / CP); } }
/// <inheritdoc /> protected override void SphericalInverse(double[] xy, double[] lp, int startIndex, int numPoints) { for (int i = startIndex; i < startIndex + numPoints; i++) { int phi = i * 2 + PHI; int lam = i * 2 + LAMBDA; int x = i * 2 + X; int y = i * 2 + Y; xy[y] /= _cY; lp[phi] = _m > 0 ? Proj.Aasin((_m * xy[y] + Math.Sin(xy[y])) / _n) : (_n != 1 ? Proj.Aasin(Math.Sin(xy[y]) / _n) : xy[y]); lp[lam] = xy[x] / (_cX * (_m + Math.Cos(xy[y]))); } }
/// <summary> /// Initializes the transform using the parameters from the specified coordinate system information /// </summary> /// <param name="projInfo">A ProjectionInfo class contains all the standard and custom parameters needed to initialize this transform</param> protected override void OnInit(ProjectionInfo projInfo) { double phip0; _hlfE = 0.5 * E; double cp = Math.Cos(Phi0); cp *= cp; _c = Math.Sqrt(1 + Es * cp * cp * ROneEs); double sp = Math.Sin(Phi0); _cosp0 = Math.Cos(phip0 = Proj.Aasin(_sinp0 = sp / _c)); sp *= E; _k = Math.Log(Math.Tan(FORT_PI + 0.5 * phip0)) - _c * ( Math.Log(Math.Tan(FORT_PI + 0.5 * Phi0)) - _hlfE * Math.Log((1 + sp) / (1 - sp))); _kR = K0 * Math.Sqrt(OneEs) / (1 - sp * sp); }
/// <inheritdoc /> protected override void OnForward(double[] lp, double[] xy, int startIndex, int numPoints) { for (int i = startIndex; i < startIndex + numPoints; i++) { int phi = i * 2 + PHI; int lam = i * 2 + LAMBDA; int x = i * 2 + X; int y = i * 2 + Y; double sp = E * Math.Sin(lp[phi]); double phip = 2 * Math.Atan(Math.Exp(_c * ( Math.Log(Math.Tan(FORT_PI + 0.5 * lp[phi])) - _hlfE * Math.Log((1 + sp) / (1 - sp))) + _k)) - HALF_PI; double lamp = _c * lp[lam]; double cp = Math.Cos(phip); double phipp = Proj.Aasin(_cosp0 * Math.Sin(phip) - _sinp0 * cp * Math.Cos(lamp)); double lampp = Proj.Aasin(cp * Math.Sin(lamp) / Math.Cos(phipp)); xy[x] = _kR * lampp; xy[y] = _kR * Math.Log(Math.Tan(FORT_PI + 0.5 * phipp)); } }
/// <inheritdoc /> protected override void OnInverse(double[] xy, double[] lp, int startIndex, int numPoints) { for (int i = startIndex; i < startIndex + numPoints; i++) { int phi = i * 2 + PHI; int lam = i * 2 + LAMBDA; int x = i * 2 + X; int y = i * 2 + Y; xy[y] /= _cY; double c = Math.Cos(lp[phi] = _tanMode ? Math.Atan(xy[y]) : Proj.Aasin(xy[y])); lp[phi] /= _cP; lp[lam] = xy[x] / (_cX * Math.Cos(lp[phi] /= _cP)); if (_tanMode) { lp[lam] /= c * c; } else { lp[lam] *= c; } } }
/// <inheritdoc /> protected override void OnInverse(double[] xy, double[] lp, int startIndex, int numPoints) { for (int i = startIndex; i < startIndex + numPoints; i++) { int phi = i * 2 + PHI; int lam = i * 2 + LAMBDA; int x = i * 2 + X; int y = i * 2 + Y; int j; double phipp = 2 * (Math.Atan(Math.Exp(xy[y] / _kR)) - FORT_PI); double lampp = xy[x] / _kR; double cp = Math.Cos(phipp); double phip = Proj.Aasin(_cosp0 * Math.Sin(phipp) + _sinp0 * cp * Math.Cos(lampp)); double lamp = Proj.Aasin(cp * Math.Sin(lampp) / Math.Cos(phip)); double con = (_k - Math.Log(Math.Tan(FORT_PI + 0.5 * phip))) / _c; for (j = NITER; j > 0; --j) { double esp = E * Math.Sin(phip); double delp = (con + Math.Log(Math.Tan(FORT_PI + 0.5 * phip)) - _hlfE * Math.Log((1 + esp) / (1 - esp))) * (1 - esp * esp) * Math.Cos(phip) * ROneEs; phip -= delp; if (Math.Abs(delp) < EPS) { break; } } if (j <= 0) { lp[lam] = double.NaN; lp[phi] = double.NaN; continue; //ProjectionException(20); } lp[phi] = phip; lp[lam] = lamp / _c; } }
/// <summary> /// Initializes the transform using the parameters from the specified coordinate system information /// </summary> /// <param name="projInfo">A ProjectionInfo class contains all the standard and custom parameters needed to initialize this transform</param> protected override void OnInit(ProjectionInfo projInfo) { double pp; /* get control point locations */ double phi1 = projInfo.Phi1; double lam1 = projInfo.Lam1; double phi2 = projInfo.Phi2; double lam2 = projInfo.Lam2; if (phi1 == phi2 && lam1 == lam2) { throw new ProjectionException(-25); } Lam0 = Proj.Adjlon(0.5 * (lam1 + lam2)); _dlam2 = Proj.Adjlon(lam2 - lam1); _cp1 = Math.Cos(phi1); _cp2 = Math.Cos(phi2); _sp1 = Math.Sin(phi1); _sp2 = Math.Sin(phi2); _cs = _cp1 * _sp2; _sc = _sp1 * _cp2; _ccs = _cp1 * _cp2 * Math.Sin(_dlam2); _z02 = Proj.Aacos(_sp1 * _sp2 + _cp1 * _cp2 * Math.Cos(_dlam2)); _hz0 = .5 * _z02; double a12 = Math.Atan2(_cp2 * Math.Sin(_dlam2), _cp1 * _sp2 - _sp1 * _cp2 * Math.Cos(_dlam2)); _ca = Math.Cos(pp = Proj.Aasin(_cp1 * Math.Sin(a12))); _sa = Math.Sin(pp); _lp = Proj.Adjlon(Math.Atan2(_cp1 * Math.Cos(a12), _sp1) - _hz0); _dlam2 *= .5; _lamc = HALF_PI - Math.Atan2(Math.Sin(a12) * _sp1, Math.Cos(a12)) - _dlam2; _thz0 = Math.Tan(_hz0); _rhshz0 = .5 / Math.Sin(_hz0); _r2Z0 = 0.5 / _z02; _z02 *= _z02; }