GEOS 3.12.0
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
250 //
253 void midPoint(Coordinate& ret) const
254 {
255 ret = Coordinate(
256 (p0.x + p1.x) / 2,
257 (p0.y + p1.y) / 2);
258 };
259
261 double distance(const LineSegment& ls) const
262 {
263 return algorithm::Distance::segmentToSegment(p0, p1, ls.p0, ls.p1);
264 };
265
267 double distance(const CoordinateXY& p) const
268 {
269 return algorithm::Distance::pointToSegment(p, p0, p1);
270 };
271
281 double distancePerpendicular(const CoordinateXY& p) const
282 {
283 if (p0.equals2D(p1))
284 return p0.distance(p);
285 return algorithm::Distance::pointToLinePerpendicular(p, p0, p1);
286 };
287
299 double distancePerpendicularOriented(const CoordinateXY& p) const;
300
315 void pointAlong(double segmentLengthFraction, Coordinate& ret) const
316 {
317 ret = Coordinate(
318 p0.x + segmentLengthFraction * (p1.x - p0.x),
319 p0.y + segmentLengthFraction * (p1.y - p0.y));
320 };
321
346 void pointAlongOffset(double segmentLengthFraction,
347 double offsetDistance,
348 Coordinate& ret) const;
349
350
363 LineSegment offset(double offsetDistance);
364
365
383 double projectionFactor(const CoordinateXY& p) const;
384
400 double segmentFraction(const CoordinateXY& inputPt) const;
401
410 void project(const Coordinate& p, Coordinate& ret) const;
411
412 CoordinateXY project(const CoordinateXY& p) const;
413
429 bool project(const LineSegment& seg, LineSegment& ret) const;
430
432 //
437 void closestPoint(const CoordinateXY& p, CoordinateXY& ret) const;
438
448 bool equalsTopo(const LineSegment& other) const;
449
456 std::array<Coordinate, 2> closestPoints(const LineSegment& line);
457
458 std::array<Coordinate, 2> closestPoints(const LineSegment* line)
459 {
460 assert(line);
461 return closestPoints(*line);
462 }
463
477
495
502 std::unique_ptr<LineString> toGeometry(const GeometryFactory& gf) const;
503
504
516 inline int compareTo(const LineSegment& other) const
517 {
518 int comp0 = p0.compareTo(other.p0);
519 if (comp0 != 0) {
520 return comp0;
521 }
522 return p1.compareTo(other.p1);
523 }
524
525 std::ostream& operator<< (std::ostream& o);
526
527 inline bool operator==(const LineSegment& rhs) const {
528 return compareTo(rhs) == 0;
529 };
530
531 inline bool operator<(const LineSegment& rhs) const {
532 return compareTo(rhs) < 0;
533 };
534
535 inline bool operator>(const LineSegment& rhs) const {
536 return compareTo(rhs) > 0;
537 };
538
539 struct HashCode {
540 inline std::size_t operator()(const LineSegment & s) const {
541 std::size_t h = std::hash<double>{}(s.p0.x);
542 h ^= (std::hash<double>{}(s.p0.y) << 1);
543 h ^= (std::hash<double>{}(s.p1.x) << 1);
544 return h ^ (std::hash<double>{}(s.p1.y) << 1);
545 }
546
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 };
555
556 using UnorderedSet = std::unordered_set<LineSegment, HashCode>;
557
558
559private:
560 void project(double factor, CoordinateXY& ret) const;
561
562};
563
564
565// std::ostream& operator<< (std::ostream& o, const LineSegment& l);
566
567
568} // namespace geos::geom
569} // namespace geos
Coordinate is the lightweight class used to store coordinates.
Definition Coordinate.h:216
Supplies a set of utility methods for building Geometry objects from CoordinateSequence or other Geom...
Definition GeometryFactory.h:65
Definition LineSegment.h:61
bool isVertical() const
Definition LineSegment.h:156
LineSegment(const Coordinate &c0, const Coordinate &c1)
Segment end.
Definition LineSegment.h:68
void midPoint(Coordinate &ret) const
Computes the midpoint of the segment.
Definition LineSegment.h:253
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:516
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:315
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.
double distance(const LineSegment &ls) const
Computes the distance between this line segment and another one.
Definition LineSegment.h:261
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:281
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:267
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:39