GeographicLib 2.3
Intersect.hpp
Go to the documentation of this file.
1/**
2 * \file Intersect.hpp
3 * \brief Header for GeographicLib::Intersect class
4 *
5 * Copyright (c) Charles Karney (2023) <karney@alum.mit.edu> and licensed under
6 * the MIT/X11 License. For more information, see
7 * https://geographiclib.sourceforge.io/
8 **********************************************************************/
9
10#if !defined(GEOGRAPHICLIB_INTERSECT_HPP)
11#define GEOGRAPHICLIB_INTERSECT_HPP 1
12
13#include <vector>
14#include <set>
18
19namespace GeographicLib {
20
21 /**
22 * \brief %Geodesic intersections
23 *
24 * Find the intersections of two geodesics \e X and \e Y. Four calling
25 * sequences are supported.
26 * - The geodesics are defined by a position (latitude and longitude) and an
27 * azimuth. In this case the \e closest intersection is found.
28 * - The geodesics are defined by two endpoints. The intersection of the two
29 * segments is found. It they don't intersect, the the closest
30 * intersection is returned.
31 * - The geodesics are defined as an intersection point, a single position
32 * and two azimuths. In this case, the next closest intersection is found.
33 * - The geodesics are defined as in the first case and all intersection
34 * within a specified distance are returned.
35 * .
36 * In all cases the position of the intersection is given by the signed
37 * displacements \e x and \e y along the geodesics from the starting point
38 * (the first point in the case of a geodesic segment). The closest
39 * itersection is defined as the one that minimizes the L1 distance,
40 * Intersect::Dist([<i>x</i>, <i>y</i>) = |<i>x</i>| + |<i>y</i>|.
41 *
42 * The routines also optionally return a coincidence indicator \e c. This is
43 * typically 0. However if the geodesics lie on top of one another at the
44 * point of intersection, then \e c is set to +1, if they are parallel, and
45 * &minus;1, if they are antiparallel.
46 *
47 * Example of use:
48 * \include example-Intersect.cpp
49 *
50 * <a href="IntersectTool.1.html">IntersectTool</a> is a command-line utility
51 * providing access to the functionality of this class.
52 *
53 * This solution for intersections is described in
54 * - C. F. F. Karney,<br>
55 * <a href="https://arxiv.org/abs/yymm.nnnnn">
56 * Geodesic intersections</a>,<br>
57 * Technical Report, SRI International, MMM 2023.<br>
58 * <a href="https://arxiv.org/abs/yymm.nnnnn">arxiv:yymm.nnnnn</a>
59 * .
60 * It is based on the work of
61 * - S. Baseldga and J. C. Martinez-Llario,
62 * <a href="https://doi.org/10.1007/s11200-017-1020-z">
63 * Intersection and point-to-line solutions for geodesics
64 * on the ellipsoid</a>,
65 * Stud. Geophys. Geod. <b>62</b>, 353--363 (2018);
66 * DOI: <a href="https://doi.org/10.1007/s11200-017-1020-z">
67 * 10.1007/s11200-017-1020-z</a>.
68 **********************************************************************/
69
71 private:
72 typedef Math::real real;
73 public:
74 /**
75 * The type used to hold the two displacement along the geodesics. This is
76 * just a std::pair with \e x = \e first and \e y = \e second.
77 **********************************************************************/
78 typedef std::pair<Math::real, Math::real> Point;
79 /**
80 * The minimum capabilities for GeodesicLine objects which are passed to
81 * this class.
82 **********************************************************************/
83 static const unsigned LineCaps = Geodesic::LATITUDE | Geodesic::LONGITUDE |
86 private:
87 static const int numit_ = 100;
88 const Geodesic _geod;
89 real _a, _f, // equatorial radius, flattening
90 _R, // authalic radius
91 _d, // pi*_R
92 _eps, // criterion for intersection + coincidence
93 _tol, // convergence for Newton in Solve1
94 _delta, // for equality tests, safety margin for tiling
95 _t1, // min distance between intersections
96 _t2, // furthest dist to closest intersection
97 _t3, // 1/2 furthest min dist to next intersection
98 _t4, // capture radius for spherical sol in Solve0
99 _t5, // longest shortest geodesic
100 _d1, // tile spacing for Closest
101 _d2, // tile spacing for Next
102 _d3; // tile spacing for All
103 // The L1 distance
104 static Math::real d1(Math::real x, Math::real y)
105 { using std::fabs; return fabs(x) + fabs(y); }
106 // An internal version of Point with a little more functionality
107 class XPoint {
108 public:
109 real x, y;
110 int c;
111 XPoint(Math::real x, Math::real y, int c = 0)
112 : x(x), y(y), c(c)
113 {}
114 XPoint()
115 : x(Math::NaN()), y(Math::NaN()), c(0)
116 {}
117 XPoint(const Point& p)
118 : x(p.first), y(p.second), c(0)
119 {}
120 XPoint& operator+=(const XPoint& p) {
121 x += p.x; y += p.y;
122 if (p.c) c = p.c; // pass along a nonzero c from either operand
123 return *this;
124 }
125 XPoint operator+(const XPoint& p) const {
126 XPoint t = *this; t += p; return t;
127 }
128 Math::real Dist() const { return d1(x, y); }
129 Math::real Dist(const XPoint& p) const { return d1(x - p.x, y - p.y); }
130 Point data() const { return Point(x, y); }
131 };
132 // Comparing XPoints for insertions into sets, but ensure that close
133 // XPoints test equal.
134 class GEOGRAPHICLIB_EXPORT SetComp {
135 private:
136 const real _delta;
137 public:
138 SetComp(Math::real delta) : _delta(delta) {}
139 bool eq(const XPoint& p, const XPoint& q) const {
140 return d1(p.x - q.x, p.y - q.y) <= _delta;
141 }
142 bool operator()(const XPoint& p, const XPoint& q) const {
143 return !eq(p, q) && ( p.x != q.x ? p.x < q.x : p.y < q.y );
144 }
145 };
146 SetComp _comp;
147 // For ranking XPoints by closeness
148 class RankPoint {
149 private:
150 const real _x, _y;
151 public:
152 RankPoint(const Point& p0) : _x(p0.first), _y(p0.second) {}
153 RankPoint(const XPoint& p0) : _x(p0.x), _y(p0.y) {}
154 bool operator()(const XPoint& p, const XPoint& q) const {
155 real dp = d1(p.x - _x, p.y - _y),
156 dq = d1(q.x - _x, q.y - _y);
157 return dp != dq ? (dp < dq) :
158 (p.x != q.x ? (p.x < q.x) : (p.y < q.y));
159 }
160 };
161// The spherical solution
162 XPoint Spherical(const GeodesicLine& lineX, const GeodesicLine& lineY,
163 const XPoint& p) const;
164 // The basic algorithm
165 XPoint Basic(const GeodesicLine& lineX, const GeodesicLine& lineY,
166 const XPoint& p0) const;
167 // The closest intersecton
168 XPoint ClosestInt(const GeodesicLine& lineX, const GeodesicLine& lineY,
169 const XPoint& p0) const;
170 // The next intersecton
171 XPoint NextInt(const GeodesicLine& lineX, const GeodesicLine& lineY) const;
172 // Segment intersecton
173 XPoint SegmentInt(const GeodesicLine& lineX, const GeodesicLine& lineY,
174 int& segmode) const;
175 // All intersectons
176 std::vector<XPoint>
177 AllInt0(const GeodesicLine& lineX, const GeodesicLine& lineY,
178 Math::real maxdist, const XPoint& p0) const;
179 std::vector<Point>
180 AllInternal(const GeodesicLine& lineX, const GeodesicLine& lineY,
181 Math::real maxdist, const Point& p0,
182 std::vector<int>& c, bool cp) const;
183 // Find {semi-,}conjugate point which is close to s3. Optional m12, M12,
184 // M21 use {semi-,}conjugacy relative to point 2
185 Math::real ConjugateDist(const GeodesicLine& line, Math::real s3, bool semi,
186 Math::real m12 = 0, Math::real M12 = 1,
187 Math::real M21 = 1) const;
188 Math::real distpolar(Math::real lat1, Math::real* lat2 = nullptr) const;
189 Math::real polarb(Math::real* lata = nullptr, Math::real* latb = nullptr)
190 const;
191 Math::real conjdist(Math::real azi, Math::real* ds = nullptr,
192 Math::real* sp = nullptr, Math::real* sm = nullptr)
193 const;
194 Math::real distoblique(Math::real* azi = nullptr, Math::real* sp = nullptr,
195 Math::real* sm = nullptr) const;
196 // p is intersection point on coincident lines orientation = c; p0 is
197 // origin point. Change p to center point wrt p0, i.e, abs((p-p0)_x) =
198 // abs((p-p0)_y)
199 static XPoint fixcoincident(const XPoint& p0, const XPoint& p);
200 static XPoint fixcoincident(const XPoint& p0, const XPoint& p, int c);
201 static XPoint fixsegment(Math::real sx, Math::real sy, const XPoint& p);
202 static int segmentmode(Math::real sx, Math::real sy, const XPoint& p) {
203 return (p.x < 0 ? -1 : p.x <= sx ? 0 : 1) * 3
204 + (p.y < 0 ? -1 : p.y <= sy ? 0 : 1);
205 }
206 mutable long long _cnt0, _cnt1, _cnt2, _cnt3, _cnt4;
207 public:
208 /** \name Constructor
209 **********************************************************************/
210 ///@{
211 /**
212 * Constructor for an ellipsoid with
213 *
214 * @param[in] geod a Geodesic object. This sets the parameters \e a and \e
215 * f for the ellipsoid.
216 * @exception GeographicErr if the eccentricity of the elliposdoid is too
217 * large.
218 *
219 * \note This class has been validated for -1/4 &le; \e f &le; 1/5. It may
220 * give satisfactory results slightly outside this range; however
221 * sufficient far outside the range, some internal checks will fail and an
222 * exception thrown.
223 *
224 * \note If |<i>f</i>| > 1/50, then the Geodesic object should be
225 * constructed with \e exact = true.
226 **********************************************************************/
227 Intersect(const Geodesic& geod);
228 ///@}
229
230 /** \name Finding intersections
231 **********************************************************************/
232 ///@{
233 /**
234 * Find the closest intersection point, with each geodesic specified by
235 * position and azimuth.
236 *
237 * @param[in] latX latitude of starting point for geodesic \e X (degrees).
238 * @param[in] lonX longitude of starting point for geodesic \e X (degrees).
239 * @param[in] aziX azimuth at starting point for geodesic \e X (degrees).
240 * @param[in] latY latitude of starting point for geodesic \e Y (degrees).
241 * @param[in] lonY longitude of starting point for geodesic \e Y (degrees).
242 * @param[in] aziY azimuth at starting point for geodesic \e Y (degrees).
243 * @param[in] p0 an optional offset for the starting points (meters),
244 * default = [0,0].
245 * @param[out] c optional pointer to an integer coincidence indicator.
246 * @return \e p the intersection point closest to \e p0.
247 *
248 * The returned intersection minimizes Intersect::Dist(\e p, \e p0).
249 **********************************************************************/
250 Point Closest(Math::real latX, Math::real lonX, Math::real aziX,
251 Math::real latY, Math::real lonY, Math::real aziY,
252 const Point& p0 = Point(0, 0), int* c = nullptr) const;
253 /**
254 * Find the closest intersection point, with each geodesic given as a
255 * GeodesicLine.
256 *
257 * @param[in] lineX geodesic \e X.
258 * @param[in] lineY geodesic \e Y.
259 * @param[in] p0 an optional offset for the starting points (meters),
260 * default = [0,0].
261 * @param[out] c optional pointer to an integer coincidence indicator.
262 * @return \e p the intersection point closest to \e p0.
263 *
264 * The returned intersection minimizes Intersect::Dist(\e p, \e p0).
265 *
266 * \note \e lineX and \e lineY should be created with minimum capabilities
267 * Intersect::LineCaps. The methods for creating a GeodesicLine include
268 * all these capabilities by default.
269 **********************************************************************/
270 Point Closest(const GeodesicLine& lineX, const GeodesicLine& lineY,
271 const Point& p0 = Point(0, 0), int* c = nullptr) const;
272 /**
273 * Find the intersection of two geodesic segments defined by their
274 * endpoints.
275 *
276 * @param[in] latX1 latitude of first point for segment \e X (degrees).
277 * @param[in] lonX1 longitude of first point for segment \e X (degrees).
278 * @param[in] latX2 latitude of second point for segment \e X (degrees).
279 * @param[in] lonX2 longitude of second point for segment \e X (degrees).
280 * @param[in] latY1 latitude of first point for segment \e Y (degrees).
281 * @param[in] lonY1 longitude of first point for segment \e Y (degrees).
282 * @param[in] latY2 latitude of second point for segment \e Y (degrees).
283 * @param[in] lonY2 longitude of second point for segment \e Y (degrees).
284 * @param[out] segmode an indicator equal to zero if the segments
285 * intersect (see below).
286 * @param[out] c optional pointer to an integer coincidence indicator.
287 * @return \e p the intersection point if the segments intersect, otherwise
288 * the intersection point closest to the midpoints of the two
289 * segments.
290 *
291 * \warning The results are only well defined if there's a \e unique
292 * shortest geodesic between the endpoints of the two segments.
293 *
294 * \e segmode codes up information about the closest intersection in the
295 * case where the segments intersect. Let <i>x</i><sub>12</sub> be the
296 * length of the segment \e X and \e x = <i>p</i>.first, the position of
297 * the intersection on segment \e X. Define
298 * - \e k<sub><i>x</i></sub> = &minus;1, if \e x < 0,
299 * - \e k<sub><i>x</i></sub> = 0,
300 * if 0 &le; \e x &le; <i>x</i><sub>12</sub>,
301 * - \e k<sub><i>x</i></sub> = 1, if <i>x</i><sub>12</sub> < \e x.
302 * .
303 * and similarly for segment \e Y. Then
304 * \e segmode = 3 \e k<sub><i>x</i></sub> + \e k<sub><i>y</i></sub>.
305 **********************************************************************/
306 Point Segment(Math::real latX1, Math::real lonX1,
307 Math::real latX2, Math::real lonX2,
308 Math::real latY1, Math::real lonY1,
309 Math::real latY2, Math::real lonY2,
310 int& segmode, int* c = nullptr) const;
311 /**
312 * Find the intersection of two geodesic segments each defined by a
313 * GeodesicLine.
314 *
315 * @param[in] lineX segment \e X.
316 * @param[in] lineY segment \e Y.
317 * @param[out] segmode an indicator equal to zero if the segments
318 * intersect (see below).
319 * @param[out] c optional pointer to an integer coincidence indicator.
320 * @return \e p the intersection point if the segments intersect, otherwise
321 * the intersection point closest to the midpoints of the two
322 * segments.
323 *
324 * \warning \e lineX and \e lineY must represent shortest geodesics, e.g.,
325 * they can be created by Geodesic::InverseLine. The results are only well
326 * defined if there's a \e unique shortest geodesic between the endpoints
327 * of the two segments.
328 *
329 * \note \e lineX and \e lineY should be created with minimum capabilities
330 * Intersect::LineCaps. The methods for creating a GeodesicLine include
331 * all these capabilities by default.
332 *
333 * See previous definition of Intersect::Segment for more information on \e
334 * segmode.
335 **********************************************************************/
336 Point Segment(const GeodesicLine& lineX, const GeodesicLine& lineY,
337 int& segmode, int* c = nullptr) const;
338 /**
339 * Find the next closest intersection point to a given intersection,
340 * specified by position and two azimuths.
341 *
342 * @param[in] latX latitude of starting points for geodesics \e X and \e Y
343 * (degrees).
344 * @param[in] lonX longitude of starting points for geodesics \e X and \e Y
345 * (degrees).
346 * @param[in] aziX azimuth at starting point for geodesic \e X (degrees).
347 * @param[in] aziY azimuth at starting point for geodesic \e Y (degrees).
348 * @param[out] c optional pointer to an integer coincidence indicator.
349 * @return \e p the next closest intersection point.
350 *
351 * The returned intersection minimizes Intersect::Dist(\e p) (excluding \e
352 * p = [0,0]).
353 *
354 * \note Equidistant closest intersections are surprisingly common. If
355 * this may be a problem, use Intersect::All with a sufficiently large \e
356 * maxdist to capture close intersections.
357 **********************************************************************/
358 Point Next(Math::real latX, Math::real lonX,
359 Math::real aziX, Math::real aziY, int* c = nullptr) const;
360 /**
361 * Find the next closest intersection point to a given intersection,
362 * with each geodesic specified a GeodesicLine.
363 *
364 * @param[in] lineX geodesic \e X.
365 * @param[in] lineY geodesic \e Y.
366 * @param[out] c optional pointer to an integer coincidence indicator.
367 * @return \e p the next closest intersection point.
368 *
369 * \warning \e lineX and \e lineY must both have the same starting point,
370 * i.e., the distance between [<i>lineX</i>.Latitude(),
371 * <i>lineX</i>.Longitude()] and [<i>lineY</i>.Latitude(),
372 * <i>lineY</i>.Longitude()] must be zero.
373 *
374 * \note \e lineX and \e lineY should be created with minimum capabilities
375 * Intersect::LineCaps. The methods for creating a GeodesicLine include
376 * all these capabilities by default.
377 *
378 * \note Equidistant closest intersections are surprisingly common. If
379 * this may be a problem, use Intersect::All with a sufficiently large \e
380 * maxdist to capture close intersections.
381 **********************************************************************/
382 Point Next(const GeodesicLine& lineX, const GeodesicLine& lineY,
383 int* c = nullptr) const;
384 ///@}
385
386 /** \name Finding all intersections
387 **********************************************************************/
388 ///@{
389 /**
390 * Find all intersections within a certain distance, with each geodesic
391 * specified by position and azimuth.
392 *
393 * @param[in] latX latitude of starting point for geodesic \e X (degrees).
394 * @param[in] lonX longitude of starting point for geodesic \e X (degrees).
395 * @param[in] aziX azimuth at starting point for geodesic \e X (degrees).
396 * @param[in] latY latitude of starting point for geodesic \e Y (degrees).
397 * @param[in] lonY longitude of starting point for geodesic \e Y (degrees).
398 * @param[in] aziY azimuth at starting point for geodesic \e Y (degrees).
399 * @param[in] maxdist the maximum distance for the returned intersections
400 * (meters).
401 * @param[out] c vector of coincidences.
402 * @param[in] p0 an optional offset for the starting points (meters),
403 * default = [0,0].
404 * @return \e plist a vector for the intersections closest to \e p0.
405 *
406 * Each intersection point satisfies Intersect::Dist(\e p, \e p0) &le; \e
407 * maxdist. The vector of returned intersections is sorted on the distance
408 * from \e p0.
409 **********************************************************************/
410 std::vector<Point> All(Math::real latX, Math::real lonX, Math::real aziX,
411 Math::real latY, Math::real lonY, Math::real aziY,
412 Math::real maxdist, std::vector<int>& c,
413 const Point& p0 = Point(0, 0))
414 const;
415 /**
416 * Find all intersections within a certain distance, with each geodesic
417 * specified by position and azimuth. Don't return vector of
418 * coincidences.
419 *
420 * @param[in] latX latitude of starting point for geodesic \e X (degrees).
421 * @param[in] lonX longitude of starting point for geodesic \e X (degrees).
422 * @param[in] aziX azimuth at starting point for geodesic \e X (degrees).
423 * @param[in] latY latitude of starting point for geodesic \e Y (degrees).
424 * @param[in] lonY longitude of starting point for geodesic \e Y (degrees).
425 * @param[in] aziY azimuth at starting point for geodesic \e Y (degrees).
426 * @param[in] maxdist the maximum distance for the returned intersections
427 * (meters).
428 * @param[in] p0 an optional offset for the starting points (meters),
429 * default = [0,0].
430 * @return \e plist a vector for the intersections closest to \e p0.
431 *
432 * Each intersection point satisfies Intersect::Dist(\e p, \e p0) &le; \e
433 * maxdist. The vector of returned intersections is sorted on the distance
434 * from \e p0.
435 **********************************************************************/
436 std::vector<Point> All(Math::real latX, Math::real lonX, Math::real aziX,
437 Math::real latY, Math::real lonY, Math::real aziY,
438 Math::real maxdist, const Point& p0 = Point(0, 0))
439 const;
440 /**
441 * Find all intersections within a certain distance, with each geodesic
442 * specified by a GeodesicLine.
443 *
444 * @param[in] lineX geodesic \e X.
445 * @param[in] lineY geodesic \e Y.
446 * @param[in] maxdist the maximum distance for the returned intersections
447 * (meters).
448 * @param[out] c vector of coincidences.
449 * @param[in] p0 an optional offset for the starting points (meters),
450 * default = [0,0].
451 * @return \e plist a vector for the intersections closest to \e p0.
452 *
453 * Each intersection point satisfies Intersect::Dist(\e p, \e p0) &le; \e
454 * maxdist. The vector of returned intersections is sorted on the distance
455 * from \e p0.
456 *
457 * \note \e lineX and \e lineY should be created with minimum capabilities
458 * Intersect::LineCaps. The methods for creating a GeodesicLine include
459 * all these capabilities by default.
460 **********************************************************************/
461 std::vector<Point> All(const GeodesicLine& lineX, const GeodesicLine& lineY,
462 Math::real maxdist, std::vector<int>& c,
463 const Point& p0 = Point(0, 0))
464 const;
465 /**
466 * Find all intersections within a certain distance, with each geodesic
467 * specified by a GeodesicLine. Don't return vector or coincidences.
468 *
469 * @param[in] lineX geodesic \e X.
470 * @param[in] lineY geodesic \e Y.
471 * @param[in] maxdist the maximum distance for the returned intersections
472 * (meters).
473 * @param[in] p0 an optional offset for the starting points (meters),
474 * default = [0,0].
475 * @return \e plist a vector for the intersections closest to \e p0.
476 *
477 * Each intersection point satisfies Intersect::Dist(\e p, \e p0) &le; \e
478 * maxdist. The vector of returned intersections is sorted on the distance
479 * from \e p0.
480 *
481 * \note \e lineX and \e lineY should be created with minimum capabilities
482 * Intersect::LineCaps. The methods for creating a GeodesicLine include
483 * all these capabilities by default.
484 **********************************************************************/
485 std::vector<Point> All(const GeodesicLine& lineX, const GeodesicLine& lineY,
486 Math::real maxdist, const Point& p0 = Point(0, 0))
487 const;
488 ///@}
489
490 /** \name Diagnostic counters
491 **********************************************************************/
492 ///@{
493 /**
494 * @return the cumulative number of invocations of **h**.
495 *
496 * This is a count of the number of times the spherical triangle needs to
497 * be solved. Each involves a call to Geodesic::Inverse and this is a good
498 * metric for the overall cost. This counter is set to zero by the
499 * constructor.
500 *
501 * \warning The counter is a mutable variable and so is not thread safe.
502 **********************************************************************/
503 long long NumInverse() const { return _cnt0; }
504 /**
505 * @return the cumulative number of invocations of **b**.
506 *
507 * This is a count of the number of invocations of the basic algorithm,
508 * which is used by all the intersection methods. This counter is set to
509 * zero by the constructor.
510 *
511 * \warning The counter is a mutable variable and so is not thread safe.
512 **********************************************************************/
513 long long NumBasic() const { return _cnt1; }
514 /**
515 * @return the number of times intersection point was changed in
516 * Intersect::Closest and Intersect::Next.
517 *
518 * If this counter is incremented by just 1 in Intersect::Closest, then the
519 * initial result of the basic algorithm was eventually accepted. This
520 * counter is set to zero by the constructor.
521 *
522 * \note This counter is also incremented by Intersect::Segment, which
523 * calls Intersect::Closest.
524 *
525 * \warning The counter is a mutable variable and so is not thread safe.
526 **********************************************************************/
527 long long NumChange() const { return _cnt2; }
528 /**
529 * @return the number of times a corner point is checked in
530 * Intersect::Segment.
531 *
532 * This counter is set to zero by the constructor.
533 *
534 * \warning The counter is a mutable variable and so is not thread safe.
535 **********************************************************************/
536 long long NumCorner() const { return _cnt3; }
537 /**
538 * @return the number of times a corner point is returned by
539 * Intersect::Segment.
540 *
541 * This counter is set to zero by the constructor.
542 *
543 * \note A conjecture is that a corner point never results in an
544 * intersection that overrides the intersection closest to the midpoints of
545 * the segments; i.e., NumCorner() always returns 0.
546 *
547 * \warning The counter is a mutable variable and so is not thread safe.
548 **********************************************************************/
549 long long NumOverride() const { return _cnt4; }
550 ///@}
551
552 /** \name Insepctor function
553 **********************************************************************/
554 ///@{
555 /**
556 * @return \e geod the Geodesic object used in the constructor.
557 *
558 * This can be used to query Geodesic::EquatorialRadius(),
559 * Geodesic::Flattening(), Geodesic::Exact(), and
560 * Geodesic::EllipsoidArea().
561 **********************************************************************/
562 const Geodesic& GeodesicObject() const { return _geod; }
563 ///@}
564
565 /**
566 * The L1 distance.
567 *
568 * @param[in] p the position along geodesics \e X and \e Y.
569 * @param[in] p0 [optional] the reference position, default = [0, 0].
570
571 * @return the L1 distance of \e p from \e p0, i.e.,
572 * |<i>p</i><sub><i>x</i></sub> &minus; <i>p0</i><sub><i>x</i></sub>| +
573 * |<i>p</i><sub><i>y</i></sub> &minus; <i>p0</i><sub><i>y</i></sub>|.
574 **********************************************************************/
575 static Math::real Dist(const Point& p, const Point& p0 = Point(0, 0)) {
576 using std::fabs;
577 return fabs(p.first - p0.first) + fabs(p.second - p0.second);
578 }
579 };
580
581} // namespace GeographicLib
582
583#endif // GEOGRAPHICLIB_INTERSECT_HPP
#define GEOGRAPHICLIB_EXPORT
Definition: Constants.hpp:67
GeographicLib::Math::real real
Definition: GeodSolve.cpp:29
Header for GeographicLib::GeodesicLine class.
Header for GeographicLib::Geodesic class.
Header for GeographicLib::Math class.
Geodesic calculations
Definition: Geodesic.hpp:175
Geodesic intersections
Definition: Intersect.hpp:70
const Geodesic & GeodesicObject() const
Definition: Intersect.hpp:562
long long NumChange() const
Definition: Intersect.hpp:527
long long NumBasic() const
Definition: Intersect.hpp:513
long long NumInverse() const
Definition: Intersect.hpp:503
static Math::real Dist(const Point &p, const Point &p0=Point(0, 0))
Definition: Intersect.hpp:575
std::pair< Math::real, Math::real > Point
Definition: Intersect.hpp:78
long long NumOverride() const
Definition: Intersect.hpp:549
long long NumCorner() const
Definition: Intersect.hpp:536
Namespace for GeographicLib.
Definition: Accumulator.cpp:12