GEOS 3.15.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
37namespace geos {
38namespace geom {
39class CoordinateSequence;
40class GeometryFactory;
41class LineString;
42}
43}
44
45namespace geos {
46namespace geom { // geos::geom
47
61class GEOS_DLL LineSegment {
62public:
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 //
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);
291 return algorithm::Distance::pointToLinePerpendicular(p, p0, p1);
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
329 static CoordinateXY pointAlong(double segmentLengthFraction, const CoordinateXY& p0, const CoordinateXY& p1)
330 {
331 return { p0.x + segmentLengthFraction * (p1.x - p0.x),
332 p0.y + segmentLengthFraction * (p1.y - p0.y) };
333 }
334
335 static Coordinate pointAlong(double segmentLengthFraction, const Coordinate& p0, const Coordinate& p1)
336 {
337 return { p0.x + segmentLengthFraction * (p1.x - p0.x),
338 p0.y + segmentLengthFraction * (p1.y - p0.y),
339 p0.z + segmentLengthFraction * (p1.z - p0.z) };
340 }
341
342 static CoordinateXYM pointAlong(double segmentLengthFraction, const CoordinateXYM& p0, const CoordinateXYM& p1)
343 {
344 return { p0.x + segmentLengthFraction * (p1.x - p0.x),
345 p0.y + segmentLengthFraction * (p1.y - p0.y),
346 p0.m + segmentLengthFraction * (p1.m - p0.m) };
347 }
348
349 static CoordinateXYZM pointAlong(double segmentLengthFraction, const CoordinateXYZM& p0, const CoordinateXYZM& p1)
350 {
351 return { p0.x + segmentLengthFraction * (p1.x - p0.x),
352 p0.y + segmentLengthFraction * (p1.y - p0.y),
353 p0.z + segmentLengthFraction * (p1.z - p0.z),
354 p0.m + segmentLengthFraction * (p1.m - p0.m) };
355 }
356
381 void pointAlongOffset(double segmentLengthFraction,
382 double offsetDistance,
383 Coordinate& ret) const;
384
385
398 LineSegment offset(double offsetDistance);
399
400
418 double projectionFactor(const CoordinateXY& p) const;
419
420 static double projectionFactor(const CoordinateXY& p0, const CoordinateXY& p1, const CoordinateXY& q);
421
437 double segmentFraction(const CoordinateXY& inputPt) const;
438
447 void project(const Coordinate& p, Coordinate& ret) const;
448
449 CoordinateXY project(const CoordinateXY& p) const;
450
451 static CoordinateXY project(const CoordinateXY& p0, const CoordinateXY& p1, const CoordinateXY& q);
452
468 bool project(const LineSegment& seg, LineSegment& ret) const;
469
471 //
476 void closestPoint(const CoordinateXY& p, CoordinateXY& ret) const;
477
478 static CoordinateXY closestPoint(const CoordinateXY& p0, const CoordinateXY& p1,
479 const CoordinateXY& q);
480
490 bool equalsTopo(const LineSegment& other) const;
491
498 std::array<Coordinate, 2> closestPoints(const LineSegment& line);
499
500 std::array<Coordinate, 2> closestPoints(const LineSegment* line)
501 {
502 assert(line);
503 return closestPoints(*line);
504 }
505
506 static std::array<CoordinateXY, 2> closestPoints(const CoordinateXY& p0,
507 const CoordinateXY& p1,
508 const CoordinateXY& q0,
509 const CoordinateXY& q1);
510
524
542
549 std::unique_ptr<LineString> toGeometry(const GeometryFactory& gf) const;
550
551
563 inline int compareTo(const LineSegment& other) const
564 {
565 int comp0 = p0.compareTo(other.p0);
566 if (comp0 != 0) {
567 return comp0;
568 }
569 return p1.compareTo(other.p1);
570 }
571
572 std::ostream& operator<< (std::ostream& o);
573
574 inline bool operator==(const LineSegment& rhs) const {
575 return compareTo(rhs) == 0;
576 };
577
578 inline bool operator<(const LineSegment& rhs) const {
579 return compareTo(rhs) < 0;
580 };
581
582 inline bool operator>(const LineSegment& rhs) const {
583 return compareTo(rhs) > 0;
584 };
585
586 struct HashCode {
587 inline std::size_t operator()(const LineSegment & s) const {
588 std::size_t h = std::hash<double>{}(s.p0.x);
589 h ^= (std::hash<double>{}(s.p0.y) << 1);
590 h ^= (std::hash<double>{}(s.p1.x) << 1);
591 return h ^ (std::hash<double>{}(s.p1.y) << 1);
592 }
593
594 inline std::size_t operator()(const LineSegment * s) const {
595 std::size_t h = std::hash<double>{}(s->p0.x);
596 h ^= (std::hash<double>{}(s->p0.y) << 1);
597 h ^= (std::hash<double>{}(s->p1.x) << 1);
598 return h ^ (std::hash<double>{}(s->p1.y) << 1);
599 }
600
601 };
602
603 using UnorderedSet = std::unordered_set<LineSegment, HashCode>;
604
605
606private:
607 static CoordinateXY project(const CoordinateXY& p0, const CoordinateXY& p1, double factor);
608
609 void project(double factor, CoordinateXY& ret) const;
610
611};
612
613
614// std::ostream& operator<< (std::ostream& o, const LineSegment& l);
615
616
617} // namespace geos::geom
618} // namespace geos
Coordinate is the lightweight class used to store coordinates.
Definition Coordinate.h:220
double z
z-coordinate
Definition Coordinate.h:244
Supplies a set of utility methods for building Geometry objects from CoordinateSequence or other Geom...
Definition GeometryFactory.h:71
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:563
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.
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
std::unique_ptr< LineString > toGeometry(const GeometryFactory &gf) const
void normalize()
Puts the line segment into a normalized form.
Definition LineSegment.h:236
std::array< Coordinate, 2 > closestPoints(const LineSegment &line)
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
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.
Basic namespace for all GEOS functionalities.
Definition geos.h:38