LineSegment.h
/**********************************************************************
*
* GEOS - Geometry Engine Open Source
* http://geos.osgeo.org
*
* Copyright (C) 2009 2011 Sandro Santilli <strk@kbt.io>
* Copyright (C) 2005-2006 Refractions Research Inc.
* Copyright (C) 2001-2002 Vivid Solutions Inc.
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU Lesser General Public Licence as published
* by the Free Software Foundation.
* See the COPYING file for more information.
*
**********************************************************************
*
* Last port: geom/LineSegment.java r18 (JTS-1.11)
*
**********************************************************************/
#pragma once
#include <geos/export.h>
#include <geos/geom/Coordinate.h> // for composition
#include <geos/geom/LineSegment.h>
#include <geos/algorithm/Distance.h>
#include <geos/algorithm/Orientation.h>
#include <array>
#include <iostream> // for ostream
#include <functional> // for std::hash
#include <memory> // for unique_ptr
#include <cassert>
#include <unordered_set>
// Forward declarations
namespace geos {
namespace geom {
class CoordinateSequence;
class GeometryFactory;
class LineString;
}
}
namespace geos {
namespace geom { // geos::geom
class GEOS_DLL LineSegment {
public:
Coordinate p0;
Coordinate p1;
LineSegment(const Coordinate& c0, const Coordinate& c1)
: p0(c0)
, p1(c1)
{};
LineSegment(double x0, double y0, double x1, double y1)
: p0(x0, y0)
, p1(x1, y1)
{};
LineSegment() {};
void setCoordinates(const Coordinate& c0, const Coordinate& c1)
{
p0 = c0;
p1 = c1;
};
void setCoordinates(const LineSegment& ls)
{
setCoordinates(ls.p0, ls.p1);
};
// obsoleted, use operator[] instead
//const Coordinate& getCoordinate(std::size_t i) const;
const Coordinate& operator[](std::size_t i) const
{
if(i == 0) {
return p0;
}
assert(i == 1);
return p1;
};
Coordinate& operator[](std::size_t i)
{
if(i == 0) {
return p0;
}
assert(i == 1);
return p1;
};
double minX() const
{
return std::min(p0.x, p1.x);
};
double maxX() const
{
return std::max(p0.x, p1.x);
};
double minY() const
{
return std::min(p0.y, p1.y);
};
double maxY() const
{
return std::max(p0.y, p1.y);
};
double getLength() const
{
return p0.distance(p1);
};
bool isHorizontal() const
{
return p0.y == p1.y;
};
bool isVertical() const
{
return p0.x == p1.x;
};
int orientationIndex(const LineSegment& seg) const;
// TODO deprecate this
int orientationIndex(const LineSegment* seg) const
{
assert(seg);
return orientationIndex(*seg);
};
int orientationIndex(const CoordinateXY& p) const
{
return algorithm::Orientation::index(p0, p1, p);
}
int orientationIndex(const Coordinate& p) const
{
return algorithm::Orientation::index(p0, p1, p);
};
void reverse();
//
void normalize()
{
if(p1.compareTo(p0) < 0) {
reverse();
}
};
double angle() const
{
return std::atan2(p1.y - p0.y, p1.x - p0.x);
};
CoordinateXY midPoint() const
{
return midPoint(p0, p1);
};
static CoordinateXY midPoint(const CoordinateXY& pt0, const CoordinateXY& pt1)
{
return CoordinateXY(
(pt0.x + pt1.x) / 2,
(pt0.y + pt1.y) / 2);
}
double distance(const LineSegment& ls) const
{
return algorithm::Distance::segmentToSegment(p0, p1, ls.p0, ls.p1);
};
double distance(const CoordinateXY& p) const
{
return algorithm::Distance::pointToSegment(p, p0, p1);
};
double distancePerpendicular(const CoordinateXY& p) const
{
if (p0.equals2D(p1))
return p0.distance(p);
return algorithm::Distance::pointToLinePerpendicular(p, p0, p1);
};
double distancePerpendicularOriented(const CoordinateXY& p) const;
void pointAlong(double segmentLengthFraction, Coordinate& ret) const
{
ret = Coordinate(
p0.x + segmentLengthFraction * (p1.x - p0.x),
p0.y + segmentLengthFraction * (p1.y - p0.y),
p0.z + segmentLengthFraction * (p1.z - p0.z));
};
void pointAlongOffset(double segmentLengthFraction,
double offsetDistance,
Coordinate& ret) const;
LineSegment offset(double offsetDistance);
double projectionFactor(const CoordinateXY& p) const;
double segmentFraction(const CoordinateXY& inputPt) const;
void project(const Coordinate& p, Coordinate& ret) const;
CoordinateXY project(const CoordinateXY& p) const;
bool project(const LineSegment& seg, LineSegment& ret) const;
//
void closestPoint(const CoordinateXY& p, CoordinateXY& ret) const;
bool equalsTopo(const LineSegment& other) const;
std::array<Coordinate, 2> closestPoints(const LineSegment& line);
std::array<Coordinate, 2> closestPoints(const LineSegment* line)
{
assert(line);
return closestPoints(*line);
}
Coordinate intersection(const LineSegment& line) const;
Coordinate lineIntersection(const LineSegment& line) const;
std::unique_ptr<LineString> toGeometry(const GeometryFactory& gf) const;
inline int compareTo(const LineSegment& other) const
{
int comp0 = p0.compareTo(other.p0);
if (comp0 != 0) {
return comp0;
}
return p1.compareTo(other.p1);
}
std::ostream& operator<< (std::ostream& o);
inline bool operator==(const LineSegment& rhs) const {
return compareTo(rhs) == 0;
};
inline bool operator<(const LineSegment& rhs) const {
return compareTo(rhs) < 0;
};
inline bool operator>(const LineSegment& rhs) const {
return compareTo(rhs) > 0;
};
struct HashCode {
inline std::size_t operator()(const LineSegment & s) const {
std::size_t h = std::hash<double>{}(s.p0.x);
h ^= (std::hash<double>{}(s.p0.y) << 1);
h ^= (std::hash<double>{}(s.p1.x) << 1);
return h ^ (std::hash<double>{}(s.p1.y) << 1);
}
inline std::size_t operator()(const LineSegment * s) const {
std::size_t h = std::hash<double>{}(s->p0.x);
h ^= (std::hash<double>{}(s->p0.y) << 1);
h ^= (std::hash<double>{}(s->p1.x) << 1);
return h ^ (std::hash<double>{}(s->p1.y) << 1);
}
};
using UnorderedSet = std::unordered_set<LineSegment, HashCode>;
private:
void project(double factor, CoordinateXY& ret) const;
};
// std::ostream& operator<< (std::ostream& o, const LineSegment& l);
} // namespace geos::geom
} // namespace geos
geos::algorithm::Distance::pointToSegment
static double pointToSegment(const geom::CoordinateXY &p, const geom::CoordinateXY &A, const geom::CoordinateXY &B)
geos::algorithm::Distance::segmentToSegment
static double segmentToSegment(const geom::CoordinateXY &A, const geom::CoordinateXY &B, const geom::CoordinateXY &C, const geom::CoordinateXY &D)
geos::algorithm::Distance::pointToLinePerpendicular
static double pointToLinePerpendicular(const geom::CoordinateXY &p, const geom::CoordinateXY &A, const geom::CoordinateXY &B)
geos::algorithm::Orientation::index
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...
geos::geom::CoordinateSequence
The internal representation of a list of coordinates inside a Geometry.
Definition CoordinateSequence.h:56
geos::geom::Coordinate
Coordinate is the lightweight class used to store coordinates.
Definition Coordinate.h:217
geos::geom::GeometryFactory
Supplies a set of utility methods for building Geometry objects from CoordinateSequence or other Geom...
Definition GeometryFactory.h:70
geos::geom::LineSegment
Definition LineSegment.h:61
geos::geom::LineSegment::isVertical
bool isVertical() const
Definition LineSegment.h:156
geos::geom::LineSegment::LineSegment
LineSegment(const Coordinate &c0, const Coordinate &c1)
Segment end.
Definition LineSegment.h:68
geos::geom::LineSegment::minX
double minX() const
gets the minimum X ordinate value
Definition LineSegment.h:114
geos::geom::LineSegment::compareTo
int compareTo(const LineSegment &other) const
Compares this object with the specified object for order.
Definition LineSegment.h:523
geos::geom::LineSegment::orientationIndex
int orientationIndex(const CoordinateXY &p) const
Definition LineSegment.h:202
geos::geom::LineSegment::pointAlongOffset
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 ...
geos::geom::LineSegment::project
bool project(const LineSegment &seg, LineSegment &ret) const
Project a line segment onto this line segment and return the resulting line segment.
geos::geom::LineSegment::minY
double minY() const
gets the minimum Y ordinate value
Definition LineSegment.h:126
geos::geom::LineSegment::pointAlong
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
geos::geom::LineSegment::project
void project(const Coordinate &p, Coordinate &ret) const
Compute the projection of a point onto the line determined by this line segment.
geos::geom::LineSegment::maxX
double maxX() const
gets the maximum X ordinate value
Definition LineSegment.h:120
geos::geom::LineSegment::equalsTopo
bool equalsTopo(const LineSegment &other) const
Returns true if other is topologically equal to this LineSegment (e.g. irrespective of orientation).
geos::geom::LineSegment::reverse
void reverse()
Reverses the direction of the line segment.
geos::geom::LineSegment::midPoint
CoordinateXY midPoint() const
Computes the midpoint of the segment.
Definition LineSegment.h:254
geos::geom::LineSegment::distance
double distance(const LineSegment &ls) const
Computes the distance between this line segment and another one.
Definition LineSegment.h:267
geos::geom::LineSegment::orientationIndex
int orientationIndex(const LineSegment &seg) const
geos::geom::LineSegment::toGeometry
std::unique_ptr< LineString > toGeometry(const GeometryFactory &gf) const
geos::geom::LineSegment::normalize
void normalize()
Puts the line segment into a normalized form.
Definition LineSegment.h:236
geos::geom::LineSegment::closestPoints
std::array< Coordinate, 2 > closestPoints(const LineSegment &line)
geos::geom::LineSegment::isHorizontal
bool isHorizontal() const
Definition LineSegment.h:147
geos::geom::LineSegment::getLength
double getLength() const
Computes the length of the line segment.
Definition LineSegment.h:138
geos::geom::LineSegment::p1
Coordinate p1
Segment start.
Definition LineSegment.h:66
geos::geom::LineSegment::distancePerpendicular
double distancePerpendicular(const CoordinateXY &p) const
Definition LineSegment.h:287
geos::geom::LineSegment::lineIntersection
Coordinate lineIntersection(const LineSegment &line) const
Computes the intersection point of the lines defined by two segments, if there is one.
geos::geom::LineSegment::offset
LineSegment offset(double offsetDistance)
geos::geom::LineSegment::orientationIndex
int orientationIndex(const Coordinate &p) const
Determines the orientation index of a Coordinate relative to this segment.
Definition LineSegment.h:223
geos::geom::LineSegment::angle
double angle() const
Definition LineSegment.h:244
geos::geom::LineSegment::intersection
Coordinate intersection(const LineSegment &line) const
geos::geom::LineSegment::maxY
double maxY() const
gets the maximum Y ordinate value
Definition LineSegment.h:132
geos::geom::LineSegment::distance
double distance(const CoordinateXY &p) const
Computes the distance between this line segment and a point.
Definition LineSegment.h:273
geos::geom::LineSegment::closestPoint
void closestPoint(const CoordinateXY &p, CoordinateXY &ret) const
Computes the closest point on this line segment to another point.
geos::geom::LineSegment::distancePerpendicularOriented
double distancePerpendicularOriented(const CoordinateXY &p) const
geos::geom::LineSegment::segmentFraction
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...
geos::geom::LineSegment::projectionFactor
double projectionFactor(const CoordinateXY &p) const
Compute the projection factor for the projection of the point p onto this LineSegment.
geos::geom::LineString
Definition LineString.h:66
geos::geom
Definition Angle.h:26
geos
Basic namespace for all GEOS functionalities.
Definition geos.h:38