Recti 1.2.4
Loading...
Searching...
No Matches
rpolygon.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <cstddef>
8#include <iterator>
9#include <span>
10#include <vector>
11
12#include "point.hpp"
13
14namespace recti {
15
50 template <typename T> class RPolygonVertexIterator {
51 public:
52 using iterator_category = std::forward_iterator_tag;
54 using difference_type = std::ptrdiff_t;
55 using pointer = const value_type*;
57
58 constexpr RPolygonVertexIterator(const Point<T>* origin, const Vector2<T>* vecs_begin,
59 std::size_t idx)
60 : _origin(origin), _vecs_begin(vecs_begin), _idx(idx) {}
61
62 constexpr auto operator*() const -> value_type {
63 if (_idx == 0) return *_origin;
64 return *_origin + _vecs_begin[_idx - 1];
65 }
66
67 constexpr auto operator++() -> RPolygonVertexIterator& {
68 ++_idx;
69 return *this;
70 }
71
72 constexpr auto operator==(const RPolygonVertexIterator& other) const -> bool {
73 return _idx == other._idx;
74 }
75
76 constexpr auto operator!=(const RPolygonVertexIterator& other) const -> bool {
77 return _idx != other._idx;
78 }
79
80 private:
81 const Point<T>* _origin;
82 const Vector2<T>* _vecs_begin;
83 std::size_t _idx;
84 };
85
86 template <typename T> class RPolygon {
87 private:
88 Point<T> _origin{};
89 std::vector<Vector2<T>> _vecs{};
90
91 public:
93
97 constexpr RPolygon() = default;
98
102 constexpr auto begin() const -> const_iterator {
103 return const_iterator(&_origin, _vecs.data(), 0);
104 }
105
109 constexpr auto end() const -> const_iterator {
110 return const_iterator(&_origin, _vecs.data(), _vecs.size() + 1);
111 }
112
119 constexpr RPolygon(Point<T> origin, std::vector<Vector2<T>> vecs)
120 : _origin{origin}, _vecs{std::move(vecs)} {}
121
133 explicit constexpr RPolygon(std::span<const Point<T>> pointset)
134 : _origin{pointset.front()} {
135 if (pointset.size() <= 1) return;
136 _vecs.reserve(pointset.size() - 1);
137 for (auto iterator = pointset.begin() + 1; iterator != pointset.end(); ++iterator) {
138 _vecs.emplace_back(*iterator - _origin);
139 }
140 }
141
145 constexpr bool operator==(const RPolygon& rhs) const {
146 return _origin == rhs._origin && _vecs == rhs._vecs;
147 }
148
152 constexpr bool operator!=(const RPolygon& rhs) const { return !(*this == rhs); }
153
163 constexpr auto operator+=(const Vector2<T>& vector_offset) -> RPolygon& {
164 this->_origin += vector_offset;
165 return *this;
166 }
167
177 constexpr auto operator-=(const Vector2<T>& vector_offset) -> RPolygon& {
178 this->_origin -= vector_offset;
179 return *this;
180 }
181
185 constexpr const Point<T>& origin() const { return _origin; }
186
190 constexpr const std::vector<Vector2<T>>& vectors() const { return _vecs; }
191
195 constexpr auto vertices() const -> std::vector<Point<T>> {
196 std::vector<Point<T>> result;
197 result.reserve(_vecs.size() + 1);
198 result.emplace_back(_origin);
199 for (const auto& vec : _vecs) {
200 result.emplace_back(_origin + vec);
201 }
202 return result;
203 }
204
213 constexpr auto signed_area() const -> T {
214 if (_vecs.empty()) return T{0};
215
216 auto iterator = _vecs.begin();
217 Vector2<T> first_vec = *iterator++;
218 T result = first_vec.x() * first_vec.y();
219
220 for (; iterator != _vecs.end(); ++iterator) {
221 Vector2<T> second_vec = *iterator;
222 result += second_vec.x() * (second_vec.y() - first_vec.y());
223 first_vec = second_vec;
224 }
225 return result;
226 }
227
231 constexpr auto is_rectilinear() const -> bool { return true; }
232 };
233
251 template <typename FwIter, typename KeyFn, typename CmpFn>
252 auto create_mono_rpolygon(FwIter&& first, FwIter&& last, const KeyFn& dir, const CmpFn& cmp)
253 -> bool;
254
266 template <typename FwIter> auto create_xmono_rpolygon(FwIter&& first, FwIter&& last) -> bool;
267
279 template <typename FwIter> auto create_ymono_rpolygon(FwIter&& first, FwIter&& last) -> bool;
280
292 template <typename FwIter> void create_test_rpolygon_old(FwIter&& first, FwIter&& last);
293
306 template <typename FwIter> auto create_test_rpolygon(FwIter first, FwIter last)
307 -> std::vector<typename std::iterator_traits<FwIter>::value_type>;
308
319 template <typename T> auto rpolygon_is_xmonotone(std::span<const Point<T>> pointset) -> bool;
320
331 template <typename T> auto rpolygon_is_ymonotone(std::span<const Point<T>> pointset) -> bool;
332
342 template <typename T> auto rpolygon_is_convex(std::span<const Point<T>> pointset) -> bool;
343
360 template <typename T>
361 auto point_in_rpolygon(std::span<const Point<T>> pointset, const Point<T>& query_point) -> bool;
362
373 template <typename T> auto rpolygon_is_anticlockwise(std::span<const Point<T>> pointset)
374 -> bool;
375} // namespace recti
Rectilinear Polygon.
Definition rpolygon.hpp:50
constexpr auto operator++() -> RPolygonVertexIterator &
Definition rpolygon.hpp:67
constexpr auto operator*() const -> value_type
Definition rpolygon.hpp:62
constexpr RPolygonVertexIterator(const Point< T > *origin, const Vector2< T > *vecs_begin, std::size_t idx)
Definition rpolygon.hpp:58
std::forward_iterator_tag iterator_category
Definition rpolygon.hpp:52
constexpr auto operator==(const RPolygonVertexIterator &other) const -> bool
Definition rpolygon.hpp:72
constexpr auto operator!=(const RPolygonVertexIterator &other) const -> bool
Definition rpolygon.hpp:76
std::ptrdiff_t difference_type
Definition rpolygon.hpp:54
Point< T > value_type
Definition rpolygon.hpp:53
Definition rpolygon.hpp:86
constexpr const Point< T > & origin() const
Gets the origin point of the polygon.
Definition rpolygon.hpp:185
constexpr auto end() const -> const_iterator
Past-the-end iterator.
Definition rpolygon.hpp:109
constexpr auto signed_area() const -> T
Calculates the signed area of the rectilinear polygon.
Definition rpolygon.hpp:213
constexpr auto is_rectilinear() const -> bool
Checks if the polygon is rectilinear (all edges are horizontal or vertical)
Definition rpolygon.hpp:231
constexpr RPolygon(Point< T > origin, std::vector< Vector2< T > > vecs)
Constructs a new RPolygon object from origin and vectors.
Definition rpolygon.hpp:119
constexpr auto vertices() const -> std::vector< Point< T > >
Gets all vertices of the polygon as points.
Definition rpolygon.hpp:195
constexpr auto operator+=(const Vector2< T > &vector_offset) -> RPolygon &
Adds a vector to the origin of the rectilinear polygon.
Definition rpolygon.hpp:163
constexpr RPolygon(std::span< const Point< T > > pointset)
Constructs a new RPolygon object from a set of points.
Definition rpolygon.hpp:133
constexpr RPolygon()=default
Default constructor.
constexpr bool operator!=(const RPolygon &rhs) const
Inequality comparison operator.
Definition rpolygon.hpp:152
RPolygonVertexIterator< T > const_iterator
Definition rpolygon.hpp:92
constexpr auto operator-=(const Vector2< T > &vector_offset) -> RPolygon &
Subtracts a vector from the origin of the rectilinear polygon.
Definition rpolygon.hpp:177
constexpr auto begin() const -> const_iterator
Iterator to first vertex (the origin).
Definition rpolygon.hpp:102
constexpr bool operator==(const RPolygon &rhs) const
Equality comparison operator.
Definition rpolygon.hpp:145
constexpr const std::vector< Vector2< T > > & vectors() const
Gets the displacement vectors of the polygon.
Definition rpolygon.hpp:190
2D vector template class.
Definition vector2.hpp:28
constexpr auto x() const noexcept -> const T1 &
Returns a const reference to the x-coordinate of the vector.
Definition vector2.hpp:72
constexpr auto y() const noexcept -> const T2 &
Returns a const reference to the y-coordinate of the vector.
Definition vector2.hpp:81
Definition svg_utils.hpp:12
void create_test_rpolygon_old(FwIter &&first, FwIter &&last)
Create a test rectilinear polygon (RPolygon) object.
auto create_xmono_rpolygon(FwIter &&first, FwIter &&last) -> bool
Create a x-monotone rectilinear polygon (RPolygon) object.
auto create_test_rpolygon(FwIter first, FwIter last) -> std::vector< typename std::iterator_traits< FwIter >::value_type >
Create a test rectilinear polygon (RPolygon) object.
auto point_in_rpolygon(std::span< const Point< T > > pointset, const Point< T > &query_point) -> bool
Determine if a point is within a rectilinear polygon.
auto rpolygon_is_xmonotone(std::span< const Point< T > > pointset) -> bool
Check if a polygon is x-monotone.
auto rpolygon_is_anticlockwise(std::span< const Point< T > > pointset) -> bool
Determine if a rectilinear polygon is oriented clockwise.
auto rpolygon_is_convex(std::span< const Point< T > > pointset) -> bool
Check if a polygon is convex.
auto create_mono_rpolygon(FwIter &&first, FwIter &&last, const KeyFn &dir, const CmpFn &cmp) -> bool
Create a x-monotone rectilinear polygon (RPolygon) object.
auto create_ymono_rpolygon(FwIter &&first, FwIter &&last) -> bool
Create a y-monotone rectilinear polygon (RPolygon) object.
auto rpolygon_is_ymonotone(std::span< const Point< T > > pointset) -> bool
Check if a polygon is y-monotone.
2D Point template class supporting intervals, arithmetic, and geometric queries.