00001 /** 00002 * \file NETGeographicLib/Ellipsoid.h 00003 * \brief Header for NETGeographicLib::Ellipsoid class 00004 * 00005 * NETGeographicLib is copyright (c) Scott Heiman (2013) 00006 * GeographicLib is Copyright (c) Charles Karney (2010-2012) 00007 * <charles@karney.com> and licensed under the MIT/X11 License. 00008 * For more information, see 00009 * http://geographiclib.sourceforge.net/ 00010 **********************************************************************/ 00011 #pragma once 00012 00013 namespace NETGeographicLib 00014 { 00015 /** 00016 * \brief .NET wrapper for GeographicLib::Ellipsoid. 00017 * 00018 * This class allows .NET applications to access GeographicLib::Ellipsoid. 00019 * 00020 * This class returns various properties of the ellipsoid and converts 00021 * between various types of latitudes. The latitude conversions are also 00022 * possible using the various projections supported by %GeographicLib; but 00023 * Ellipsoid provides more direct access (sometimes using private functions 00024 * of the projection classes). Ellipsoid::RectifyingLatitude, 00025 * Ellipsoid::InverseRectifyingLatitude, and Ellipsoid::MeridianDistance 00026 * provide functionality which can be provided by the Geodesic class. 00027 * However Geodesic uses a series approximation (valid for abs \e f < 1/150), 00028 * whereas Ellipsoid computes these quantities using EllipticFunction which 00029 * provides accurate results even when \e f is large. Use of this class 00030 * should be limited to −3 < \e f < 3/4 (i.e., 1/4 < b/a < 4). 00031 * 00032 * C# Example: 00033 * \include example-Ellipsoid.cs 00034 * Managed C++ Example: 00035 * \include example-Ellipsoid.cpp 00036 * Visual Basic Example: 00037 * \include example-Ellipsoid.vb 00038 * 00039 * <B>INTERFACE DIFFERENCES:</B><BR> 00040 * A default constructor has been provided that assumes a WGS84 ellipsoid. 00041 * 00042 * The following functions are implemented as properties: 00043 * MajorRadius, MinorRadius, QuarterMeridian, Area, Volume, Flattening, 00044 * SecondFlattening, ThirdFlattening, EccentricitySq, SecondEccentricitySq, 00045 * and ThirdEccentricitySq. 00046 **********************************************************************/ 00047 public ref class Ellipsoid 00048 { 00049 private: 00050 // A pointer to the unmanaged GeographicLib::Ellipsoid 00051 GeographicLib::Ellipsoid* m_pEllipsoid; 00052 00053 // The finalizer frees the unmanaged memory when the object is destroyed. 00054 !Ellipsoid(); 00055 public: 00056 /** \name Constructor 00057 **********************************************************************/ 00058 ///@{ 00059 00060 /** 00061 * Constructor for a WGS84 ellipsoid 00062 **********************************************************************/ 00063 Ellipsoid(); 00064 00065 /** 00066 * Constructor for a ellipsoid with 00067 * 00068 * @param[in] a equatorial radius (meters). 00069 * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere. 00070 * Negative \e f gives a prolate ellipsoid. If \e f > 1, set flattening 00071 * to 1/\e f. 00072 * @exception GeographicErr if \e a or (1 − \e f ) \e a is not 00073 * positive. 00074 **********************************************************************/ 00075 Ellipsoid(double a, double f); 00076 ///@} 00077 00078 /** The destructor calls the finalizer. 00079 **********************************************************************/ 00080 ~Ellipsoid() 00081 { this->!Ellipsoid(); } 00082 00083 /** \name %Ellipsoid dimensions. 00084 **********************************************************************/ 00085 ///@{ 00086 00087 /** 00088 * @return \e a the equatorial radius of the ellipsoid (meters). This is 00089 * the value used in the constructor. 00090 **********************************************************************/ 00091 property double MajorRadius { double get(); } 00092 00093 /** 00094 * @return \e b the polar semi-axis (meters). 00095 **********************************************************************/ 00096 property double MinorRadius { double get(); } 00097 00098 /** 00099 * @return \e L the distance between the equator and a pole along a 00100 * meridian (meters). For a sphere \e L = (π/2) \e a. The radius 00101 * of a sphere with the same meridian length is \e L / (π/2). 00102 **********************************************************************/ 00103 property double QuarterMeridian { double get(); } 00104 00105 /** 00106 * @return \e A the total area of the ellipsoid (meters<sup>2</sup>). For 00107 * a sphere \e A = 4π <i>a</i><sup>2</sup>. The radius of a sphere 00108 * with the same area is sqrt(\e A / (4π)). 00109 **********************************************************************/ 00110 property double Area { double get(); } 00111 00112 /** 00113 * @return \e V the total volume of the ellipsoid (meters<sup>3</sup>). 00114 * For a sphere \e V = (4π / 3) <i>a</i><sup>3</sup>. The radius of 00115 * a sphere with the same volume is cbrt(\e V / (4π/3)). 00116 **********************************************************************/ 00117 property double Volume { double get(); } 00118 ///@} 00119 00120 /** \name %Ellipsoid shape 00121 **********************************************************************/ 00122 ///@{ 00123 00124 /** 00125 * @return \e f = (\e a − \e b) / \e a, the flattening of the 00126 * ellipsoid. This is the value used in the constructor. This is zero, 00127 * positive, or negative for a sphere, oblate ellipsoid, or prolate 00128 * ellipsoid. 00129 **********************************************************************/ 00130 property double Flattening { double get(); } 00131 00132 /** 00133 * @return \e f ' = (\e a − \e b) / \e b, the second flattening of 00134 * the ellipsoid. This is zero, positive, or negative for a sphere, 00135 * oblate ellipsoid, or prolate ellipsoid. 00136 **********************************************************************/ 00137 property double SecondFlattening { double get(); } 00138 00139 /** 00140 * @return \e n = (\e a − \e b) / (\e a + \e b), the third flattening 00141 * of the ellipsoid. This is zero, positive, or negative for a sphere, 00142 * oblate ellipsoid, or prolate ellipsoid. 00143 **********************************************************************/ 00144 property double ThirdFlattening { double get(); } 00145 00146 /** 00147 * @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> − 00148 * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity squared 00149 * of the ellipsoid. This is zero, positive, or negative for a sphere, 00150 * oblate ellipsoid, or prolate ellipsoid. 00151 **********************************************************************/ 00152 property double EccentricitySq { double get(); } 00153 00154 /** 00155 * @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> − 00156 * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentricity 00157 * squared of the ellipsoid. This is zero, positive, or negative for a 00158 * sphere, oblate ellipsoid, or prolate ellipsoid. 00159 **********************************************************************/ 00160 property double SecondEccentricitySq { double get(); } 00161 00162 /** 00163 * @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> − 00164 * <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</sup>), 00165 * the third eccentricity squared of the ellipsoid. This is zero, 00166 * positive, or negative for a sphere, oblate ellipsoid, or prolate 00167 * ellipsoid. 00168 **********************************************************************/ 00169 property double ThirdEccentricitySq { double get(); } 00170 ///@} 00171 00172 /** \name Latitude conversion. 00173 **********************************************************************/ 00174 ///@{ 00175 00176 /** 00177 * @param[in] phi the geographic latitude (degrees). 00178 * @return β the parametric latitude (degrees). 00179 * 00180 * The geographic latitude, φ, is the angle beween the equatorial 00181 * plane and a vector normal to the surface of the ellipsoid. 00182 * 00183 * The parametric latitude (also called the reduced latitude), β, 00184 * allows the cartesian coordinated of a meridian to be expressed 00185 * conveniently in parametric form as 00186 * - \e R = \e a cos β 00187 * - \e Z = \e b sin β 00188 * . 00189 * where \e a and \e b are the equatorial radius and the polar semi-axis. 00190 * For a sphere β = φ. 00191 * 00192 * φ must lie in the range [−90°, 90°]; the 00193 * result is undefined if this condition does not hold. The returned value 00194 * β lies in [−90°, 90°]. 00195 **********************************************************************/ 00196 double ParametricLatitude(double phi); 00197 00198 /** 00199 * @param[in] beta the parametric latitude (degrees). 00200 * @return φ the geographic latitude (degrees). 00201 * 00202 * β must lie in the range [−90°, 90°]; the 00203 * result is undefined if this condition does not hold. The returned value 00204 * φ lies in [−90°, 90°]. 00205 **********************************************************************/ 00206 double InverseParametricLatitude(double beta); 00207 00208 /** 00209 * @param[in] phi the geographic latitude (degrees). 00210 * @return θ the geocentric latitude (degrees). 00211 * 00212 * The geocentric latitude, θ, is the angle beween the equatorial 00213 * plane and a line between the center of the ellipsoid and a point on the 00214 * ellipsoid. For a sphere θ = φ. 00215 * 00216 * φ must lie in the range [−90°, 90°]; the 00217 * result is undefined if this condition does not hold. The returned value 00218 * θ lies in [−90°, 90°]. 00219 **********************************************************************/ 00220 double GeocentricLatitude(double phi); 00221 00222 /** 00223 * @param[in] theta the geocentric latitude (degrees). 00224 * @return φ the geographic latitude (degrees). 00225 * 00226 * θ must lie in the range [−90°, 90°]; the 00227 * result is undefined if this condition does not hold. The returned value 00228 * φ lies in [−90°, 90°]. 00229 **********************************************************************/ 00230 double InverseGeocentricLatitude(double theta); 00231 00232 /** 00233 * @param[in] phi the geographic latitude (degrees). 00234 * @return μ the rectifying latitude (degrees). 00235 * 00236 * The rectifying latitude, μ, has the property that the distance along 00237 * a meridian of the ellipsoid between two points with rectifying latitudes 00238 * μ<sub>1</sub> and μ<sub>2</sub> is equal to 00239 * (μ<sub>2</sub> - μ<sub>1</sub>) \e L / 90°, 00240 * where \e L = QuarterMeridian(). For a sphere μ = φ. 00241 * 00242 * φ must lie in the range [−90°, 90°]; the 00243 * result is undefined if this condition does not hold. The returned value 00244 * μ lies in [−90°, 90°]. 00245 **********************************************************************/ 00246 double RectifyingLatitude(double phi); 00247 00248 /** 00249 * @param[in] mu the rectifying latitude (degrees). 00250 * @return φ the geographic latitude (degrees). 00251 * 00252 * μ must lie in the range [−90°, 90°]; the 00253 * result is undefined if this condition does not hold. The returned value 00254 * φ lies in [−90°, 90°]. 00255 **********************************************************************/ 00256 double InverseRectifyingLatitude(double mu); 00257 00258 /** 00259 * @param[in] phi the geographic latitude (degrees). 00260 * @return ξ the authalic latitude (degrees). 00261 * 00262 * The authalic latitude, ξ, has the property that the area of the 00263 * ellipsoid between two circles with authalic latitudes 00264 * ξ<sub>1</sub> and ξ<sub>2</sub> is equal to (sin 00265 * ξ<sub>2</sub> - sin ξ<sub>1</sub>) \e A / 2, where \e A 00266 * = Area(). For a sphere ξ = φ. 00267 * 00268 * φ must lie in the range [−90°, 90°]; the 00269 * result is undefined if this condition does not hold. The returned value 00270 * ξ lies in [−90°, 90°]. 00271 **********************************************************************/ 00272 double AuthalicLatitude(double phi); 00273 00274 /** 00275 * @param[in] xi the authalic latitude (degrees). 00276 * @return φ the geographic latitude (degrees). 00277 * 00278 * ξ must lie in the range [−90°, 90°]; the 00279 * result is undefined if this condition does not hold. The returned value 00280 * φ lies in [−90°, 90°]. 00281 **********************************************************************/ 00282 double InverseAuthalicLatitude(double xi); 00283 00284 /** 00285 * @param[in] phi the geographic latitude (degrees). 00286 * @return χ the conformal latitude (degrees). 00287 * 00288 * The conformal latitude, χ, gives the mapping of the ellipsoid to a 00289 * sphere which which is conformal (angles are preserved) and in which the 00290 * equator of the ellipsoid maps to the equator of the sphere. For a 00291 * sphere χ = φ. 00292 * 00293 * φ must lie in the range [−90°, 90°]; the 00294 * result is undefined if this condition does not hold. The returned value 00295 * χ lies in [−90°, 90°]. 00296 **********************************************************************/ 00297 double ConformalLatitude(double phi); 00298 00299 /** 00300 * @param[in] chi the conformal latitude (degrees). 00301 * @return φ the geographic latitude (degrees). 00302 * 00303 * χ must lie in the range [−90°, 90°]; the 00304 * result is undefined if this condition does not hold. The returned value 00305 * φ lies in [−90°, 90°]. 00306 **********************************************************************/ 00307 double InverseConformalLatitude(double chi); 00308 00309 /** 00310 * @param[in] phi the geographic latitude (degrees). 00311 * @return ψ the isometric latitude (degrees). 00312 * 00313 * The isometric latitude gives the mapping of the ellipsoid to a plane 00314 * which which is conformal (angles are preserved) and in which the equator 00315 * of the ellipsoid maps to a straight line of constant scale; this mapping 00316 * defines the Mercator projection. For a sphere ψ = 00317 * sinh<sup>−1</sup> tan φ. 00318 * 00319 * φ must lie in the range [−90°, 90°]; the 00320 * result is undefined if this condition does not hold. 00321 **********************************************************************/ 00322 double IsometricLatitude(double phi); 00323 00324 /** 00325 * @param[in] psi the isometric latitude (degrees). 00326 * @return φ the geographic latitude (degrees). 00327 * 00328 * The returned value φ lies in [−90°, 90°]. 00329 **********************************************************************/ 00330 double InverseIsometricLatitude(double psi); 00331 ///@} 00332 00333 /** \name Other quantities. 00334 **********************************************************************/ 00335 ///@{ 00336 00337 /** 00338 * @param[in] phi the geographic latitude (degrees). 00339 * @return \e R = \e a cos β the radius of a circle of latitude 00340 * φ (meters). \e R (π/180°) gives meters per degree 00341 * longitude measured along a circle of latitude. 00342 * 00343 * φ must lie in the range [−90°, 90°]; the 00344 * result is undefined if this condition does not hold. 00345 **********************************************************************/ 00346 double CircleRadius(double phi); 00347 00348 /** 00349 * @param[in] phi the geographic latitude (degrees). 00350 * @return \e Z = \e b sin β the distance of a circle of latitude 00351 * φ from the equator measured parallel to the ellipsoid axis 00352 * (meters). 00353 * 00354 * φ must lie in the range [−90°, 90°]; the 00355 * result is undefined if this condition does not hold. 00356 **********************************************************************/ 00357 double CircleHeight(double phi); 00358 00359 /** 00360 * @param[in] phi the geographic latitude (degrees). 00361 * @return \e s the distance along a meridian 00362 * between the equator and a point of latitude φ (meters). \e s is 00363 * given by \e s = μ \e L / 90°, where \e L = 00364 * QuarterMeridian()). 00365 * 00366 * φ must lie in the range [−90°, 90°]; the 00367 * result is undefined if this condition does not hold. 00368 **********************************************************************/ 00369 double MeridianDistance(double phi); 00370 00371 /** 00372 * @param[in] phi the geographic latitude (degrees). 00373 * @return ρ the meridional radius of curvature of the ellipsoid at 00374 * latitude φ (meters); this is the curvature of the meridian. \e 00375 * rho is given by ρ = (180°/π) d\e s / dφ, 00376 * where \e s = MeridianDistance(); thus ρ (π/180°) 00377 * gives meters per degree latitude measured along a meridian. 00378 * 00379 * φ must lie in the range [−90°, 90°]; the 00380 * result is undefined if this condition does not hold. 00381 **********************************************************************/ 00382 double MeridionalCurvatureRadius(double phi); 00383 00384 /** 00385 * @param[in] phi the geographic latitude (degrees). 00386 * @return ν the transverse radius of curvature of the ellipsoid at 00387 * latitude φ (meters); this is the curvature of a curve on the 00388 * ellipsoid which also lies in a plane perpendicular to the ellipsoid 00389 * and to the meridian. ν is related to \e R = CircleRadius() by \e 00390 * R = ν cos φ. 00391 * 00392 * φ must lie in the range [−90°, 90°]; the 00393 * result is undefined if this condition does not hold. 00394 **********************************************************************/ 00395 double TransverseCurvatureRadius(double phi); 00396 00397 /** 00398 * @param[in] phi the geographic latitude (degrees). 00399 * @param[in] azi the angle between the meridian and the normal section 00400 * (degrees). 00401 * @return the radius of curvature of the ellipsoid in the normal 00402 * section at latitude φ inclined at an angle \e azi to the 00403 * meridian (meters). 00404 * 00405 * φ must lie in the range [−90°, 90°] and \e 00406 * azi must lie in the range [−540°, 540°); the 00407 * result is undefined if either of conditions does not hold. 00408 **********************************************************************/ 00409 double NormalCurvatureRadius(double phi, double azi); 00410 ///@} 00411 00412 /** \name Eccentricity conversions. 00413 **********************************************************************/ 00414 ///@{ 00415 00416 /** 00417 * @param[in] fp = \e f ' = (\e a − \e b) / \e b, the second 00418 * flattening. 00419 * @return \e f = (\e a − \e b) / \e a, the flattening. 00420 * 00421 * \e f ' should lie in (−1, ∞). 00422 * The returned value \e f lies in (−∞, 1). 00423 **********************************************************************/ 00424 static double SecondFlatteningToFlattening(double fp); 00425 00426 /** 00427 * @param[in] f = (\e a − \e b) / \e a, the flattening. 00428 * @return \e f ' = (\e a − \e b) / \e b, the second flattening. 00429 * 00430 * \e f should lie in (−∞, 1). 00431 * The returned value \e f ' lies in (−1, ∞). 00432 **********************************************************************/ 00433 static double FlatteningToSecondFlattening(double f); 00434 00435 /** 00436 * @param[in] n = (\e a − \e b) / (\e a + \e b), the third 00437 * flattening. 00438 * @return \e f = (\e a − \e b) / \e a, the flattening. 00439 * 00440 * \e n should lie in (−1, 1). 00441 * The returned value \e f lies in (−∞, 1). 00442 **********************************************************************/ 00443 static double ThirdFlatteningToFlattening(double n); 00444 00445 /** 00446 * @param[in] f = (\e a − \e b) / \e a, the flattening. 00447 * @return \e n = (\e a − \e b) / (\e a + \e b), the third 00448 * flattening. 00449 * 00450 * \e f should lie in (−∞, 1). 00451 * The returned value \e n lies in (−1, 1). 00452 **********************************************************************/ 00453 static double FlatteningToThirdFlattening(double f); 00454 00455 /** 00456 * @param[in] e2 = <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> − 00457 * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity 00458 * squared. 00459 * @return \e f = (\e a − \e b) / \e a, the flattening. 00460 * 00461 * <i>e</i><sup>2</sup> should lie in (−∞, 1). 00462 * The returned value \e f lies in (−∞, 1). 00463 **********************************************************************/ 00464 static double EccentricitySqToFlattening(double e2); 00465 00466 /** 00467 * @param[in] f = (\e a − \e b) / \e a, the flattening. 00468 * @return <i>e</i><sup>2</sup> = (<i>a</i><sup>2</sup> − 00469 * <i>b</i><sup>2</sup>) / <i>a</i><sup>2</sup>, the eccentricity 00470 * squared. 00471 * 00472 * \e f should lie in (−∞, 1). 00473 * The returned value <i>e</i><sup>2</sup> lies in (−∞, 1). 00474 **********************************************************************/ 00475 static double FlatteningToEccentricitySq(double f); 00476 00477 /** 00478 * @param[in] ep2 = <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> − 00479 * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentricity 00480 * squared. 00481 * @return \e f = (\e a − \e b) / \e a, the flattening. 00482 * 00483 * <i>e'</i> <sup>2</sup> should lie in (−1, ∞). 00484 * The returned value \e f lies in (−∞, 1). 00485 **********************************************************************/ 00486 static double SecondEccentricitySqToFlattening(double ep2); 00487 00488 /** 00489 * @param[in] f = (\e a − \e b) / \e a, the flattening. 00490 * @return <i>e'</i> <sup>2</sup> = (<i>a</i><sup>2</sup> − 00491 * <i>b</i><sup>2</sup>) / <i>b</i><sup>2</sup>, the second eccentricity 00492 * squared. 00493 * 00494 * \e f should lie in (−∞, 1). 00495 * The returned value <i>e'</i> <sup>2</sup> lies in (−1, ∞). 00496 **********************************************************************/ 00497 static double FlatteningToSecondEccentricitySq(double f); 00498 00499 /** 00500 * @param[in] epp2 = <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> 00501 * − <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + 00502 * <i>b</i><sup>2</sup>), the third eccentricity squared. 00503 * @return \e f = (\e a − \e b) / \e a, the flattening. 00504 * 00505 * <i>e''</i> <sup>2</sup> should lie in (−1, 1). 00506 * The returned value \e f lies in (−∞, 1). 00507 **********************************************************************/ 00508 static double ThirdEccentricitySqToFlattening(double epp2); 00509 00510 /** 00511 * @param[in] f = (\e a − \e b) / \e a, the flattening. 00512 * @return <i>e''</i> <sup>2</sup> = (<i>a</i><sup>2</sup> − 00513 * <i>b</i><sup>2</sup>) / (<i>a</i><sup>2</sup> + <i>b</i><sup>2</sup>), 00514 * the third eccentricity squared. 00515 * 00516 * \e f should lie in (−∞, 1). 00517 * The returned value <i>e''</i> <sup>2</sup> lies in (−1, 1). 00518 **********************************************************************/ 00519 static double FlatteningToThirdEccentricitySq(double f); 00520 }; 00521 } // namespace NETGeographicLib