Recti 1.2.4
Loading...
Searching...
No Matches
recti.hpp
Go to the documentation of this file.
1
5#pragma once
6
7#include <algorithm> // for std::sort
8#include <optional> // for std::optional, std::nullopt
9#include <vector> // for std::vector
10
11#include "interval.hpp" // for Interval
12#include "point.hpp" // for Point
13
14namespace recti {
15
61 template <typename T> struct Rectangle : Point<Interval<T>> {
69 : Point<Interval<T>>{std::move(xcoord), std::move(ycoord)} {}
70
78 constexpr Rectangle(
79 Point<Interval<T>> base) noexcept // Note: intentionally allow implicit conversion
80 : Point<Interval<T>>{std::move(base)} {}
81
91 constexpr auto ll() const -> Point<T> { return {this->xcoord().lb(), this->ycoord().lb()}; }
92
105 constexpr auto ur() const -> Point<T> { return {this->xcoord().ub(), this->ycoord().ub()}; }
106
115 constexpr auto area() const -> T {
116 return this->xcoord().length() * this->ycoord().length();
117 }
118 };
119
132 template <typename T> struct HSegment : Point<Interval<T>, T> {
139 constexpr HSegment(Interval<T> xcoord, T ycoord) noexcept
140 : Point<Interval<T>, T>{std::move(xcoord), std::move(ycoord)} {}
141
147 constexpr HSegment(
148 Point<Interval<T>, T> base) noexcept // Note: intentionally allow implicit conversion
149 : Point<Interval<T>, T>{std::move(base)} {}
150 };
151
164 template <typename T> struct VSegment : Point<T, Interval<T>> {
171 constexpr VSegment(T xcoord, Interval<T> ycoord) noexcept
172 : Point<T, Interval<T>>{std::move(xcoord), std::move(ycoord)} {}
173
179 constexpr VSegment(
180 Point<T, Interval<T>> base) noexcept // Note: intentionally allow implicit conversion
181 : Point<T, Interval<T>>{std::move(base)} {}
182 };
183
197 template <typename Container> constexpr auto detect_overlap(const Container& rectangles)
198 -> std::optional<
199 std::pair<typename Container::value_type, typename Container::value_type>> {
200 using RectT = typename Container::value_type;
201 using T = typename RectT::value_type; // Extract the underlying type (int)
202
203 if (rectangles.size() < 2) {
204 return std::nullopt;
205 }
206
207 using Event = std::tuple<T, int, size_t>;
208 std::vector<Event> events;
209
210 size_t idx = 0;
211 for (const auto& rect : rectangles) {
212 if (rect.xcoord().is_invalid() || rect.ycoord().is_invalid()) {
213 ++idx;
214 continue;
215 }
216 events.emplace_back(rect.xcoord().lb(), 1, idx);
217 events.emplace_back(rect.xcoord().ub(), -1, idx);
218 ++idx;
219 }
220
221 std::sort(events.begin(), events.end(),
222 [](const Event& a, const Event& b) { return std::get<0>(a) < std::get<0>(b); });
223
224 std::vector<std::pair<size_t, Interval<T>>> active;
225
226 for (const auto& [x, event_type, rect_idx] : events) {
227 const auto& rect = rectangles[rect_idx];
228
229 if (event_type == 1) {
230 for (const auto& [other_idx, other_y] : active) {
231 if (rect.ycoord().overlaps(other_y)) {
232 return std::make_optional(std::make_pair(rect, rectangles[other_idx]));
233 }
234 }
235 active.emplace_back(rect_idx, rect.ycoord());
236 } else {
237 for (size_t i = 0; i < active.size(); ++i) {
238 if (active[i].first == rect_idx) {
239 // O(1) removal: swap with back and pop
240 active[i] = active.back();
241 active.pop_back();
242 break;
243 }
244 }
245 }
246 }
247
248 return std::nullopt;
249 }
250
251} // namespace recti
Interval.
Definition interval.hpp:23
Point.
Definition point.hpp:30
constexpr auto xcoord() const -> const Interval< T > &
Gets the x coordinate of this Point.
Definition point.hpp:72
constexpr auto ycoord() const -> const Interval< T > &
Gets the y coordinate of this Point.
Definition point.hpp:78
Interval (range) template class with arithmetic and set operations.
Definition svg_utils.hpp:12
constexpr auto detect_overlap(const Container &rectangles) -> std::optional< std::pair< typename Container::value_type, typename Container::value_type > >
Detect if any pair of rectangles overlap using the line sweep algorithm.
Definition recti.hpp:197
2D Point template class supporting intervals, arithmetic, and geometric queries.
Horizontal Line Segment.
Definition recti.hpp:132
constexpr HSegment(Interval< T > xcoord, T ycoord) noexcept
Construct a new HSegment object.
Definition recti.hpp:139
constexpr HSegment(Point< Interval< T >, T > base) noexcept
Construct a new HSegment object from the.
Definition recti.hpp:147
Rectangle (Rectilinear)
Definition recti.hpp:61
constexpr auto area() const -> T
area
Definition recti.hpp:115
constexpr Rectangle(Point< Interval< T > > base) noexcept
Construct a new Rectangle object from the base object (implicitly)
Definition recti.hpp:78
constexpr Rectangle(Interval< T > xcoord, Interval< T > ycoord) noexcept
Construct a new Rectangle object.
Definition recti.hpp:68
constexpr auto ll() const -> Point< T >
lower left corner
Definition recti.hpp:91
constexpr auto ur() const -> Point< T >
upper right corner
Definition recti.hpp:105
Vertical Line Segment.
Definition recti.hpp:164
constexpr VSegment(Point< T, Interval< T > > base) noexcept
Construct a new VSegment object from the base object (implicitly)
Definition recti.hpp:179
constexpr VSegment(T xcoord, Interval< T > ycoord) noexcept
Construct a new VSegment object.
Definition recti.hpp:171