Fishnet 2.0.1
Framework for Graph-Based Analysis of GIS Vector Data
Loading...
Searching...
No Matches
Line.hpp
Go to the documentation of this file.
1#pragma once
2#include <fishnet/Option.hpp>
5#include "Vec2D.hpp"
6
7namespace fishnet::geometry{
13template<fishnet::math::Number T = fishnet::math::DEFAULT_NUMERIC>
14class Line{
15private:
16 Vec2D<T> _p;
17 Vec2D<T> _q;
18 constexpr static auto hasher = std::hash<fishnet::math::DEFAULT_FLOATING_POINT>{};
19 const static inline Line<T> yAxis = Line<T>(Vec2D<T>(0,0),Vec2D<T>(0,1));
20public:
21
28 constexpr static Line<T> verticalLine(T x) noexcept {
29 return Line<T>(Vec2D<T>(x,0),Vec2D<T>(x,1));
30 }
31
38 constexpr static Line<T> horizontalLine(T y) noexcept {
39 return Line<T>(0,y);
40 }
41
42 using numeric_type = T;
43 constexpr static GeometryType type = GeometryType::LINE;
44
49 constexpr Line(Vec2D<T> _p , Vec2D<T> _q):_p(_p),_q(_q){
50 if (_p == _q)
51 throw std::invalid_argument("Coinciding Points cannot define a Line");
52 }
53
61 template<fishnet::math::Number U, typename = std::enable_if_t<!std::is_same_v<U,T> && std::is_same_v<T,fishnet::math::DEFAULT_NUMERIC>>>
62 constexpr Line(Vec2D<T> _p, Vec2D<U> _q):Line(_p,static_cast<Vec2D<T>>(_q)){}
63
71 template<fishnet::math::Number U, typename = std::enable_if_t<!std::is_same_v<U,T> && std::is_same_v<T,fishnet::math::DEFAULT_NUMERIC>>>
72 constexpr Line(Vec2D<U> _p , Vec2D<T> _q):Line(static_cast<Vec2D<T>>(_p),_q){}
73
78 constexpr Line(T slope, T yIntercept):_p(Vec2D<T>(0,yIntercept)),_q(Vec2D<T>(1,slope+yIntercept)){}
79
87 template<fishnet::math::Number U, typename = std::enable_if_t<!std::is_same_v<U,T> && std::is_same_v<T,fishnet::math::DEFAULT_NUMERIC>>>
88 constexpr Line(T slope, U yIntercept):Line(slope,fishnet::math::DEFAULT_NUMERIC(yIntercept)){}
89
97 template<fishnet::math::Number U, typename = std::enable_if_t<!std::is_same_v<U,T> && std::is_same_v<T,fishnet::math::DEFAULT_NUMERIC>>>
98 constexpr Line(U slope, T yIntercept):Line(fishnet::math::DEFAULT_NUMERIC(slope),yIntercept){}
99
100 constexpr Vec2D<T> p() const noexcept{
101 return _p;
102 }
103
104 constexpr Vec2D<T> q() const noexcept{
105 return _q;
106 }
107
108 constexpr Line<T> toLine() const noexcept{
109 return Line(_p,_q);
110 }
111
112 constexpr Vec2D<T> direction() const noexcept{
113 return _q-_p;
114 }
115
116 constexpr bool isVertical() const noexcept{
117 return _p.x == _q.x;
118 }
119
120 constexpr bool isHorizontal() const noexcept{
121 return _p.y == _q.y;
122 }
123
125 fishnet::Option<Vec2DReal> intersectionWithY = intersection(yAxis);
126 [[likely]] if (intersectionWithY){
127 return fishnet::Option(intersectionWithY->y);
128 }
129 return std::nullopt;
130 }
131
133 [[unlikely]] if (direction().x == 0)
134 return std::numeric_limits<fishnet::math::DEFAULT_FLOATING_POINT>::max();
136 }
137
138 constexpr bool contains(IPoint auto const & point) const noexcept{
139 using FLOAT_TYPE = fishnet::math::DEFAULT_FLOATING_POINT;
140 auto dir = direction();
141 if(dir.x == 0) { // line is vertical
142 return point.x == _p.x; //or _q.x
143 }
144 if(dir.y == 0){ // line is horizontal
145 return point.y == _p.y;
146 }
147 FLOAT_TYPE lX = FLOAT_TYPE(point.x - this->_p.x) / FLOAT_TYPE(dir.x);
148 FLOAT_TYPE lY = FLOAT_TYPE(point.y - this->_p.y) / FLOAT_TYPE(dir.y);
149 return fabs(lX-lY) < fishnet::math::EPSILON;
150 }
151
152 constexpr bool isLeft(IPoint auto const & point) const noexcept {
153 return direction().cross(point-_p) > 0;
154 }
155
156 constexpr bool isRight(IPoint auto const & point) const noexcept {
157 return direction().cross(point-_p) < 0;
158 }
159
160 constexpr bool isParallel(LinearGeometry auto const& other) const noexcept {
161 return areParallel(*this,other);
162 }
163
164 constexpr bool intersects(LinearGeometry auto const& other) const noexcept{
165 return intersect(*this,other);
166 }
167
168 template<fishnet::math::Number U>
169 constexpr bool operator==(const Line<U> & other) const noexcept {
170 if(this->isParallel(other)){
171 [[unlikely]] if (isVertical()){ //other must also be vertical since both are parallel
172 return this->_p.x == other.p().x;
173 }
174 return fabs(yIntercept().value() - other.yIntercept().value()) < fishnet::math::EPSILON;
175 }
176 return false;
177 }
178
179 constexpr fishnet::Option<Vec2DReal> intersection(LinearGeometry auto const& other) const noexcept {
180 return linearIntersection(*this,other);
181 }
182
183 constexpr size_t hash() const noexcept {
184 size_t slopeHash = hasher(this->slope());
185 size_t yInterceptHash = hasher(this->yIntercept().value_or(this->_p.x));
186 return fishnet::math::CantorPairing(slopeHash,yInterceptHash);
187 }
188
189 constexpr std::string toString() const {
190 auto t = yIntercept();
191 if (t){
192 return "Line y = " + std::to_string(slope())+" * x + "+std::to_string(t.value());
193 }
194 return "Vertical Line x = "+std::to_string(_p.x);
195 }
196};
197
198//Deduction guides
199template<math::Number T>
201
202const static inline Line<double> X_AXIS = Line<double>(0.0,0.0);
204static_assert(ILine<Line<double>>);
205static_assert(LinearGeometry<Line<double>>);
206
207// Explicit template instantiation
209}
Definition Option.hpp:13
Implementation of a line.
Definition Line.hpp:14
constexpr Line(U slope, T yIntercept)
Constructor of line using slope and y intercept with heterogenous type.
Definition Line.hpp:98
constexpr Vec2D< T > p() const noexcept
Definition Line.hpp:100
constexpr size_t hash() const noexcept
Definition Line.hpp:183
constexpr Vec2D< T > q() const noexcept
Definition Line.hpp:104
constexpr bool isRight(IPoint auto const &point) const noexcept
Definition Line.hpp:156
constexpr fishnet::math::DEFAULT_FLOATING_POINT slope() const noexcept
Definition Line.hpp:132
constexpr bool isVertical() const noexcept
Definition Line.hpp:116
constexpr Line(Vec2D< T > _p, Vec2D< U > _q)
Constructor for a line with heterogenous numeric types Construct new line by converting to the defaul...
Definition Line.hpp:62
constexpr Line(Vec2D< T > _p, Vec2D< T > _q)
Constructor for a line formed by two points.
Definition Line.hpp:49
static constexpr Line< T > verticalLine(T x) noexcept
Vertical line factory.
Definition Line.hpp:28
constexpr fishnet::Option< Vec2DReal > intersection(LinearGeometry auto const &other) const noexcept
Definition Line.hpp:179
constexpr std::string toString() const
Definition Line.hpp:189
static constexpr GeometryType type
Definition Line.hpp:43
T numeric_type
Definition Line.hpp:42
constexpr Vec2D< T > direction() const noexcept
Definition Line.hpp:112
constexpr bool contains(IPoint auto const &point) const noexcept
Definition Line.hpp:138
constexpr Line< T > toLine() const noexcept
Definition Line.hpp:108
constexpr fishnet::Option< fishnet::math::DEFAULT_FLOATING_POINT > yIntercept() const noexcept
Definition Line.hpp:124
constexpr bool isLeft(IPoint auto const &point) const noexcept
Definition Line.hpp:152
constexpr bool isHorizontal() const noexcept
Definition Line.hpp:120
constexpr bool isParallel(LinearGeometry auto const &other) const noexcept
Definition Line.hpp:160
constexpr bool intersects(LinearGeometry auto const &other) const noexcept
Definition Line.hpp:164
static constexpr Line< T > horizontalLine(T y) noexcept
Horizontal line factory.
Definition Line.hpp:38
constexpr Line(Vec2D< U > _p, Vec2D< T > _q)
Constructor for a line with heterogenous numeric types Construct new line by converting to the defaul...
Definition Line.hpp:72
constexpr Line(T slope, T yIntercept)
Constructor of line using slope and y intercept.
Definition Line.hpp:78
constexpr Line(T slope, U yIntercept)
Constructor of line using slope and y intercept with heterogenous type.
Definition Line.hpp:88
constexpr bool operator==(const Line< U > &other) const noexcept
Definition Line.hpp:169
Implementation of a two-dimensional vector.
Definition Vec2D.hpp:16
T y
Definition Vec2D.hpp:21
constexpr auto cross(const IPoint auto &other) const noexcept
Definition Vec2D.hpp:130
T x
Definition Vec2D.hpp:20
Interface for a line A line is defined through two points p and q, defining a direction vector.
Definition ILine.hpp:76
Interface for a point.
Definition IPoint.hpp:92
Definition IGeometry.hpp:13
Definition BoundingBoxWrapper.hpp:5
static constexpr fishnet::Option< Vec2DReal > linearIntersection(ILine auto const &l, ILine auto const &r) noexcept
Computation of line intersection.
Definition LinearIntersection.hpp:15
static constexpr bool areParallel(LinearGeometry auto const &lhs, LinearGeometry auto const &rhs) noexcept
Definition LinearIntersection.hpp:41
static constexpr bool intersect(LinearGeometry auto const &lhs, LinearGeometry auto const &rhs) noexcept
Definition LinearIntersection.hpp:45
GeometryType
Definition GeometryBase.hpp:6
static const Line< double > Y_AXIS
Definition Line.hpp:203
static const Line< double > X_AXIS
Definition Line.hpp:202
constexpr size_t CantorPairing(size_t x, size_t y) noexcept
Definition CantorPairing.hpp:5
static constexpr DEFAULT_FLOATING_POINT EPSILON
Definition Constants.hpp:20
double DEFAULT_FLOATING_POINT
Definition NumericConcepts.hpp:12
Definition BFSClustering.hpp:5
static string to_string(fishnet::geometry::GeometryType type) noexcept
Definition GeometryBase.hpp:22