public override Coordinate ProjectInverse(double x, double y, Coordinate lp)
        {
            if (Spherical)
            {
                double t;

                if ((t = Math.Abs(y *= ScaleFactor)) - EPS10 <= 1.0)
                {
                    if (t >= 1.0)
                    {
                        lp.Y = y < 0.0 ? -ProjectionMath.PiHalf : ProjectionMath.PiHalf;
                    }
                    else
                    {
                        lp.Y = Math.Asin(y);
                    }
                    lp.X = x / ScaleFactor;
                }
                else
                {
                    throw new ProjectionException();
                }
            }
            else
            {
                lp.Y = ProjectionMath.AuthLat(Math.Asin(2.0 * y * ScaleFactor / _qp), _apa);
                lp.X = x / ScaleFactor;
            }
            return(lp);
        }
        protected void ProjectInverseNonSpherical(double xyx, double xyy, Coordinate dst)
        {
            double lpphi, lplam;
            double cCe, sCe, q, rho, ab = 0.0;

            switch (mode)
            {
            case AzimuthalMode.Equator:
            case AzimuthalMode.Oblique:
                if ((rho = ProjectionMath.Hypot(xyx /= dd, xyy *= dd)) < EPS10)
                {
                    lplam = 0.0;
                    lpphi = phi0;
                    dst.X = lplam;
                    dst.Y = lpphi;
                    return;
                }
                cCe  = Math.Cos(sCe = 2.0 * Math.Asin(.5 * rho / rq));
                xyx *= (sCe = Math.Sin(sCe));
                if (mode == AzimuthalMode.Oblique)
                {
                    q   = qp * (ab = cCe * sinb1 + xyy * sCe * cosb1 / rho);
                    xyy = rho * cosb1 * cCe - xyy * sinb1 * sCe;
                }
                else
                {
                    q   = qp * (ab = xyy * sCe / rho);
                    xyy = rho * cCe;
                }
                break;

            case AzimuthalMode.NorthPole:
            case AzimuthalMode.SouthPole:
                if (mode == AzimuthalMode.NorthPole)
                {
                    xyy = -xyy;
                }
                if (0 == (q = (xyx * xyx + xyy * xyy)))
                {
                    lplam = 0.0;
                    lpphi = phi0;
                    dst.X = lplam;
                    dst.Y = lpphi;
                    return;
                }

                /*
                 * q = P->qp - q;
                 */
                ab = 1.0 - q / qp;
                if (mode == AzimuthalMode.SouthPole)
                {
                    ab = -ab;
                }
                break;
            }
            lplam = Math.Atan2(xyx, xyy);
            lpphi = ProjectionMath.AuthLat(Math.Asin(ab), apa);
            dst.X = lplam;
            dst.Y = lpphi;
        }
        public ProjCoordinate projectInverse(double x, double y, ProjCoordinate lp)
        {
            if (Spherical)
            {
                double cosz = 0, rh, sinz = 0;

                rh = ProjectionMath.Distance(x, y);
                if ((lp.Y = rh * .5) > 1.0)
                {
                    throw new ProjectionException();
                }
                lp.Y = 2.0 * Math.Asin(lp.Y);
                if (Mode == AzimuthalMode.Oblique || Mode == AzimuthalMode.Equator)
                {
                    sinz = Math.Sin(lp.Y);
                    cosz = Math.Cos(lp.Y);
                }
                switch (Mode)
                {
                case AzimuthalMode.Equator:
                    lp.Y = Math.Abs(rh) <= EPS10 ? 0.0 : Math.Asin(y * sinz / rh);
                    x   *= sinz;
                    y    = cosz * rh;
                    break;

                case AzimuthalMode.Oblique:
                    lp.Y = Math.Abs(rh) <= EPS10 ? ProjectionLatitude :
                           Math.Asin(cosz * _sinphi0 + y * sinz * _cosphi0 / rh);
                    x *= sinz * _cosphi0;
                    y  = (cosz - Math.Sin(lp.Y) * _sinphi0) * rh;
                    break;

                case AzimuthalMode.NorthPole:
                    y    = -y;
                    lp.Y = ProjectionMath.PiHalf - lp.Y;
                    break;

                case AzimuthalMode.SouthPole:
                    lp.Y -= ProjectionMath.PiHalf;
                    break;
                }
                lp.X = (y == 0.0 && (Mode == AzimuthalMode.Equator || Mode == AzimuthalMode.Oblique)) ?
                       0.0 : Math.Atan2(x, y);
            }
            else
            {
                double cCe, sCe, q, rho, ab = 0;

                switch (Mode)
                {
                case AzimuthalMode.Equator:
                case AzimuthalMode.Oblique:
                    if ((rho = ProjectionMath.Distance(x /= _dd, y *= _dd)) < EPS10)
                    {
                        lp.X = 0.0;
                        lp.Y = ProjectionLatitude;
                        return(lp);
                    }
                    cCe = Math.Cos(sCe = 2.0 * Math.Asin(.5 * rho / _rq));
                    x  *= (sCe = Math.Sin(sCe));
                    if (Mode == AzimuthalMode.Oblique)
                    {
                        q = _qp * (ab = cCe * _sinb1 + y * sCe * _cosb1 / rho);
                        y = rho * _cosb1 * cCe - y * _sinb1 * sCe;
                    }
                    else
                    {
                        q = _qp * (ab = y * sCe / rho);
                        y = rho * cCe;
                    }
                    break;

                case AzimuthalMode.NorthPole:
                case AzimuthalMode.SouthPole:
                    if (Mode == AzimuthalMode.NorthPole)
                    {
                        y = -y;
                    }
                    if ((q = (x * x + y * y)) == 0)
                    {
                        lp.X = 0.0;
                        lp.Y = ProjectionLatitude;
                        return(lp);
                    }
                    ab = 1.0 - q / _qp;
                    if (Mode == AzimuthalMode.SouthPole)
                    {
                        ab = -ab;
                    }
                    break;
                }
                lp.X = Math.Atan2(x, y);
                lp.Y = ProjectionMath.AuthLat(Math.Asin(ab), _apa);
            }
            return(lp);
        }