GEOS  3.11.0beta2
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 
35 // Forward declarations
36 namespace geos {
37 namespace geom {
38 class CoordinateSequence;
39 class GeometryFactory;
40 class LineString;
41 }
42 }
43 
44 namespace geos {
45 namespace geom { // geos::geom
46 
60 class GEOS_DLL LineSegment {
61 public:
62 
63  Coordinate p0;
65 
66  friend std::ostream& operator<< (std::ostream& o, const LineSegment& l);
67 
69  friend bool operator==(const LineSegment& a, const LineSegment& b)
70  {
71  return a.p0 == b.p0 && a.p1 == b.p1;
72  };
73 
74  LineSegment(const Coordinate& c0, const Coordinate& c1)
75  : p0(c0)
76  , p1(c1)
77  {};
78 
79  LineSegment(double x0, double y0, double x1, double y1)
80  : p0(x0, y0)
81  , p1(x1, y1)
82  {};
83 
84  LineSegment() {};
85 
86 
87  void setCoordinates(const Coordinate& c0, const Coordinate& c1)
88  {
89  p0 = c0;
90  p1 = c1;
91  };
92 
93  void setCoordinates(const LineSegment& ls)
94  {
95  setCoordinates(ls.p0, ls.p1);
96  };
97 
98  // obsoleted, use operator[] instead
99  //const Coordinate& getCoordinate(std::size_t i) const;
100 
101  const Coordinate& operator[](std::size_t i) const
102  {
103  if(i == 0) {
104  return p0;
105  }
106  assert(i == 1);
107  return p1;
108  };
109 
110  Coordinate& operator[](std::size_t i)
111  {
112  if(i == 0) {
113  return p0;
114  }
115  assert(i == 1);
116  return p1;
117  };
118 
120  double getLength() const
121  {
122  return p0.distance(p1);
123  };
124 
129  bool isHorizontal() const
130  {
131  return p0.y == p1.y;
132  };
133 
138  bool isVertical() const
139  {
140  return p0.x == p1.x;
141  };
142 
164  int orientationIndex(const LineSegment& seg) const;
165 
166  // TODO deprecate this
167  int orientationIndex(const LineSegment* seg) const
168  {
169  assert(seg);
170  return orientationIndex(*seg);
171  };
172 
173 
174 
191  int orientationIndex(const Coordinate& p) const
192  {
193  return algorithm::Orientation::index(p0, p1, p);
194  };
195 
197  void reverse();
198 
200  //
204  void normalize()
205  {
206  if(p1.compareTo(p0) < 0) {
207  reverse();
208  }
209  };
210 
212  double angle() const
213  {
214  return std::atan2(p1.y - p0.y, p1.x - p0.x);
215  };
216 
218  //
221  void midPoint(Coordinate& ret) const
222  {
223  ret = Coordinate(
224  (p0.x + p1.x) / 2,
225  (p0.y + p1.y) / 2);
226  };
227 
229  double distance(const LineSegment& ls) const
230  {
231  return algorithm::Distance::segmentToSegment(p0, p1, ls.p0, ls.p1);
232  };
233 
235  double distance(const Coordinate& p) const
236  {
237  return algorithm::Distance::pointToSegment(p, p0, p1);
238  };
239 
244  double distancePerpendicular(const Coordinate& p) const
245  {
247  };
248 
263  void pointAlong(double segmentLengthFraction, Coordinate& ret) const
264  {
265  ret = Coordinate(
266  p0.x + segmentLengthFraction * (p1.x - p0.x),
267  p0.y + segmentLengthFraction * (p1.y - p0.y));
268  };
269 
294  void pointAlongOffset(double segmentLengthFraction,
295  double offsetDistance,
296  Coordinate& ret) const;
297 
298 
311  LineSegment offset(double offsetDistance);
312 
313 
331  double projectionFactor(const Coordinate& p) const;
332 
348  double segmentFraction(const Coordinate& inputPt) const;
349 
358  void project(const Coordinate& p, Coordinate& ret) const;
359 
375  bool project(const LineSegment& seg, LineSegment& ret) const;
376 
378  //
383  void closestPoint(const Coordinate& p, Coordinate& ret) const;
384 
396  int compareTo(const LineSegment& other) const;
397 
407  bool equalsTopo(const LineSegment& other) const;
408 
415  std::array<Coordinate, 2> closestPoints(const LineSegment& line);
416 
417  std::array<Coordinate, 2> closestPoints(const LineSegment* line)
418  {
419  assert(line);
420  return closestPoints(*line);
421  }
422 
435  Coordinate intersection(const LineSegment& line) const;
436 
454 
461  std::unique_ptr<LineString> toGeometry(const GeometryFactory& gf) const;
462 
463  struct HashCode {
464  std::size_t operator()(const LineSegment & s) const {
465  std::size_t h = std::hash<double>{}(s.p0.x);
466  h ^= (std::hash<double>{}(s.p0.y) << 1);
467  h ^= (std::hash<double>{}(s.p1.x) << 1);
468  return h ^ (std::hash<double>{}(s.p1.y) << 1);
469  }
470  };
471 
472 private:
473  void project(double factor, Coordinate& ret) const;
474 
475 };
476 
477 // std::ostream& operator<< (std::ostream& o, const LineSegment& l);
478 
479 
480 
481 } // namespace geos::geom
482 } // namespace geos
483 
484 
485 
486 
487 
488 
489 
490 
491 
492 
493 
494 
495 
496 
497 
498 
499 
500 
501 
502 
503 
504 
505 
static double pointToLinePerpendicular(const geom::Coordinate &p, const geom::Coordinate &A, const geom::Coordinate &B)
static double segmentToSegment(const geom::Coordinate &A, const geom::Coordinate &B, const geom::Coordinate &C, const geom::Coordinate &D)
static double pointToSegment(const geom::Coordinate &p, const geom::Coordinate &A, const geom::Coordinate &B)
static int index(const geom::Coordinate &p1, const geom::Coordinate &p2, const geom::Coordinate &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:58
double distance(const Coordinate &p) const
Definition: Coordinate.h:191
double y
y-coordinate
Definition: Coordinate.h:81
double x
x-coordinate
Definition: Coordinate.h:78
int compareTo(const Coordinate &other) const
TODO: deprecate this, move logic to CoordinateLessThen instead.
Definition: Coordinate.h:161
Supplies a set of utility methods for building Geometry objects from CoordinateSequence or other Geom...
Definition: GeometryFactory.h:66
Definition: LineSegment.h:60
void closestPoint(const Coordinate &p, Coordinate &ret) const
Computes the closest point on this line segment to another point.
bool isVertical() const
Definition: LineSegment.h:138
double distancePerpendicular(const Coordinate &p) const
Computes the perpendicular distance between the (infinite) line defined by this line segment and a po...
Definition: LineSegment.h:244
void midPoint(Coordinate &ret) const
Computes the midpoint of the segment.
Definition: LineSegment.h:221
int compareTo(const LineSegment &other) const
Compares this object with the specified object for order.
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 projectionFactor(const Coordinate &p) const
Compute the projection factor for the projection of the point p onto this LineSegment.
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:263
void project(const Coordinate &p, Coordinate &ret) const
Compute the projection of a point onto the line determined by this line segment.
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.
double distance(const Coordinate &p) const
Computes the distance between this line segment and a point.
Definition: LineSegment.h:235
double distance(const LineSegment &ls) const
Computes the distance between this line segment and another one.
Definition: LineSegment.h:229
int orientationIndex(const LineSegment &seg) const
void normalize()
Puts the line segment into a normalized form.
Definition: LineSegment.h:204
bool isHorizontal() const
Definition: LineSegment.h:129
double getLength() const
Computes the length of the line segment.
Definition: LineSegment.h:120
Coordinate p1
Segment start.
Definition: LineSegment.h:64
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)
friend bool operator==(const LineSegment &a, const LineSegment &b)
Checks if two LineSegment are equal (2D only check)
Definition: LineSegment.h:69
int orientationIndex(const Coordinate &p) const
Determines the orientation index of a Coordinate relative to this segment.
Definition: LineSegment.h:191
double angle() const
Definition: LineSegment.h:212
Coordinate intersection(const LineSegment &line) const
std::array< Coordinate, 2 > closestPoints(const LineSegment &line)
double segmentFraction(const Coordinate &inputPt) const
Computes the fraction of distance (in [0.0, 1.0]) that the projection of a point occurs along this li...
Basic namespace for all GEOS functionalities.
Definition: Angle.h:25