// Input argument: the center of the projection
        public GnomonicProjection(Dictionary <String, double> parameters)
            : base(parameters)
        {
            _center = SpatialUtil.SphericalRadToCartesian(InputLatitude("latitude1", 90), InputLongitude("longitude1", 360));

            // This projection is designed for numerical computations rather than cartography.
            // The choice of coordinate basis for the tangent plane - which affects the
            // orientation of the projection in the xy plane - is optimized for accuracy rather
            // than good looks. The first basis vector is obtained by dropping the smallest coordinate,
            // switching the other two, and flipping the sign of one of them. The second one is
            // obtained by cross product.

            double[] center = { _center.X, _center.Y, _center.Z };
            var      vector = new double[3];

            var k = GetMinEntry(center);
            var j = (k + 2) % 3;
            var i = (j + 2) % 3;

            vector[i] = -center[j];
            vector[j] = center[i];
            vector[k] = 0;

            _xAxis = new Vector3(vector[0], vector[1], vector[2]).Unitize();

            _yAxis = _center.CrossProduct(_xAxis);
        }
        protected internal override void Project(double latitude, double longitude, out double x, out double y)
        {
            var vector = SpatialUtil.SphericalRadToCartesian(latitude, longitude);
            var r      = vector * _center;

            if (r < _tolerance)
            {
                throw new ArgumentOutOfRangeException(nameof(latitude), "Input point is too far away from the center of projection.");
            }
            vector = vector / r;

            x = vector * _xAxis;
            y = vector * _yAxis;
        }