NETGeographicLib 1.52
Loading...
Searching...
No Matches
Geodesic.h
Go to the documentation of this file.
1/**
2 * \file NETGeographicLib/Geodesic.h
3 * \brief Header for NETGeographicLib::Geodesic class
4 *
5 * NETGeographicLib is copyright (c) Scott Heiman (2013)
6 * GeographicLib is Copyright (c) Charles Karney (2010-2012)
7 * <charles@karney.com> and licensed under the MIT/X11 License.
8 * For more information, see
9 * https://geographiclib.sourceforge.io/
10 **********************************************************************/
11#pragma once
12#include "NETGeographicLib.h"
13
14namespace NETGeographicLib
15{
16 ref class GeodesicLine;
17 /**
18 * \brief .NET wrapper for GeographicLib::Geodesic.
19 *
20 * This class allows .NET applications to access GeographicLib::Geodesic.
21 *
22 * The shortest path between two points on a ellipsoid at (\e lat1, \e lon1)
23 * and (\e lat2, \e lon2) is called the geodesic. Its length is \e s12 and
24 * the geodesic from point 1 to point 2 has azimuths \e azi1 and \e azi2 at
25 * the two end points. (The azimuth is the heading measured clockwise from
26 * north. \e azi2 is the "forward" azimuth, i.e., the heading that takes you
27 * beyond point 2 not back to point 1.) In the figure below, latitude if
28 * labeled &phi;, longitude &lambda; (with &lambda;<sub>12</sub> =
29 * &lambda;<sub>2</sub> &minus; &lambda;<sub>1</sub>), and azimuth &alpha;.
30 *
31 * <img src="https://upload.wikimedia.org/wikipedia/commons/c/cb/Geodesic_problem_on_an_ellipsoid.svg" width=250 alt="spheroidal triangle">
32 *
33 * Given \e lat1, \e lon1, \e azi1, and \e s12, we can determine \e lat2, \e
34 * lon2, and \e azi2. This is the \e direct geodesic problem and its
35 * solution is given by the function Geodesic::Direct. (If \e s12 is
36 * sufficiently large that the geodesic wraps more than halfway around the
37 * earth, there will be another geodesic between the points with a smaller \e
38 * s12.)
39 *
40 * Given \e lat1, \e lon1, \e lat2, and \e lon2, we can determine \e azi1, \e
41 * azi2, and \e s12. This is the \e inverse geodesic problem, whose solution
42 * is given by Geodesic::Inverse. Usually, the solution to the inverse
43 * problem is unique. In cases where there are multiple solutions (all with
44 * the same \e s12, of course), all the solutions can be easily generated
45 * once a particular solution is provided.
46 *
47 * The standard way of specifying the direct problem is the specify the
48 * distance \e s12 to the second point. However it is sometimes useful
49 * instead to specify the arc length \e a12 (in degrees) on the auxiliary
50 * sphere. This is a mathematical construct used in solving the geodesic
51 * problems. The solution of the direct problem in this form is provided by
52 * Geodesic::ArcDirect. An arc length in excess of 180&deg; indicates that
53 * the geodesic is not a shortest path. In addition, the arc length between
54 * an equatorial crossing and the next extremum of latitude for a geodesic is
55 * 90&deg;.
56 *
57 * This class can also calculate several other quantities related to
58 * geodesics. These are:
59 * - <i>reduced length</i>. If we fix the first point and increase \e azi1
60 * by \e dazi1 (radians), the second point is displaced \e m12 \e dazi1 in
61 * the direction \e azi2 + 90&deg;. The quantity \e m12 is called
62 * the "reduced length" and is symmetric under interchange of the two
63 * points. On a curved surface the reduced length obeys a symmetry
64 * relation, \e m12 + \e m21 = 0. On a flat surface, we have \e m12 = \e
65 * s12. The ratio <i>s12</i>/\e m12 gives the azimuthal scale for an
66 * azimuthal equidistant projection.
67 * - <i>geodesic scale</i>. Consider a reference geodesic and a second
68 * geodesic parallel to this one at point 1 and separated by a small
69 * distance \e dt. The separation of the two geodesics at point 2 is \e
70 * M12 \e dt where \e M12 is called the "geodesic scale". \e M21 is
71 * defined similarly (with the geodesics being parallel at point 2). On a
72 * flat surface, we have \e M12 = \e M21 = 1. The quantity 1/\e M12 gives
73 * the scale of the Cassini-Soldner projection.
74 * - <i>area</i>. The area between the geodesic from point 1 to point 2 and
75 * the equation is represented by \e S12; it is the area, measured
76 * counter-clockwise, of the geodesic quadrilateral with corners
77 * (<i>lat1</i>,<i>lon1</i>), (0,<i>lon1</i>), (0,<i>lon2</i>), and
78 * (<i>lat2</i>,<i>lon2</i>). It can be used to compute the area of any
79 * geodesic polygon.
80 *
81 * Overloaded versions of Geodesic::Direct, Geodesic::ArcDirect, and
82 * Geodesic::Inverse allow these quantities to be returned. In addition
83 * there are general functions Geodesic::GenDirect, and Geodesic::GenInverse
84 * which allow an arbitrary set of results to be computed. The quantities \e
85 * m12, \e M12, \e M21 which all specify the behavior of nearby geodesics
86 * obey addition rules. If points 1, 2, and 3 all lie on a single geodesic,
87 * then the following rules hold:
88 * - \e s13 = \e s12 + \e s23
89 * - \e a13 = \e a12 + \e a23
90 * - \e S13 = \e S12 + \e S23
91 * - \e m13 = \e m12 \e M23 + \e m23 \e M21
92 * - \e M13 = \e M12 \e M23 &minus; (1 &minus; \e M12 \e M21) \e m23 / \e m12
93 * - \e M31 = \e M32 \e M21 &minus; (1 &minus; \e M23 \e M32) \e m12 / \e m23
94 *
95 * Additional functionality is provided by the GeodesicLine class, which
96 * allows a sequence of points along a geodesic to be computed.
97 *
98 * The shortest distance returned by the solution of the inverse problem is
99 * (obviously) uniquely defined. However, in a few special cases there are
100 * multiple azimuths which yield the same shortest distance. Here is a
101 * catalog of those cases:
102 * - \e lat1 = &minus;\e lat2 (with neither point at a pole). If \e azi1 =
103 * \e azi2, the geodesic is unique. Otherwise there are two geodesics and
104 * the second one is obtained by setting [\e azi1, \e azi2] &rarr; [\e
105 * azi2, \e azi1], [\e M12, \e M21] &rarr; [\e M21, \e M12], \e S12 &rarr;
106 * &minus;\e S12. (This occurs when the longitude difference is near
107 * &plusmn;180&deg; for oblate ellipsoids.)
108 * - \e lon2 = \e lon1 &plusmn; 180&deg; (with neither point at a pole). If
109 * \e azi1 = 0&deg; or &plusmn;180&deg;, the geodesic is unique. Otherwise
110 * there are two geodesics and the second one is obtained by setting [\e
111 * azi1, \e azi2] &rarr; [&minus;\e azi1, &minus;\e azi2], \e S12 &rarr;
112 * &minus;\e S12. (This occurs when \e lat2 is near &minus;\e lat1 for
113 * prolate ellipsoids.)
114 * - Points 1 and 2 at opposite poles. There are infinitely many geodesics
115 * which can be generated by setting [\e azi1, \e azi2] &rarr; [\e azi1, \e
116 * azi2] + [\e d, &minus;\e d], for arbitrary \e d. (For spheres, this
117 * prescription applies when points 1 and 2 are antipodal.)
118 * - \e s12 = 0 (coincident points). There are infinitely many geodesics
119 * which can be generated by setting [\e azi1, \e azi2] &rarr;
120 * [\e azi1, \e azi2] + [\e d, \e d], for arbitrary \e d.
121 *
122 * The calculations are accurate to better than 15 nm (15 nanometers) for the
123 * WGS84 ellipsoid. See Sec. 9 of
124 * <a href="https://arxiv.org/abs/1102.1215v1">arXiv:1102.1215v1</a> for
125 * details. The algorithms used by this class are based on series expansions
126 * using the flattening \e f as a small parameter. These are only accurate
127 * for |<i>f</i>| &lt; 0.02; however reasonably accurate results will be
128 * obtained for |<i>f</i>| &lt; 0.2. Here is a table of the approximate
129 * maximum error (expressed as a distance) for an ellipsoid with the same
130 * equatorial radius as the WGS84 ellipsoid and different values of the
131 * flattening.<pre>
132 * |f| error
133 * 0.01 25 nm
134 * 0.02 30 nm
135 * 0.05 10 um
136 * 0.1 1.5 mm
137 * 0.2 300 mm
138 * </pre>
139 * For very eccentric ellipsoids, use GeodesicExact instead.
140 *
141 * The algorithms are described in
142 * - C. F. F. Karney,
143 * <a href="https://doi.org/10.1007/s00190-012-0578-z">
144 * Algorithms for geodesics</a>,
145 * J. Geodesy <b>87</b>, 43--55 (2013);
146 * DOI: <a href="https://doi.org/10.1007/s00190-012-0578-z">
147 * 10.1007/s00190-012-0578-z</a>;
148 * addenda: <a href="https://geographiclib.sourceforge.io/geod-addenda.html">
149 * geod-addenda.html</a>.
150 * .
151 * For more information on geodesics see \ref geodesic.
152 *
153 * C# Example:
154 * \include example-Geodesic.cs
155 * Managed C++ Example:
156 * \include example-Geodesic.cpp
157 * Visual Basic Example:
158 * \include example-Geodesic.vb
159 *
160 * <B>INTERFACE DIFFERENCES:</B><BR>
161 * A default constructor has been provided that assumes WGS84 parameters.
162 *
163 * The EquatorialRadius, Flattening, and EllipsoidArea functions are
164 * implemented as properties.
165 *
166 * The GenDirect, GenInverse, and Line functions accept the
167 * "capabilities mask" as a NETGeographicLib::Mask rather than an
168 * unsigned.
169 **********************************************************************/
170 public ref class Geodesic
171 {
172 private:
173 // The pointer to the unmanaged GeographicLib::Geodesic.
174 const GeographicLib::Geodesic* m_pGeodesic;
175
176 // Frees the unmanaged memory when this object is destroyed.
177 !Geodesic();
178 public:
179 /**
180 * Bit masks for what calculations to do. These masks do double duty.
181 * They signify to the GeodesicLine::GeodesicLine constructor and to
182 * Geodesic::Line what capabilities should be included in the GeodesicLine
183 * object. They also specify which results to return in the general
184 * routines Geodesic::GenDirect and Geodesic::GenInverse routines.
185 * GeodesicLine::mask is a duplication of this enum.
186 **********************************************************************/
187 enum class mask {
188 /**
189 * No capabilities, no output.
190 * @hideinitializer
191 **********************************************************************/
192 NONE = 0U,
193 /**
194 * Calculate latitude \e lat2. (It's not necessary to include this as a
195 * capability to GeodesicLine because this is included by default.)
196 * @hideinitializer
197 **********************************************************************/
198 LATITUDE = 1U<<7 | unsigned(captype::CAP_NONE),
199 /**
200 * Calculate longitude \e lon2.
201 * @hideinitializer
202 **********************************************************************/
203 LONGITUDE = 1U<<8 | unsigned(captype::CAP_C3),
204 /**
205 * Calculate azimuths \e azi1 and \e azi2. (It's not necessary to
206 * include this as a capability to GeodesicLine because this is included
207 * by default.)
208 * @hideinitializer
209 **********************************************************************/
210 AZIMUTH = 1U<<9 | unsigned(captype::CAP_NONE),
211 /**
212 * Calculate distance \e s12.
213 * @hideinitializer
214 **********************************************************************/
215 DISTANCE = 1U<<10 | unsigned(captype::CAP_C1),
216 /**
217 * Allow distance \e s12 to be used as input in the direct geodesic
218 * problem.
219 * @hideinitializer
220 **********************************************************************/
221 DISTANCE_IN = 1U<<11 | unsigned(captype::CAP_C1) | unsigned(captype::CAP_C1p),
222 /**
223 * Calculate reduced length \e m12.
224 * @hideinitializer
225 **********************************************************************/
226 REDUCEDLENGTH = 1U<<12 | unsigned(captype::CAP_C1) | unsigned(captype::CAP_C2),
227 /**
228 * Calculate geodesic scales \e M12 and \e M21.
229 * @hideinitializer
230 **********************************************************************/
231 GEODESICSCALE = 1U<<13 | unsigned(captype::CAP_C1) | unsigned(captype::CAP_C2),
232 /**
233 * Calculate area \e S12.
234 * @hideinitializer
235 **********************************************************************/
236 AREA = 1U<<14 | unsigned(captype::CAP_C4),
237 /**
238 * Unroll \e lon2 in the direct calculation.
239 * @hideinitializer
240 **********************************************************************/
241 LONG_UNROLL = 1U<<15,
242 /**
243 * All capabilities, calculate everything. (LONG_UNROLL is not
244 * included in this mask.)
245 * @hideinitializer
246 **********************************************************************/
247 ALL = unsigned(captype::OUT_ALL)| unsigned(captype::CAP_ALL),
248 };
249 /** \name Constructor
250 **********************************************************************/
251 ///@{
252 /**
253 * Constructor for a ellipsoid with
254 *
255 * @param[in] a equatorial radius (meters).
256 * @param[in] f flattening of ellipsoid. Setting \e f = 0 gives a sphere.
257 * Negative \e f gives a prolate ellipsoid.
258 * @exception GeographicErr if \e a or (1 &minus; \e f ) \e a is not
259 * positive.
260 **********************************************************************/
261 Geodesic(double a, double f);
262
263 /**
264 * Constructor for the WGS84 ellipsoid.
265 **********************************************************************/
267 ///@}
268
269 /**
270 * \brief the destructor calls the finalizer.
271 **********************************************************************/
272 ~Geodesic() { this->!Geodesic(); }
273
274 /** \name Direct geodesic problem specified in terms of distance.
275 **********************************************************************/
276 ///@{
277 /**
278 * Solve the direct geodesic problem where the length of the geodesic
279 * is specified in terms of distance.
280 *
281 * @param[in] lat1 latitude of point 1 (degrees).
282 * @param[in] lon1 longitude of point 1 (degrees).
283 * @param[in] azi1 azimuth at point 1 (degrees).
284 * @param[in] s12 distance between point 1 and point 2 (meters); it can be
285 * negative.
286 * @param[out] lat2 latitude of point 2 (degrees).
287 * @param[out] lon2 longitude of point 2 (degrees).
288 * @param[out] azi2 (forward) azimuth at point 2 (degrees).
289 * @param[out] m12 reduced length of geodesic (meters).
290 * @param[out] M12 geodesic scale of point 2 relative to point 1
291 * (dimensionless).
292 * @param[out] M21 geodesic scale of point 1 relative to point 2
293 * (dimensionless).
294 * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
295 * @return \e a12 arc length of between point 1 and point 2 (degrees).
296 *
297 * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]. The
298 * values of \e lon2 and \e azi2 returned are in the range
299 * [&minus;180&deg;, 180&deg;).
300 *
301 * If either point is at a pole, the azimuth is defined by keeping the
302 * longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon;),
303 * and taking the limit &epsilon; &rarr; 0+. An arc length greater that
304 * 180&deg; signifies a geodesic which is not a shortest path. (For a
305 * prolate ellipsoid, an additional condition is necessary for a shortest
306 * path: the longitudinal extent must not exceed of 180&deg;.)
307 *
308 * The following functions are overloaded versions of Geodesic::Direct
309 * which omit some of the output parameters. Note, however, that the arc
310 * length is always computed and returned as the function value.
311 **********************************************************************/
312 double Direct(double lat1, double lon1, double azi1, double s12,
313 [System::Runtime::InteropServices::Out] double% lat2,
314 [System::Runtime::InteropServices::Out] double% lon2,
315 [System::Runtime::InteropServices::Out] double% azi2,
316 [System::Runtime::InteropServices::Out] double% m12,
317 [System::Runtime::InteropServices::Out] double% M12,
318 [System::Runtime::InteropServices::Out] double% M21,
319 [System::Runtime::InteropServices::Out] double% S12);
320
321 /**
322 * See the documentation for Geodesic::Direct.
323 **********************************************************************/
324 double Direct(double lat1, double lon1, double azi1, double s12,
325 [System::Runtime::InteropServices::Out] double% lat2,
326 [System::Runtime::InteropServices::Out] double% lon2);
327
328 /**
329 * See the documentation for Geodesic::Direct.
330 **********************************************************************/
331 double Direct(double lat1, double lon1, double azi1, double s12,
332 [System::Runtime::InteropServices::Out] double% lat2,
333 [System::Runtime::InteropServices::Out] double% lon2,
334 [System::Runtime::InteropServices::Out] double% azi2);
335
336 /**
337 * See the documentation for Geodesic::Direct.
338 **********************************************************************/
339 double Direct(double lat1, double lon1, double azi1, double s12,
340 [System::Runtime::InteropServices::Out] double% lat2,
341 [System::Runtime::InteropServices::Out] double% lon2,
342 [System::Runtime::InteropServices::Out] double% azi2,
343 [System::Runtime::InteropServices::Out] double% m12);
344
345 /**
346 * See the documentation for Geodesic::Direct.
347 **********************************************************************/
348 double Direct(double lat1, double lon1, double azi1, double s12,
349 [System::Runtime::InteropServices::Out] double% lat2,
350 [System::Runtime::InteropServices::Out] double% lon2,
351 [System::Runtime::InteropServices::Out] double% azi2,
352 [System::Runtime::InteropServices::Out] double% M12,
353 [System::Runtime::InteropServices::Out] double% M21);
354
355 /**
356 * See the documentation for Geodesic::Direct.
357 **********************************************************************/
358 double Direct(double lat1, double lon1, double azi1, double s12,
359 [System::Runtime::InteropServices::Out] double% lat2,
360 [System::Runtime::InteropServices::Out] double% lon2,
361 [System::Runtime::InteropServices::Out] double% azi2,
362 [System::Runtime::InteropServices::Out] double% m12,
363 [System::Runtime::InteropServices::Out] double% M12,
364 [System::Runtime::InteropServices::Out] double% M21);
365 ///@}
366
367 /** \name Direct geodesic problem specified in terms of arc length.
368 **********************************************************************/
369 ///@{
370 /**
371 * Solve the direct geodesic problem where the length of the geodesic
372 * is specified in terms of arc length.
373 *
374 * @param[in] lat1 latitude of point 1 (degrees).
375 * @param[in] lon1 longitude of point 1 (degrees).
376 * @param[in] azi1 azimuth at point 1 (degrees).
377 * @param[in] a12 arc length between point 1 and point 2 (degrees); it can
378 * be negative.
379 * @param[out] lat2 latitude of point 2 (degrees).
380 * @param[out] lon2 longitude of point 2 (degrees).
381 * @param[out] azi2 (forward) azimuth at point 2 (degrees).
382 * @param[out] s12 distance between point 1 and point 2 (meters).
383 * @param[out] m12 reduced length of geodesic (meters).
384 * @param[out] M12 geodesic scale of point 2 relative to point 1
385 * (dimensionless).
386 * @param[out] M21 geodesic scale of point 1 relative to point 2
387 * (dimensionless).
388 * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
389 *
390 * \e lat1 should be in the range [&minus;90&deg;, 90&deg;]. The
391 * values of \e lon2 and \e azi2 returned are in the range
392 * [&minus;180&deg;, 180&deg;).
393 *
394 * If either point is at a pole, the azimuth is defined by keeping the
395 * longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon;),
396 * and taking the limit &epsilon; &rarr; 0+. An arc length greater that
397 * 180&deg; signifies a geodesic which is not a shortest path. (For a
398 * prolate ellipsoid, an additional condition is necessary for a shortest
399 * path: the longitudinal extent must not exceed of 180&deg;.)
400 *
401 * The following functions are overloaded versions of Geodesic::Direct
402 * which omit some of the output parameters.
403 **********************************************************************/
404 void ArcDirect(double lat1, double lon1, double azi1, double a12,
405 [System::Runtime::InteropServices::Out] double% lat2,
406 [System::Runtime::InteropServices::Out] double% lon2,
407 [System::Runtime::InteropServices::Out] double% azi2,
408 [System::Runtime::InteropServices::Out] double% s12,
409 [System::Runtime::InteropServices::Out] double% m12,
410 [System::Runtime::InteropServices::Out] double% M12,
411 [System::Runtime::InteropServices::Out] double% M21,
412 [System::Runtime::InteropServices::Out] double% S12);
413
414 /**
415 * See the documentation for Geodesic::ArcDirect.
416 **********************************************************************/
417 void ArcDirect(double lat1, double lon1, double azi1, double a12,
418 [System::Runtime::InteropServices::Out] double% lat2,
419 [System::Runtime::InteropServices::Out] double% lon2);
420
421 /**
422 * See the documentation for Geodesic::ArcDirect.
423 **********************************************************************/
424 void ArcDirect(double lat1, double lon1, double azi1, double a12,
425 [System::Runtime::InteropServices::Out] double% lat2,
426 [System::Runtime::InteropServices::Out] double% lon2,
427 [System::Runtime::InteropServices::Out] double% azi2);
428
429 /**
430 * See the documentation for Geodesic::ArcDirect.
431 **********************************************************************/
432 void ArcDirect(double lat1, double lon1, double azi1, double a12,
433 [System::Runtime::InteropServices::Out] double% lat2,
434 [System::Runtime::InteropServices::Out] double% lon2,
435 [System::Runtime::InteropServices::Out] double% azi2,
436 [System::Runtime::InteropServices::Out] double% s12);
437
438 /**
439 * See the documentation for Geodesic::ArcDirect.
440 **********************************************************************/
441 void ArcDirect(double lat1, double lon1, double azi1, double a12,
442 [System::Runtime::InteropServices::Out] double% lat2,
443 [System::Runtime::InteropServices::Out] double% lon2,
444 [System::Runtime::InteropServices::Out] double% azi2,
445 [System::Runtime::InteropServices::Out] double% s12,
446 [System::Runtime::InteropServices::Out] double% m12);
447
448 /**
449 * See the documentation for Geodesic::ArcDirect.
450 **********************************************************************/
451 void ArcDirect(double lat1, double lon1, double azi1, double a12,
452 [System::Runtime::InteropServices::Out] double% lat2,
453 [System::Runtime::InteropServices::Out] double% lon2,
454 [System::Runtime::InteropServices::Out] double% azi2,
455 [System::Runtime::InteropServices::Out] double% s12,
456 [System::Runtime::InteropServices::Out] double% M12,
457 [System::Runtime::InteropServices::Out] double% M21);
458
459 /**
460 * See the documentation for Geodesic::ArcDirect.
461 **********************************************************************/
462 void ArcDirect(double lat1, double lon1, double azi1, double a12,
463 [System::Runtime::InteropServices::Out] double% lat2,
464 [System::Runtime::InteropServices::Out] double% lon2,
465 [System::Runtime::InteropServices::Out] double% azi2,
466 [System::Runtime::InteropServices::Out] double% s12,
467 [System::Runtime::InteropServices::Out] double% m12,
468 [System::Runtime::InteropServices::Out] double% M12,
469 [System::Runtime::InteropServices::Out] double% M21);
470 ///@}
471
472 /** \name General version of the direct geodesic solution.
473 **********************************************************************/
474 ///@{
475
476 /**
477 * The general direct geodesic problem. Geodesic::Direct and
478 * Geodesic::ArcDirect are defined in terms of this function.
479 *
480 * @param[in] lat1 latitude of point 1 (degrees).
481 * @param[in] lon1 longitude of point 1 (degrees).
482 * @param[in] azi1 azimuth at point 1 (degrees).
483 * @param[in] arcmode boolean flag determining the meaning of the \e
484 * s12_a12.
485 * @param[in] s12_a12 if \e arcmode is false, this is the distance between
486 * point 1 and point 2 (meters); otherwise it is the arc length between
487 * point 1 and point 2 (degrees); it can be negative.
488 * @param[in] outmask a bitor'ed combination of Geodesic::mask values
489 * specifying which of the following parameters should be set.
490 * @param[out] lat2 latitude of point 2 (degrees).
491 * @param[out] lon2 longitude of point 2 (degrees).
492 * @param[out] azi2 (forward) azimuth at point 2 (degrees).
493 * @param[out] s12 distance between point 1 and point 2 (meters).
494 * @param[out] m12 reduced length of geodesic (meters).
495 * @param[out] M12 geodesic scale of point 2 relative to point 1
496 * (dimensionless).
497 * @param[out] M21 geodesic scale of point 1 relative to point 2
498 * (dimensionless).
499 * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
500 * @return \e a12 arc length of between point 1 and point 2 (degrees).
501 *
502 * The Geodesic::mask values possible for \e outmask are
503 * - \e outmask |= Geodesic::LATITUDE for the latitude \e lat2;
504 * - \e outmask |= Geodesic::LONGITUDE for the latitude \e lon2;
505 * - \e outmask |= Geodesic::AZIMUTH for the latitude \e azi2;
506 * - \e outmask |= Geodesic::DISTANCE for the distance \e s12;
507 * - \e outmask |= Geodesic::REDUCEDLENGTH for the reduced length \e
508 * m12;
509 * - \e outmask |= Geodesic::GEODESICSCALE for the geodesic scales \e
510 * M12 and \e M21;
511 * - \e outmask |= Geodesic::AREA for the area \e S12;
512 * - \e outmask |= Geodesic::ALL for all of the above;
513 * - \e outmask |= Geodesic::LONG_UNROLL to unroll \e lon2 instead of
514 * wrapping it into the range [&minus;180&deg;, 180&deg;).
515 * .
516 * The function value \e a12 is always computed and returned and this
517 * equals \e s12_a12 is \e arcmode is true. If \e outmask includes
518 * Geodesic::DISTANCE and \e arcmode is false, then \e s12 = \e s12_a12.
519 * It is not necessary to include Geodesic::DISTANCE_IN in \e outmask; this
520 * is automatically included is \e arcmode is false.
521 *
522 * With the LONG_UNROLL bit set, the quantity \e lon2 &minus; \e lon1
523 * indicates how many times and in what sense the geodesic encircles
524 * the ellipsoid.
525 **********************************************************************/
526 double GenDirect(double lat1, double lon1, double azi1,
527 bool arcmode, double s12_a12,
528 Geodesic::mask outmask,
529 [System::Runtime::InteropServices::Out] double% lat2,
530 [System::Runtime::InteropServices::Out] double% lon2,
531 [System::Runtime::InteropServices::Out] double% azi2,
532 [System::Runtime::InteropServices::Out] double% s12,
533 [System::Runtime::InteropServices::Out] double% m12,
534 [System::Runtime::InteropServices::Out] double% M12,
535 [System::Runtime::InteropServices::Out] double% M21,
536 [System::Runtime::InteropServices::Out] double% S12);
537 ///@}
538
539 /** \name Inverse geodesic problem.
540 **********************************************************************/
541 ///@{
542 /**
543 * Solve the inverse geodesic problem.
544 *
545 * @param[in] lat1 latitude of point 1 (degrees).
546 * @param[in] lon1 longitude of point 1 (degrees).
547 * @param[in] lat2 latitude of point 2 (degrees).
548 * @param[in] lon2 longitude of point 2 (degrees).
549 * @param[out] s12 distance between point 1 and point 2 (meters).
550 * @param[out] azi1 azimuth at point 1 (degrees).
551 * @param[out] azi2 (forward) azimuth at point 2 (degrees).
552 * @param[out] m12 reduced length of geodesic (meters).
553 * @param[out] M12 geodesic scale of point 2 relative to point 1
554 * (dimensionless).
555 * @param[out] M21 geodesic scale of point 1 relative to point 2
556 * (dimensionless).
557 * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
558 * @return \e a12 arc length of between point 1 and point 2 (degrees).
559 *
560 * \e lat1 and \e lat2 should be in the range [&minus;90&deg;,
561 * 90&deg;]. The values of \e azi1 and \e azi2 returned are in the
562 * range [&minus;180&deg;, 180&deg;).
563 *
564 * If either point is at a pole, the azimuth is defined by keeping the
565 * longitude fixed, writing \e lat = &plusmn;(90&deg; &minus; &epsilon;),
566 * and taking the limit &epsilon; &rarr; 0+.
567 *
568 * The solution to the inverse problem is found using Newton's method. If
569 * this fails to converge (this is very unlikely in geodetic applications
570 * but does occur for very eccentric ellipsoids), then the bisection method
571 * is used to refine the solution.
572 *
573 * The following functions are overloaded versions of Geodesic::Inverse
574 * which omit some of the output parameters. Note, however, that the arc
575 * length is always computed and returned as the function value.
576 **********************************************************************/
577 double Inverse(double lat1, double lon1, double lat2, double lon2,
578 [System::Runtime::InteropServices::Out] double% s12,
579 [System::Runtime::InteropServices::Out] double% azi1,
580 [System::Runtime::InteropServices::Out] double% azi2,
581 [System::Runtime::InteropServices::Out] double% m12,
582 [System::Runtime::InteropServices::Out] double% M12,
583 [System::Runtime::InteropServices::Out] double% M21,
584 [System::Runtime::InteropServices::Out] double% S12);
585
586 /**
587 * See the documentation for Geodesic::Inverse.
588 **********************************************************************/
589 double Inverse(double lat1, double lon1, double lat2, double lon2,
590 [System::Runtime::InteropServices::Out] double% s12);
591
592 /**
593 * See the documentation for Geodesic::Inverse.
594 **********************************************************************/
595 double Inverse(double lat1, double lon1, double lat2, double lon2,
596 [System::Runtime::InteropServices::Out] double% azi1,
597 [System::Runtime::InteropServices::Out] double% azi2);
598
599 /**
600 * See the documentation for Geodesic::Inverse.
601 **********************************************************************/
602 double Inverse(double lat1, double lon1, double lat2, double lon2,
603 [System::Runtime::InteropServices::Out] double% s12,
604 [System::Runtime::InteropServices::Out] double% azi1,
605 [System::Runtime::InteropServices::Out] double% azi2);
606
607 /**
608 * See the documentation for Geodesic::Inverse.
609 **********************************************************************/
610 double Inverse(double lat1, double lon1, double lat2, double lon2,
611 [System::Runtime::InteropServices::Out] double% s12,
612 [System::Runtime::InteropServices::Out] double% azi1,
613 [System::Runtime::InteropServices::Out] double% azi2,
614 [System::Runtime::InteropServices::Out] double% m12);
615
616 /**
617 * See the documentation for Geodesic::Inverse.
618 **********************************************************************/
619 double Inverse(double lat1, double lon1, double lat2, double lon2,
620 [System::Runtime::InteropServices::Out] double% s12,
621 [System::Runtime::InteropServices::Out] double% azi1,
622 [System::Runtime::InteropServices::Out] double% azi2,
623 [System::Runtime::InteropServices::Out] double% M12,
624 [System::Runtime::InteropServices::Out] double% M21);
625
626 /**
627 * See the documentation for Geodesic::Inverse.
628 **********************************************************************/
629 double Inverse(double lat1, double lon1, double lat2, double lon2,
630 [System::Runtime::InteropServices::Out] double% s12,
631 [System::Runtime::InteropServices::Out] double% azi1,
632 [System::Runtime::InteropServices::Out] double% azi2,
633 [System::Runtime::InteropServices::Out] double% m12,
634 [System::Runtime::InteropServices::Out] double% M12,
635 [System::Runtime::InteropServices::Out] double% M21);
636 ///@}
637
638 /** \name General version of inverse geodesic solution.
639 **********************************************************************/
640 ///@{
641 /**
642 * The general inverse geodesic calculation. Geodesic::Inverse is defined
643 * in terms of this function.
644 *
645 * @param[in] lat1 latitude of point 1 (degrees).
646 * @param[in] lon1 longitude of point 1 (degrees).
647 * @param[in] lat2 latitude of point 2 (degrees).
648 * @param[in] lon2 longitude of point 2 (degrees).
649 * @param[in] outmask a bitor'ed combination of Geodesic::mask values
650 * specifying which of the following parameters should be set.
651 * @param[out] s12 distance between point 1 and point 2 (meters).
652 * @param[out] azi1 azimuth at point 1 (degrees).
653 * @param[out] azi2 (forward) azimuth at point 2 (degrees).
654 * @param[out] m12 reduced length of geodesic (meters).
655 * @param[out] M12 geodesic scale of point 2 relative to point 1
656 * (dimensionless).
657 * @param[out] M21 geodesic scale of point 1 relative to point 2
658 * (dimensionless).
659 * @param[out] S12 area under the geodesic (meters<sup>2</sup>).
660 * @return \e a12 arc length of between point 1 and point 2 (degrees).
661 *
662 * The Geodesic::mask values possible for \e outmask are
663 * - \e outmask |= Geodesic::DISTANCE for the distance \e s12;
664 * - \e outmask |= Geodesic::AZIMUTH for the latitude \e azi2;
665 * - \e outmask |= Geodesic::REDUCEDLENGTH for the reduced length \e
666 * m12;
667 * - \e outmask |= Geodesic::GEODESICSCALE for the geodesic scales \e
668 * M12 and \e M21;
669 * - \e outmask |= Geodesic::AREA for the area \e S12;
670 * - \e outmask |= Geodesic::ALL for all of the above.
671 * .
672 * The arc length is always computed and returned as the function value.
673 **********************************************************************/
674 double GenInverse(double lat1, double lon1, double lat2, double lon2,
675 Geodesic::mask outmask,
676 [System::Runtime::InteropServices::Out] double% s12,
677 [System::Runtime::InteropServices::Out] double% azi1,
678 [System::Runtime::InteropServices::Out] double% azi2,
679 [System::Runtime::InteropServices::Out] double% m12,
680 [System::Runtime::InteropServices::Out] double% M12,
681 [System::Runtime::InteropServices::Out] double% M21,
682 [System::Runtime::InteropServices::Out] double% S12);
683 ///@}
684
685 /** \name Interface to GeodesicLine.
686 **********************************************************************/
687 ///@{
688
689 /**
690 * Set up to compute several points on a single geodesic.
691 *
692 * @param[in] lat1 latitude of point 1 (degrees).
693 * @param[in] lon1 longitude of point 1 (degrees).
694 * @param[in] azi1 azimuth at point 1 (degrees).
695 * @param[in] caps bitor'ed combination of NETGeographicLib::Mask values
696 * specifying the capabilities the GeodesicLine object should possess,
697 * i.e., which quantities can be returned in calls to
698 * GeodesicLine::Position.
699 * @return a GeodesicLine object.
700 *
701 * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
702 *
703 * The NETGeographicLib::Mask values are
704 * - \e caps |= NETGeographicLib::Mask::LATITUDE for the latitude \e lat2; this is
705 * added automatically;
706 * - \e caps |= NETGeographicLib::Mask::LONGITUDE for the latitude \e lon2;
707 * - \e caps |= NETGeographicLib::Mask::AZIMUTH for the azimuth \e azi2; this is
708 * added automatically;
709 * - \e caps |= NETGeographicLib::Mask::DISTANCE for the distance \e s12;
710 * - \e caps |= NETGeographicLib::Mask::REDUCEDLENGTH for the reduced length \e m12;
711 * - \e caps |= NETGeographicLib::Mask::GEODESICSCALE for the geodesic scales \e M12
712 * and \e M21;
713 * - \e caps |= NETGeographicLib::Mask::AREA for the area \e S12;
714 * - \e caps |= NETGeographicLib::Mask::DISTANCE_IN permits the length of the
715 * geodesic to be given in terms of \e s12; without this capability the
716 * length can only be specified in terms of arc length;
717 * - \e caps |= NETGeographicLib::Mask::ALL for all of the above.
718 * .
719 *
720 * If the point is at a pole, the azimuth is defined by keeping \e lon1
721 * fixed, writing \e lat1 = &plusmn;(90 &minus; &epsilon;), and taking the
722 * limit &epsilon; &rarr; 0+.
723 **********************************************************************/
724 GeodesicLine^ Line(double lat1, double lon1, double azi1,
726
727 /**
728 * Define a GeodesicLine in terms of the inverse geodesic problem.
729 *
730 * @param[in] lat1 latitude of point 1 (degrees).
731 * @param[in] lon1 longitude of point 1 (degrees).
732 * @param[in] lat2 latitude of point 2 (degrees).
733 * @param[in] lon2 longitude of point 2 (degrees).
734 * @param[in] caps bitor'ed combination of Geodesic::mask values
735 * specifying the capabilities the GeodesicLine object should possess,
736 * i.e., which quantities can be returned in calls to
737 * GeodesicLine::Position.
738 * @return a GeodesicLine object.
739 *
740 * This function sets point 3 of the GeodesicLine to correspond to point 2
741 * of the inverse geodesic problem.
742 *
743 * \e lat1 and \e lat2 should be in the range [&minus;90&deg;, 90&deg;].
744 **********************************************************************/
745 GeodesicLine^ InverseLine(double lat1, double lon1, double lat2,
746 double lon2, NETGeographicLib::Mask caps);
747
748 /**
749 * Define a GeodesicLine in terms of the direct geodesic problem specified
750 * in terms of distance.
751 *
752 * @param[in] lat1 latitude of point 1 (degrees).
753 * @param[in] lon1 longitude of point 1 (degrees).
754 * @param[in] azi1 azimuth at point 1 (degrees).
755 * @param[in] s12 distance between point 1 and point 2 (meters); it can be
756 * negative.
757 * @param[in] caps bitor'ed combination of Geodesic::mask values
758 * specifying the capabilities the GeodesicLine object should possess,
759 * i.e., which quantities can be returned in calls to
760 * GeodesicLine::Position.
761 * @return a GeodesicLine object.
762 *
763 * This function sets point 3 of the GeodesicLine to correspond to point 2
764 * of the direct geodesic problem.
765 *
766 * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
767 **********************************************************************/
768 GeodesicLine^ DirectLine(double lat1, double lon1, double azi1,
769 double s12, NETGeographicLib::Mask caps);
770
771 /**
772 * Define a GeodesicLine in terms of the direct geodesic problem specified
773 * in terms of arc length.
774 *
775 * @param[in] lat1 latitude of point 1 (degrees).
776 * @param[in] lon1 longitude of point 1 (degrees).
777 * @param[in] azi1 azimuth at point 1 (degrees).
778 * @param[in] a12 arc length between point 1 and point 2 (degrees); it can
779 * be negative.
780 * @param[in] caps bitor'ed combination of Geodesic::mask values
781 * specifying the capabilities the GeodesicLine object should possess,
782 * i.e., which quantities can be returned in calls to
783 * GeodesicLine::Position.
784 * @return a GeodesicLine object.
785 *
786 * This function sets point 3 of the GeodesicLine to correspond to point 2
787 * of the direct geodesic problem.
788 *
789 * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
790 **********************************************************************/
791 GeodesicLine^ ArcDirectLine(double lat1, double lon1, double azi1,
792 double a12, NETGeographicLib::Mask caps);
793
794 /**
795 * Define a GeodesicLine in terms of the direct geodesic problem specified
796 * in terms of either distance or arc length.
797 *
798 * @param[in] lat1 latitude of point 1 (degrees).
799 * @param[in] lon1 longitude of point 1 (degrees).
800 * @param[in] azi1 azimuth at point 1 (degrees).
801 * @param[in] arcmode boolean flag determining the meaning of the \e
802 * s12_a12.
803 * @param[in] s12_a12 if \e arcmode is false, this is the distance between
804 * point 1 and point 2 (meters); otherwise it is the arc length between
805 * point 1 and point 2 (degrees); it can be negative.
806 * @param[in] caps bitor'ed combination of Geodesic::mask values
807 * specifying the capabilities the GeodesicLine object should possess,
808 * i.e., which quantities can be returned in calls to
809 * GeodesicLine::Position.
810 * @return a GeodesicLine object.
811 *
812 * This function sets point 3 of the GeodesicLine to correspond to point 2
813 * of the direct geodesic problem.
814 *
815 * \e lat1 should be in the range [&minus;90&deg;, 90&deg;].
816 **********************************************************************/
817 GeodesicLine^ GenDirectLine(double lat1, double lon1, double azi1,
818 bool arcmode, double s12_a12,
820 ///@}
821
822 /** \name Inspector functions.
823 **********************************************************************/
824 ///@{
825
826 /**
827 * @return \e a the equatorial radius of the ellipsoid (meters). This is
828 * the value used in the constructor.
829 **********************************************************************/
830 property double EquatorialRadius { double get(); }
831
832 /**
833 * @return \e f the flattening of the ellipsoid. This is the
834 * value used in the constructor.
835 **********************************************************************/
836 property double Flattening { double get(); }
837
838 /**
839 * @return total area of ellipsoid in meters<sup>2</sup>. The area of a
840 * polygon encircling a pole can be found by adding
841 * Geodesic::EllipsoidArea()/2 to the sum of \e S12 for each side of the
842 * polygon.
843 **********************************************************************/
844 property double EllipsoidArea { double get(); }
845
846 /**
847 * %return The unmanaged pointer to the GeographicLib::Geodesic.
848 *
849 * This function is for internal use only.
850 **********************************************************************/
851 System::IntPtr^ GetUnmanaged();
852 ///@}
853 };
854} // namespace NETGeographicLib
Header for NETGeographicLib::NETGeographicLib objects.
.NET wrapper for GeographicLib::GeodesicLine.
Definition: GeodesicLine.h:76
.NET wrapper for GeographicLib::Geodesic.
Definition: Geodesic.h:171
GeodesicLine ^ GenDirectLine(double lat1, double lon1, double azi1, bool arcmode, double s12_a12, NETGeographicLib::Mask caps)
double Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2)
double Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21)
void ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2)
~Geodesic()
the destructor calls the finalizer.
Definition: Geodesic.h:272
void ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12)
GeodesicLine ^ Line(double lat1, double lon1, double azi1, NETGeographicLib::Mask caps)
double GenDirect(double lat1, double lon1, double azi1, bool arcmode, double s12_a12, Geodesic::mask outmask, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12)
void ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% m12)
double Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21)
double Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12)
void ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21)
double Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21)
double Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12)
void ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12)
double Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21)
double Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12)
GeodesicLine ^ InverseLine(double lat1, double lon1, double lat2, double lon2, NETGeographicLib::Mask caps)
double Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2)
System::IntPtr ^ GetUnmanaged()
Geodesic(double a, double f)
double Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12)
double Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2)
double Direct(double lat1, double lon1, double azi1, double s12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2)
GeodesicLine ^ ArcDirectLine(double lat1, double lon1, double azi1, double a12, NETGeographicLib::Mask caps)
GeodesicLine ^ DirectLine(double lat1, double lon1, double azi1, double s12, NETGeographicLib::Mask caps)
void ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2)
double Inverse(double lat1, double lon1, double lat2, double lon2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12)
double GenInverse(double lat1, double lon1, double lat2, double lon2, Geodesic::mask outmask, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% azi1, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% m12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21, [System::Runtime::InteropServices::Out] double% S12)
void ArcDirect(double lat1, double lon1, double azi1, double a12, [System::Runtime::InteropServices::Out] double% lat2, [System::Runtime::InteropServices::Out] double% lon2, [System::Runtime::InteropServices::Out] double% azi2, [System::Runtime::InteropServices::Out] double% s12, [System::Runtime::InteropServices::Out] double% M12, [System::Runtime::InteropServices::Out] double% M21)