GEOS  3.14.0dev
LineSegment.h
1 /**********************************************************************
2  *
3  * GEOS - Geometry Engine Open Source
4  * http://geos.osgeo.org
5  *
6  * Copyright (C) 2009 2011 Sandro Santilli <strk@kbt.io>
7  * Copyright (C) 2005-2006 Refractions Research Inc.
8  * Copyright (C) 2001-2002 Vivid Solutions Inc.
9  *
10  * This is free software; you can redistribute and/or modify it under
11  * the terms of the GNU Lesser General Public Licence as published
12  * by the Free Software Foundation.
13  * See the COPYING file for more information.
14  *
15  **********************************************************************
16  *
17  * Last port: geom/LineSegment.java r18 (JTS-1.11)
18  *
19  **********************************************************************/
20 
21 #pragma once
22 
23 #include <geos/export.h>
24 #include <geos/geom/Coordinate.h> // for composition
25 #include <geos/geom/LineSegment.h>
26 #include <geos/algorithm/Distance.h>
27 #include <geos/algorithm/Orientation.h>
28 
29 #include <array>
30 #include <iostream> // for ostream
31 #include <functional> // for std::hash
32 #include <memory> // for unique_ptr
33 #include <cassert>
34 #include <unordered_set>
35 
36 // Forward declarations
37 namespace geos {
38 namespace geom {
39 class CoordinateSequence;
40 class GeometryFactory;
41 class LineString;
42 }
43 }
44 
45 namespace geos {
46 namespace geom { // geos::geom
47 
61 class GEOS_DLL LineSegment {
62 public:
63 
64 
65  Coordinate p0;
67 
68  LineSegment(const Coordinate& c0, const Coordinate& c1)
69  : p0(c0)
70  , p1(c1)
71  {};
72 
73  LineSegment(double x0, double y0, double x1, double y1)
74  : p0(x0, y0)
75  , p1(x1, y1)
76  {};
77 
78  LineSegment() {};
79 
80 
81  void setCoordinates(const Coordinate& c0, const Coordinate& c1)
82  {
83  p0 = c0;
84  p1 = c1;
85  };
86 
87  void setCoordinates(const LineSegment& ls)
88  {
89  setCoordinates(ls.p0, ls.p1);
90  };
91 
92  // obsoleted, use operator[] instead
93  //const Coordinate& getCoordinate(std::size_t i) const;
94 
95  const Coordinate& operator[](std::size_t i) const
96  {
97  if(i == 0) {
98  return p0;
99  }
100  assert(i == 1);
101  return p1;
102  };
103 
104  Coordinate& operator[](std::size_t i)
105  {
106  if(i == 0) {
107  return p0;
108  }
109  assert(i == 1);
110  return p1;
111  };
112 
114  double minX() const
115  {
116  return std::min(p0.x, p1.x);
117  };
118 
120  double maxX() const
121  {
122  return std::max(p0.x, p1.x);
123  };
124 
126  double minY() const
127  {
128  return std::min(p0.y, p1.y);
129  };
130 
132  double maxY() const
133  {
134  return std::max(p0.y, p1.y);
135  };
136 
138  double getLength() const
139  {
140  return p0.distance(p1);
141  };
142 
147  bool isHorizontal() const
148  {
149  return p0.y == p1.y;
150  };
151 
156  bool isVertical() const
157  {
158  return p0.x == p1.x;
159  };
160 
182  int orientationIndex(const LineSegment& seg) const;
183 
184  // TODO deprecate this
185  int orientationIndex(const LineSegment* seg) const
186  {
187  assert(seg);
188  return orientationIndex(*seg);
189  };
190 
202  int orientationIndex(const CoordinateXY& p) const
203  {
204  return algorithm::Orientation::index(p0, p1, p);
205  }
206 
223  int orientationIndex(const Coordinate& p) const
224  {
225  return algorithm::Orientation::index(p0, p1, p);
226  };
227 
229  void reverse();
230 
232  //
236  void normalize()
237  {
238  if(p1.compareTo(p0) < 0) {
239  reverse();
240  }
241  };
242 
244  double angle() const
245  {
246  return std::atan2(p1.y - p0.y, p1.x - p0.x);
247  };
248 
254  CoordinateXY midPoint() const
255  {
256  return midPoint(p0, p1);
257  };
258 
259  static CoordinateXY midPoint(const CoordinateXY& pt0, const CoordinateXY& pt1)
260  {
261  return CoordinateXY(
262  (pt0.x + pt1.x) / 2,
263  (pt0.y + pt1.y) / 2);
264  }
265 
267  double distance(const LineSegment& ls) const
268  {
269  return algorithm::Distance::segmentToSegment(p0, p1, ls.p0, ls.p1);
270  };
271 
273  double distance(const CoordinateXY& p) const
274  {
275  return algorithm::Distance::pointToSegment(p, p0, p1);
276  };
277 
287  double distancePerpendicular(const CoordinateXY& p) const
288  {
289  if (p0.equals2D(p1))
290  return p0.distance(p);
292  };
293 
305  double distancePerpendicularOriented(const CoordinateXY& p) const;
306 
321  void pointAlong(double segmentLengthFraction, Coordinate& ret) const
322  {
323  ret = Coordinate(
324  p0.x + segmentLengthFraction * (p1.x - p0.x),
325  p0.y + segmentLengthFraction * (p1.y - p0.y),
326  p0.z + segmentLengthFraction * (p1.z - p0.z));
327  };
328 
353  void pointAlongOffset(double segmentLengthFraction,
354  double offsetDistance,
355  Coordinate& ret) const;
356 
357 
370  LineSegment offset(double offsetDistance);
371 
372 
390  double projectionFactor(const CoordinateXY& p) const;
391 
407  double segmentFraction(const CoordinateXY& inputPt) const;
408 
417  void project(const Coordinate& p, Coordinate& ret) const;
418 
419  CoordinateXY project(const CoordinateXY& p) const;
420 
436  bool project(const LineSegment& seg, LineSegment& ret) const;
437 
439  //
444  void closestPoint(const CoordinateXY& p, CoordinateXY& ret) const;
445 
455  bool equalsTopo(const LineSegment& other) const;
456 
463  std::array<Coordinate, 2> closestPoints(const LineSegment& line);
464 
465  std::array<Coordinate, 2> closestPoints(const LineSegment* line)
466  {
467  assert(line);
468  return closestPoints(*line);
469  }
470 
483  Coordinate intersection(const LineSegment& line) const;
484 
502 
509  std::unique_ptr<LineString> toGeometry(const GeometryFactory& gf) const;
510 
511 
523  inline int compareTo(const LineSegment& other) const
524  {
525  int comp0 = p0.compareTo(other.p0);
526  if (comp0 != 0) {
527  return comp0;
528  }
529  return p1.compareTo(other.p1);
530  }
531 
532  std::ostream& operator<< (std::ostream& o);
533 
534  inline bool operator==(const LineSegment& rhs) const {
535  return compareTo(rhs) == 0;
536  };
537 
538  inline bool operator<(const LineSegment& rhs) const {
539  return compareTo(rhs) < 0;
540  };
541 
542  inline bool operator>(const LineSegment& rhs) const {
543  return compareTo(rhs) > 0;
544  };
545 
546  struct HashCode {
547  inline std::size_t operator()(const LineSegment & s) const {
548  std::size_t h = std::hash<double>{}(s.p0.x);
549  h ^= (std::hash<double>{}(s.p0.y) << 1);
550  h ^= (std::hash<double>{}(s.p1.x) << 1);
551  return h ^ (std::hash<double>{}(s.p1.y) << 1);
552  }
553 
554  inline std::size_t operator()(const LineSegment * s) const {
555  std::size_t h = std::hash<double>{}(s->p0.x);
556  h ^= (std::hash<double>{}(s->p0.y) << 1);
557  h ^= (std::hash<double>{}(s->p1.x) << 1);
558  return h ^ (std::hash<double>{}(s->p1.y) << 1);
559  }
560 
561  };
562 
563  using UnorderedSet = std::unordered_set<LineSegment, HashCode>;
564 
565 
566 private:
567  void project(double factor, CoordinateXY& ret) const;
568 
569 };
570 
571 
572 // std::ostream& operator<< (std::ostream& o, const LineSegment& l);
573 
574 
575 } // namespace geos::geom
576 } // namespace geos
static double pointToSegment(const geom::CoordinateXY &p, const geom::CoordinateXY &A, const geom::CoordinateXY &B)
static double segmentToSegment(const geom::CoordinateXY &A, const geom::CoordinateXY &B, const geom::CoordinateXY &C, const geom::CoordinateXY &D)
static double pointToLinePerpendicular(const geom::CoordinateXY &p, const geom::CoordinateXY &A, const geom::CoordinateXY &B)
static int index(const geom::CoordinateXY &p1, const geom::CoordinateXY &p2, const geom::CoordinateXY &q)
Returns the orientation index of the direction of the point q relative to a directed infinite line sp...
Coordinate is the lightweight class used to store coordinates.
Definition: Coordinate.h:217
double z
z-coordinate
Definition: Coordinate.h:241
Supplies a set of utility methods for building Geometry objects from CoordinateSequence or other Geom...
Definition: GeometryFactory.h:70
Definition: LineSegment.h:61
bool isVertical() const
Definition: LineSegment.h:156
LineSegment(const Coordinate &c0, const Coordinate &c1)
Segment end.
Definition: LineSegment.h:68
double minX() const
gets the minimum X ordinate value
Definition: LineSegment.h:114
int compareTo(const LineSegment &other) const
Compares this object with the specified object for order.
Definition: LineSegment.h:523
int orientationIndex(const CoordinateXY &p) const
Definition: LineSegment.h:202
void pointAlongOffset(double segmentLengthFraction, double offsetDistance, Coordinate &ret) const
Computes the Coordinate that lies a given fraction along the line defined by this segment and offset ...
bool project(const LineSegment &seg, LineSegment &ret) const
Project a line segment onto this line segment and return the resulting line segment.
std::unique_ptr< LineString > toGeometry(const GeometryFactory &gf) const
double minY() const
gets the minimum Y ordinate value
Definition: LineSegment.h:126
void pointAlong(double segmentLengthFraction, Coordinate &ret) const
Computes the Coordinate that lies a given fraction along the line defined by this segment.
Definition: LineSegment.h:321
void project(const Coordinate &p, Coordinate &ret) const
Compute the projection of a point onto the line determined by this line segment.
double maxX() const
gets the maximum X ordinate value
Definition: LineSegment.h:120
bool equalsTopo(const LineSegment &other) const
Returns true if other is topologically equal to this LineSegment (e.g. irrespective of orientation).
void reverse()
Reverses the direction of the line segment.
CoordinateXY midPoint() const
Computes the midpoint of the segment.
Definition: LineSegment.h:254
double distance(const LineSegment &ls) const
Computes the distance between this line segment and another one.
Definition: LineSegment.h:267
int orientationIndex(const LineSegment &seg) const
void normalize()
Puts the line segment into a normalized form.
Definition: LineSegment.h:236
bool isHorizontal() const
Definition: LineSegment.h:147
double getLength() const
Computes the length of the line segment.
Definition: LineSegment.h:138
Coordinate p1
Segment start.
Definition: LineSegment.h:66
double distancePerpendicular(const CoordinateXY &p) const
Definition: LineSegment.h:287
Coordinate lineIntersection(const LineSegment &line) const
Computes the intersection point of the lines defined by two segments, if there is one.
LineSegment offset(double offsetDistance)
int orientationIndex(const Coordinate &p) const
Determines the orientation index of a Coordinate relative to this segment.
Definition: LineSegment.h:223
double angle() const
Definition: LineSegment.h:244
Coordinate intersection(const LineSegment &line) const
double maxY() const
gets the maximum Y ordinate value
Definition: LineSegment.h:132
std::array< Coordinate, 2 > closestPoints(const LineSegment &line)
double distance(const CoordinateXY &p) const
Computes the distance between this line segment and a point.
Definition: LineSegment.h:273
void closestPoint(const CoordinateXY &p, CoordinateXY &ret) const
Computes the closest point on this line segment to another point.
double distancePerpendicularOriented(const CoordinateXY &p) const
double segmentFraction(const CoordinateXY &inputPt) const
Computes the fraction of distance (in [0.0, 1.0]) that the projection of a point occurs along this li...
double projectionFactor(const CoordinateXY &p) const
Compute the projection factor for the projection of the point p onto this LineSegment.
bool operator<(const CoordinateXY &a, const CoordinateXY &b)
Strict weak ordering operator for Coordinate.
Definition: Coordinate.h:458
Basic namespace for all GEOS functionalities.
Definition: Angle.h:25