/** * \file NETGeographicLib/Ellipsoid.h * \brief Header for NETGeographicLib::Ellipsoid class * * NETGeographicLib is copyright (c) Scott Heiman (2013) * GeographicLib is Copyright (c) Charles Karney (2010-2012) * and licensed under the MIT/X11 License. * For more information, see * https://geographiclib.sourceforge.io/ **********************************************************************/ #pragma once namespace NETGeographicLib { /** * \brief .NET wrapper for GeographicLib::Ellipsoid. * * This class allows .NET applications to access GeographicLib::Ellipsoid. * * This class returns various properties of the ellipsoid and converts * between various types of latitudes. The latitude conversions are also * possible using the various projections supported by %GeographicLib; but * Ellipsoid provides more direct access (sometimes using private functions * of the projection classes). Ellipsoid::RectifyingLatitude, * Ellipsoid::InverseRectifyingLatitude, and Ellipsoid::MeridianDistance * provide functionality which can be provided by the Geodesic class. * However Geodesic uses a series approximation (valid for abs \e f < 1/150), * whereas Ellipsoid computes these quantities using EllipticFunction which * provides accurate results even when \e f is large. Use of this class * should be limited to −3 < \e f < 3/4 (i.e., 1/4 < b/a < 4). * * C# Example: * \include example-Ellipsoid.cs * Managed C++ Example: * \include example-Ellipsoid.cpp * Visual Basic Example: * \include example-Ellipsoid.vb * * INTERFACE DIFFERENCES:
* A default constructor has been provided that assumes a WGS84 ellipsoid. * * The following functions are implemented as properties: * EquatorialRadius, MinorRadius, QuarterMeridian, Area, Volume, Flattening, * SecondFlattening, ThirdFlattening, EccentricitySq, SecondEccentricitySq, * and ThirdEccentricitySq. **********************************************************************/ public ref class Ellipsoid { private: // A pointer to the unmanaged GeographicLib::Ellipsoid GeographicLib::Ellipsoid* m_pEllipsoid; // The finalizer frees the unmanaged memory when the object is destroyed. !Ellipsoid(); public: /** \name Constructor **********************************************************************/ ///@{ /** * Constructor for a WGS84 ellipsoid **********************************************************************/ Ellipsoid(); /** * Constructor for a ellipsoid with * * @param[in] a equatorial radius (meters). * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere. * Negative \e f gives a prolate ellipsoid. * @exception GeographicErr if \e a or (1 − \e f ) \e a is not * positive. **********************************************************************/ Ellipsoid(double a, double f); ///@} /** The destructor calls the finalizer. **********************************************************************/ ~Ellipsoid() { this->!Ellipsoid(); } /** \name %Ellipsoid dimensions. **********************************************************************/ ///@{ /** * @return \e a the equatorial radius of the ellipsoid (meters). This is * the value used in the constructor. **********************************************************************/ property double EquatorialRadius { double get(); } /** * @return \e b the polar semi-axis (meters). **********************************************************************/ property double MinorRadius { double get(); } /** * @return \e L the distance between the equator and a pole along a * meridian (meters). For a sphere \e L = (π/2) \e a. The radius * of a sphere with the same meridian length is \e L / (π/2). **********************************************************************/ property double QuarterMeridian { double get(); } /** * @return \e A the total area of the ellipsoid (meters2). For * a sphere \e A = 4π a2. The radius of a sphere * with the same area is sqrt(\e A / (4π)). **********************************************************************/ property double Area { double get(); } /** * @return \e V the total volume of the ellipsoid (meters3). * For a sphere \e V = (4π / 3) a3. The radius of * a sphere with the same volume is cbrt(\e V / (4π/3)). **********************************************************************/ property double Volume { double get(); } ///@} /** \name %Ellipsoid shape **********************************************************************/ ///@{ /** * @return \e f = (\e a − \e b) / \e a, the flattening of the * ellipsoid. This is the value used in the constructor. This is zero, * positive, or negative for a sphere, oblate ellipsoid, or prolate * ellipsoid. **********************************************************************/ property double Flattening { double get(); } /** * @return \e f ' = (\e a − \e b) / \e b, the second flattening of * the ellipsoid. This is zero, positive, or negative for a sphere, * oblate ellipsoid, or prolate ellipsoid. **********************************************************************/ property double SecondFlattening { double get(); } /** * @return \e n = (\e a − \e b) / (\e a + \e b), the third flattening * of the ellipsoid. This is zero, positive, or negative for a sphere, * oblate ellipsoid, or prolate ellipsoid. **********************************************************************/ property double ThirdFlattening { double get(); } /** * @return e2 = (a2 − * b2) / a2, the eccentricity squared * of the ellipsoid. This is zero, positive, or negative for a sphere, * oblate ellipsoid, or prolate ellipsoid. **********************************************************************/ property double EccentricitySq { double get(); } /** * @return e' 2 = (a2 − * b2) / b2, the second eccentricity * squared of the ellipsoid. This is zero, positive, or negative for a * sphere, oblate ellipsoid, or prolate ellipsoid. **********************************************************************/ property double SecondEccentricitySq { double get(); } /** * @return e'' 2 = (a2 − * b2) / (a2 + b2), * the third eccentricity squared of the ellipsoid. This is zero, * positive, or negative for a sphere, oblate ellipsoid, or prolate * ellipsoid. **********************************************************************/ property double ThirdEccentricitySq { double get(); } ///@} /** \name Latitude conversion. **********************************************************************/ ///@{ /** * @param[in] phi the geographic latitude (degrees). * @return β the parametric latitude (degrees). * * The geographic latitude, φ, is the angle beween the equatorial * plane and a vector normal to the surface of the ellipsoid. * * The parametric latitude (also called the reduced latitude), β, * allows the cartesian coordinated of a meridian to be expressed * conveniently in parametric form as * - \e R = \e a cos β * - \e Z = \e b sin β * . * where \e a and \e b are the equatorial radius and the polar semi-axis. * For a sphere β = φ. * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * β lies in [−90°, 90°]. **********************************************************************/ double ParametricLatitude(double phi); /** * @param[in] beta the parametric latitude (degrees). * @return φ the geographic latitude (degrees). * * β must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * φ lies in [−90°, 90°]. **********************************************************************/ double InverseParametricLatitude(double beta); /** * @param[in] phi the geographic latitude (degrees). * @return θ the geocentric latitude (degrees). * * The geocentric latitude, θ, is the angle beween the equatorial * plane and a line between the center of the ellipsoid and a point on the * ellipsoid. For a sphere θ = φ. * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * θ lies in [−90°, 90°]. **********************************************************************/ double GeocentricLatitude(double phi); /** * @param[in] theta the geocentric latitude (degrees). * @return φ the geographic latitude (degrees). * * θ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * φ lies in [−90°, 90°]. **********************************************************************/ double InverseGeocentricLatitude(double theta); /** * @param[in] phi the geographic latitude (degrees). * @return μ the rectifying latitude (degrees). * * The rectifying latitude, μ, has the property that the distance along * a meridian of the ellipsoid between two points with rectifying latitudes * μ1 and μ2 is equal to * (μ2 - μ1) \e L / 90°, * where \e L = QuarterMeridian(). For a sphere μ = φ. * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * μ lies in [−90°, 90°]. **********************************************************************/ double RectifyingLatitude(double phi); /** * @param[in] mu the rectifying latitude (degrees). * @return φ the geographic latitude (degrees). * * μ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * φ lies in [−90°, 90°]. **********************************************************************/ double InverseRectifyingLatitude(double mu); /** * @param[in] phi the geographic latitude (degrees). * @return ξ the authalic latitude (degrees). * * The authalic latitude, ξ, has the property that the area of the * ellipsoid between two circles with authalic latitudes * ξ1 and ξ2 is equal to (sin * ξ2 - sin ξ1) \e A / 2, where \e A * = Area(). For a sphere ξ = φ. * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * ξ lies in [−90°, 90°]. **********************************************************************/ double AuthalicLatitude(double phi); /** * @param[in] xi the authalic latitude (degrees). * @return φ the geographic latitude (degrees). * * ξ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * φ lies in [−90°, 90°]. **********************************************************************/ double InverseAuthalicLatitude(double xi); /** * @param[in] phi the geographic latitude (degrees). * @return χ the conformal latitude (degrees). * * The conformal latitude, χ, gives the mapping of the ellipsoid to a * sphere which which is conformal (angles are preserved) and in which the * equator of the ellipsoid maps to the equator of the sphere. For a * sphere χ = φ. * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * χ lies in [−90°, 90°]. **********************************************************************/ double ConformalLatitude(double phi); /** * @param[in] chi the conformal latitude (degrees). * @return φ the geographic latitude (degrees). * * χ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. The returned value * φ lies in [−90°, 90°]. **********************************************************************/ double InverseConformalLatitude(double chi); /** * @param[in] phi the geographic latitude (degrees). * @return ψ the isometric latitude (degrees). * * The isometric latitude gives the mapping of the ellipsoid to a plane * which which is conformal (angles are preserved) and in which the equator * of the ellipsoid maps to a straight line of constant scale; this mapping * defines the Mercator projection. For a sphere ψ = * sinh−1 tan φ. * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. **********************************************************************/ double IsometricLatitude(double phi); /** * @param[in] psi the isometric latitude (degrees). * @return φ the geographic latitude (degrees). * * The returned value φ lies in [−90°, 90°]. **********************************************************************/ double InverseIsometricLatitude(double psi); ///@} /** \name Other quantities. **********************************************************************/ ///@{ /** * @param[in] phi the geographic latitude (degrees). * @return \e R = \e a cos β the radius of a circle of latitude * φ (meters). \e R (π/180°) gives meters per degree * longitude measured along a circle of latitude. * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. **********************************************************************/ double CircleRadius(double phi); /** * @param[in] phi the geographic latitude (degrees). * @return \e Z = \e b sin β the distance of a circle of latitude * φ from the equator measured parallel to the ellipsoid axis * (meters). * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. **********************************************************************/ double CircleHeight(double phi); /** * @param[in] phi the geographic latitude (degrees). * @return \e s the distance along a meridian * between the equator and a point of latitude φ (meters). \e s is * given by \e s = μ \e L / 90°, where \e L = * QuarterMeridian()). * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. **********************************************************************/ double MeridianDistance(double phi); /** * @param[in] phi the geographic latitude (degrees). * @return ρ the meridional radius of curvature of the ellipsoid at * latitude φ (meters); this is the curvature of the meridian. \e * rho is given by ρ = (180°/π) d\e s / dφ, * where \e s = MeridianDistance(); thus ρ (π/180°) * gives meters per degree latitude measured along a meridian. * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. **********************************************************************/ double MeridionalCurvatureRadius(double phi); /** * @param[in] phi the geographic latitude (degrees). * @return ν the transverse radius of curvature of the ellipsoid at * latitude φ (meters); this is the curvature of a curve on the * ellipsoid which also lies in a plane perpendicular to the ellipsoid * and to the meridian. ν is related to \e R = CircleRadius() by \e * R = ν cos φ. * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. **********************************************************************/ double TransverseCurvatureRadius(double phi); /** * @param[in] phi the geographic latitude (degrees). * @param[in] azi the angle between the meridian and the normal section * (degrees). * @return the radius of curvature of the ellipsoid in the normal * section at latitude φ inclined at an angle \e azi to the * meridian (meters). * * φ must lie in the range [−90°, 90°]; the * result is undefined if this condition does not hold. **********************************************************************/ double NormalCurvatureRadius(double phi, double azi); ///@} /** \name Eccentricity conversions. **********************************************************************/ ///@{ /** * @param[in] fp = \e f ' = (\e a − \e b) / \e b, the second * flattening. * @return \e f = (\e a − \e b) / \e a, the flattening. * * \e f ' should lie in (−1, ∞). * The returned value \e f lies in (−∞, 1). **********************************************************************/ static double SecondFlatteningToFlattening(double fp); /** * @param[in] f = (\e a − \e b) / \e a, the flattening. * @return \e f ' = (\e a − \e b) / \e b, the second flattening. * * \e f should lie in (−∞, 1). * The returned value \e f ' lies in (−1, ∞). **********************************************************************/ static double FlatteningToSecondFlattening(double f); /** * @param[in] n = (\e a − \e b) / (\e a + \e b), the third * flattening. * @return \e f = (\e a − \e b) / \e a, the flattening. * * \e n should lie in (−1, 1). * The returned value \e f lies in (−∞, 1). **********************************************************************/ static double ThirdFlatteningToFlattening(double n); /** * @param[in] f = (\e a − \e b) / \e a, the flattening. * @return \e n = (\e a − \e b) / (\e a + \e b), the third * flattening. * * \e f should lie in (−∞, 1). * The returned value \e n lies in (−1, 1). **********************************************************************/ static double FlatteningToThirdFlattening(double f); /** * @param[in] e2 = e2 = (a2 − * b2) / a2, the eccentricity * squared. * @return \e f = (\e a − \e b) / \e a, the flattening. * * e2 should lie in (−∞, 1). * The returned value \e f lies in (−∞, 1). **********************************************************************/ static double EccentricitySqToFlattening(double e2); /** * @param[in] f = (\e a − \e b) / \e a, the flattening. * @return e2 = (a2 − * b2) / a2, the eccentricity * squared. * * \e f should lie in (−∞, 1). * The returned value e2 lies in (−∞, 1). **********************************************************************/ static double FlatteningToEccentricitySq(double f); /** * @param[in] ep2 = e' 2 = (a2 − * b2) / b2, the second eccentricity * squared. * @return \e f = (\e a − \e b) / \e a, the flattening. * * e' 2 should lie in (−1, ∞). * The returned value \e f lies in (−∞, 1). **********************************************************************/ static double SecondEccentricitySqToFlattening(double ep2); /** * @param[in] f = (\e a − \e b) / \e a, the flattening. * @return e' 2 = (a2 − * b2) / b2, the second eccentricity * squared. * * \e f should lie in (−∞, 1). * The returned value e' 2 lies in (−1, ∞). **********************************************************************/ static double FlatteningToSecondEccentricitySq(double f); /** * @param[in] epp2 = e'' 2 = (a2 * − b2) / (a2 + * b2), the third eccentricity squared. * @return \e f = (\e a − \e b) / \e a, the flattening. * * e'' 2 should lie in (−1, 1). * The returned value \e f lies in (−∞, 1). **********************************************************************/ static double ThirdEccentricitySqToFlattening(double epp2); /** * @param[in] f = (\e a − \e b) / \e a, the flattening. * @return e'' 2 = (a2 − * b2) / (a2 + b2), * the third eccentricity squared. * * \e f should lie in (−∞, 1). * The returned value e'' 2 lies in (−1, 1). **********************************************************************/ static double FlatteningToThirdEccentricitySq(double f); }; } // namespace NETGeographicLib