Pangolin
Header-only C++20 plane computational geometry library
Loading...
Searching...
No Matches
forward.hpp
Go to the documentation of this file.
1#pragma once
2
10
11#include <type_traits>
12#include <vector>
13
14namespace pgl {
15
19struct NoLabel;
20
24class BigInt;
25
31template <class T>
32class Rational;
33
35template <class Vertex>
36class Graph;
37
39template <class PointType>
40struct EmptyShape;
41
48template <class Number, class Label>
49struct Point;
50
59template <class ANumber, class ALabel, class BNumber, class BLabel, class CNumber, class CLabel>
60constexpr bool collinear(
63 const Point<CNumber, CLabel>& c);
64
66template <class PointType, class Label = NoLabel>
67struct Segment;
68
70template <class PointType, class Label = NoLabel>
71struct OrientedSegment;
72
74template <class PointType, class Label = NoLabel>
75struct Line;
76
78template <class PointType, class Label = NoLabel>
79struct OrientedLine;
80
82template <class PointType, class Label = NoLabel>
83struct Ray;
84
86template <class PointType, class Label = NoLabel>
87struct Halfplane;
88
90template <class PointType, class Label = NoLabel>
91struct Rectangle;
92
94template <class PointType, class Label = NoLabel>
95struct Triangle;
96
98template <class PointType, class Label = NoLabel>
99struct Convex;
100
102template <class PointType, class Label = NoLabel>
103struct Polygon;
104
106template <class PointType, class Label = NoLabel>
108
110template <class PointType, class Label = NoLabel>
111struct PolygonWithHoles;
112
114template <class PointType, class Label = NoLabel>
115struct PolygonSet;
116
118template <class PointType, class Label = NoLabel, class Storage = std::vector<PointType>>
119struct MonotoneChain;
120
122template <class PointType, class Label = NoLabel>
123struct Polyline;
124
126template <class PointType, class Label>
127struct Disk;
128
130template <class PointType>
131struct Shape;
132
146template <class PointType = Point<Rational<BigInt>, NoLabel>, class Label = NoLabel>
147class Arrangement;
148
157template <class Number>
158struct Transformation;
159
161class Canvas;
162
163namespace detail {
164
175template <class T>
176inline constexpr int shapeRank = -1;
177
178template <class PointType>
179inline constexpr int shapeRank<EmptyShape<PointType>> = 0;
180template <class Number, class Label>
181inline constexpr int shapeRank<Point<Number, Label>> = 10;
182template <class PointType, class Label>
183inline constexpr int shapeRank<Segment<PointType, Label>> = 20;
184template <class PointType, class Label>
185inline constexpr int shapeRank<OrientedSegment<PointType, Label>> = 30;
186template <class PointType, class Label>
187inline constexpr int shapeRank<Line<PointType, Label>> = 40;
188template <class PointType, class Label>
189inline constexpr int shapeRank<OrientedLine<PointType, Label>> = 50;
190template <class PointType, class Label>
191inline constexpr int shapeRank<Ray<PointType, Label>> = 60;
192template <class PointType, class Label>
193inline constexpr int shapeRank<Halfplane<PointType, Label>> = 70;
194template <class PointType, class Label>
195inline constexpr int shapeRank<Rectangle<PointType, Label>> = 80;
196template <class PointType, class Label>
197inline constexpr int shapeRank<Triangle<PointType, Label>> = 90;
198template <class PointType, class Label>
199inline constexpr int shapeRank<Disk<PointType, Label>> = 100;
200template <class PointType, class Label>
201inline constexpr int shapeRank<Convex<PointType, Label>> = 110;
202template <class PointType, class Label, class Storage>
203inline constexpr int shapeRank<MonotoneChain<PointType, Label, Storage>> = 115;
204template <class PointType, class Label>
205inline constexpr int shapeRank<Polyline<PointType, Label>> = 117;
206template <class PointType, class Label>
207inline constexpr int shapeRank<Polygon<PointType, Label>> = 120;
208template <class PointType, class Label>
209inline constexpr int shapeRank<HalfplaneIntersection<PointType, Label>> = 130;
210template <class PointType, class Label>
211inline constexpr int shapeRank<PolygonWithHoles<PointType, Label>> = 140;
212template <class PointType, class Label>
213inline constexpr int shapeRank<PolygonSet<PointType, Label>> = 150;
214
215// Shape-detection traits: is_<shape>_v<T> is true when T (ignoring cv/ref) is a
216// specialization of that shape. They back the public XxxConcept concepts below
217// and the generic 'Shape' routing in predicates.hpp. Defined here, before any
218// shape header, so every header can use any shape's concept regardless of the
219// order shapes are included in pgl.hpp.
220template <class T> struct is_empty_shape : std::false_type {};
221template <class PointType> struct is_empty_shape<EmptyShape<PointType>> : std::true_type {};
222template <class T> inline constexpr bool is_empty_shape_v = is_empty_shape<std::remove_cvref_t<T>>::value;
223
224template <class T> struct is_point : std::false_type {};
225template <class Number, class Label> struct is_point<Point<Number, Label>> : std::true_type {};
226template <class T> inline constexpr bool is_point_v = is_point<std::remove_cvref_t<T>>::value;
227
228template <class T> struct is_segment : std::false_type {};
229template <class PointType, class Label> struct is_segment<Segment<PointType, Label>> : std::true_type {};
230template <class T> inline constexpr bool is_segment_v = is_segment<std::remove_cvref_t<T>>::value;
231
232template <class T> struct is_oriented_segment : std::false_type {};
233template <class PointType, class Label> struct is_oriented_segment<OrientedSegment<PointType, Label>> : std::true_type {};
234template <class T> inline constexpr bool is_oriented_segment_v = is_oriented_segment<std::remove_cvref_t<T>>::value;
235
236template <class T> struct is_line : std::false_type {};
237template <class PointType, class Label> struct is_line<Line<PointType, Label>> : std::true_type {};
238template <class T> inline constexpr bool is_line_v = is_line<std::remove_cvref_t<T>>::value;
239
240template <class T> struct is_oriented_line : std::false_type {};
241template <class PointType, class Label> struct is_oriented_line<OrientedLine<PointType, Label>> : std::true_type {};
242template <class T> inline constexpr bool is_oriented_line_v = is_oriented_line<std::remove_cvref_t<T>>::value;
243
244template <class T> struct is_ray : std::false_type {};
245template <class PointType, class Label> struct is_ray<Ray<PointType, Label>> : std::true_type {};
246template <class T> inline constexpr bool is_ray_v = is_ray<std::remove_cvref_t<T>>::value;
247
248template <class T> struct is_halfplane : std::false_type {};
249template <class PointType, class Label> struct is_halfplane<Halfplane<PointType, Label>> : std::true_type {};
250template <class T> inline constexpr bool is_halfplane_v = is_halfplane<std::remove_cvref_t<T>>::value;
251
252template <class T> struct is_rectangle : std::false_type {};
253template <class PointType, class Label> struct is_rectangle<Rectangle<PointType, Label>> : std::true_type {};
254template <class T> inline constexpr bool is_rectangle_v = is_rectangle<std::remove_cvref_t<T>>::value;
255
256template <class T> struct is_triangle : std::false_type {};
257template <class PointType, class Label> struct is_triangle<Triangle<PointType, Label>> : std::true_type {};
258template <class T> inline constexpr bool is_triangle_v = is_triangle<std::remove_cvref_t<T>>::value;
259
260template <class T> struct is_convex : std::false_type {};
261template <class PointType, class Label> struct is_convex<Convex<PointType, Label>> : std::true_type {};
262template <class T> inline constexpr bool is_convex_v = is_convex<std::remove_cvref_t<T>>::value;
263
264template <class T> struct is_polygon : std::false_type {};
265template <class PointType, class Label> struct is_polygon<Polygon<PointType, Label>> : std::true_type {};
266template <class T> inline constexpr bool is_polygon_v = is_polygon<std::remove_cvref_t<T>>::value;
267
268template <class T> struct is_polygon_with_holes : std::false_type {};
269template <class PointType, class Label> struct is_polygon_with_holes<PolygonWithHoles<PointType, Label>> : std::true_type {};
270template <class T> inline constexpr bool is_polygon_with_holes_v = is_polygon_with_holes<std::remove_cvref_t<T>>::value;
271
272template <class T> struct is_polygon_set : std::false_type {};
273template <class PointType, class Label> struct is_polygon_set<PolygonSet<PointType, Label>> : std::true_type {};
274template <class T> inline constexpr bool is_polygon_set_v = is_polygon_set<std::remove_cvref_t<T>>::value;
275
276template <class T> struct is_halfplane_intersection : std::false_type {};
277template <class PointType, class Label> struct is_halfplane_intersection<HalfplaneIntersection<PointType, Label>> : std::true_type {};
278template <class T> inline constexpr bool is_halfplane_intersection_v = is_halfplane_intersection<std::remove_cvref_t<T>>::value;
279
280template <class T> struct is_monotone_chain : std::false_type {};
281template <class PointType, class Label, class Storage> struct is_monotone_chain<MonotoneChain<PointType, Label, Storage>> : std::true_type {};
282template <class T> inline constexpr bool is_monotone_chain_v = is_monotone_chain<std::remove_cvref_t<T>>::value;
283
284template <class T> struct is_polyline : std::false_type {};
285template <class PointType, class Label> struct is_polyline<Polyline<PointType, Label>> : std::true_type {};
286template <class T> inline constexpr bool is_polyline_v = is_polyline<std::remove_cvref_t<T>>::value;
287
288template <class T> struct is_disk : std::false_type {};
289template <class PointType, class Label> struct is_disk<Disk<PointType, Label>> : std::true_type {};
290template <class T> inline constexpr bool is_disk_v = is_disk<std::remove_cvref_t<T>>::value;
291
292template <class T> struct is_shape : std::false_type {};
293template <class PointType> struct is_shape<Shape<PointType>> : std::true_type {};
294template <class T> inline constexpr bool is_shape_v = is_shape<std::remove_cvref_t<T>>::value;
295
296template <class T> struct is_transformation : std::false_type {};
297template <class Number> struct is_transformation<Transformation<Number>> : std::true_type {};
298template <class T> inline constexpr bool is_transformation_v = is_transformation<std::remove_cvref_t<T>>::value;
299
300} // namespace detail
301
302// Public per-shape concepts: each is satisfied by any specialization of that
303// shape (ignoring cv/ref). They live here so every shape and implementation
304// header can constrain on them, e.g. `template<SegmentConcept S> ...`.
305template <class T> concept EmptyShapeConcept = detail::is_empty_shape_v<T>;
306template <class T> concept PointConcept = detail::is_point_v<T>;
307template <class T> concept SegmentConcept = detail::is_segment_v<T>;
308template <class T> concept OrientedSegmentConcept = detail::is_oriented_segment_v<T>;
309template <class T> concept LineConcept = detail::is_line_v<T>;
310template <class T> concept OrientedLineConcept = detail::is_oriented_line_v<T>;
311template <class T> concept RayConcept = detail::is_ray_v<T>;
312template <class T> concept HalfplaneConcept = detail::is_halfplane_v<T>;
313template <class T> concept RectangleConcept = detail::is_rectangle_v<T>;
314template <class T> concept TriangleConcept = detail::is_triangle_v<T>;
315template <class T> concept ConvexConcept = detail::is_convex_v<T>;
316template <class T> concept PolygonConcept = detail::is_polygon_v<T>;
317template <class T> concept PolygonWithHolesConcept = detail::is_polygon_with_holes_v<T>;
318template <class T> concept PolygonSetConcept = detail::is_polygon_set_v<T>;
319template <class T> concept HalfplaneIntersectionConcept = detail::is_halfplane_intersection_v<T>;
320template <class T> concept MonotoneChainConcept = detail::is_monotone_chain_v<T>;
321template <class T> concept PolylineConcept = detail::is_polyline_v<T>;
322template <class T> concept DiskConcept = detail::is_disk_v<T>;
323template <class T> concept ShapeConcept = detail::is_shape_v<T>;
324template <class T> concept TransformationConcept = detail::is_transformation_v<T>;
325
327template <class T>
329 ShapeConcept<T> || detail::shapeRank<std::remove_cvref_t<T>> >= 0;
330
338template <class T>
342
357template <class T>
361
372template <class T>
376
402template <class T>
406
407namespace detail {
408
416template <class Self, class Other>
417concept ClosestPairConcept =
419 requires(const Self& self, const Other& other) { self.squaredDistance(other); };
420
431template <class Self, class Other>
432concept ClosestPointsPairConcept =
435 requires(const Self& self, const Other& other) { self.squaredDistance(other); };
436
437} // namespace detail
438
475template <class A, class B>
477 (ShapeConcept<A> || detail::shapeRank<std::remove_cvref_t<A>> >= 0) &&
478 (ShapeConcept<B> || detail::shapeRank<std::remove_cvref_t<B>> >= 0) &&
488
489namespace detail {
490
520template <class Other, class Predicate>
521constexpr bool reduceDegenerate(const Other& other, Predicate predicate) {
522 if constexpr (requires { other.getIfPoint(); }) {
523 if (const auto vertex = other.getIfPoint()) {
524 return predicate(*vertex);
525 }
526 }
527 if constexpr (requires { other.getIfSegment(); }) {
528 if (const auto carrier = other.getIfSegment()) {
529 return predicate(*carrier);
530 }
531 }
532 return false;
533}
534
554template <class Other, class Predicate>
555constexpr bool reduceDegenerateGuarded(const Other& other, Predicate predicate) {
556 return other.isDegenerate() && reduceDegenerate(other, predicate);
557}
558
576template <class TShape>
577constexpr bool coversNoPoint(const TShape& shape) {
578 if constexpr (requires { shape.empty(); }) {
579 return shape.empty();
580 } else if constexpr (requires { shape.size(); }) {
581 return shape.size() == 0;
582 } else {
583 return false;
584 }
585}
586
606template <class Other, class Predicate>
607constexpr bool reduceDegenerateToPoint(const Other& other, Predicate predicate) {
608 if constexpr (requires { other.getIfPoint(); }) {
609 if (const auto vertex = other.getIfPoint()) {
610 return predicate(*vertex);
611 }
612 }
613 return false;
614}
615
616} // namespace detail
617
618} // namespace pgl
The planar subdivision induced by a set of one-dimensional shapes.
Definition arrangement.hpp:171
Arbitrary precision signed integer.
Definition bigint.hpp:157
Stores drawable objects and exports them as an SVG image.
Definition canvas.hpp:128
Undirected simple graph stored as adjacency sets.
Definition graph.hpp:38
Exact rational number class template.
Definition rational.hpp:106
Any concrete geometry type or the runtime Shape wrapper.
Definition forward.hpp:328
Bounded convex primitives.
Definition forward.hpp:339
Bounded polygonal primitives, convex or not.
Definition forward.hpp:373
Definition forward.hpp:315
Definition forward.hpp:322
Definition forward.hpp:305
Definition forward.hpp:312
Definition forward.hpp:319
Definition forward.hpp:309
Shape pairs whose Minkowski sum Pangolin can represent.
Definition forward.hpp:476
Definition forward.hpp:320
Definition forward.hpp:310
Definition forward.hpp:308
Definition forward.hpp:306
Definition forward.hpp:316
Definition forward.hpp:318
Definition forward.hpp:317
Bounded polygonal regions: exactly the shapes a PolygonSet can always represent.
Definition forward.hpp:403
Definition forward.hpp:321
Definition forward.hpp:311
Definition forward.hpp:313
Definition forward.hpp:307
Definition forward.hpp:323
Definition forward.hpp:324
Definition forward.hpp:314
Unbounded convex polyhedral primitives.
Definition forward.hpp:358
Definition arrangement.hpp:67
HalfplaneIntersection() -> HalfplaneIntersection< Point<>, NoLabel >
Definition halfplaneintersection.hpp:2308
Rectangle() -> Rectangle< Point<>, NoLabel >
Definition rectangle.hpp:2384
@ vertex
Definition bitmatrix.hpp:37
Line() -> Line< Point<>, NoLabel >
Point() -> Point< int >
PolygonSet() -> PolygonSet< Point<>, NoLabel >
Definition polygonset.hpp:1699
OrientedSegment() -> OrientedSegment< Point<>, NoLabel >
MonotoneChain() -> MonotoneChain< Point<>, NoLabel >
Definition monotonechain.hpp:2439
constexpr bool collinear(const Point< ANumber, ALabel > &a, const Point< BNumber, BLabel > &b, const Point< CNumber, CLabel > &c)
Tests whether three points are collinear.
Definition orientation.hpp:651
Shape(const std::variant< T, Ts... > &) -> Shape< detail::shape_point_type_t< T > >
PolygonWithHoles() -> PolygonWithHoles< Point<>, NoLabel >
Definition polygonwithholes.hpp:3093
Convex() -> Convex< Point<>, NoLabel >
Definition convex.hpp:3311
Segment() -> Segment< Point<>, NoLabel >
Halfplane() -> Halfplane< Point<>, NoLabel >
Polyline() -> Polyline< Point<>, NoLabel >
Definition polyline.hpp:2369
Ray() -> Ray< Point<>, NoLabel >
Polygon() -> Polygon< Point<>, NoLabel >
Definition polygon.hpp:3200
Disk() -> Disk< Point<>, NoLabel >
Deduces a default disk with Point<> boundary points and no label.
Definition disk.hpp:1691
OrientedLine() -> OrientedLine< Point<>, NoLabel >
Triangle() -> Triangle< Point<>, NoLabel >
Definition triangle.hpp:2029
Closed convex polygon stored by its vertices.
Definition convex.hpp:170
Closed Euclidean disk stored by boundary points plus optional disk label.
Definition disk.hpp:66
The empty set of points in the plane.
Definition emptyshape.hpp:33
Intersection of closed half-planes; convex but possibly unbounded or empty.
Definition halfplaneintersection.hpp:244
Closed half-plane defined by an oriented boundary line.
Definition halfplane.hpp:51
Unoriented infinite line.
Definition line.hpp:52
Weakly x-monotone polyline stored by lexicographically sorted vertices.
Definition monotonechain.hpp:146
Sentinel type used when a point carries no extra label.
Definition point.hpp:31
Directed infinite line with left/right side semantics plus optional line label.
Definition orientedline.hpp:53
Directed segment preserving source-to-target order plus optional segment label.
Definition orientedsegment.hpp:44
Two-dimensional point with optional label payload.
Definition point.hpp:129
Set of closed regions with pairwise disjoint interiors.
Definition polygonset.hpp:165
Closed region bounded by one outer simple polygon minus disjoint polygonal holes.
Definition polygonwithholes.hpp:89
Closed simple polygon stored by its vertices.
Definition polygon.hpp:59
Open polygonal chain stored in traversal order; may self-intersect.
Definition polyline.hpp:69
Half-infinite line starting from one source point plus optional ray label.
Definition ray.hpp:51
Axis-aligned rectangle stored by minimum and maximum corners.
Definition rectangle.hpp:75
Unoriented closed segment between two endpoints plus optional segment label.
Definition segment.hpp:58
Runtime variant wrapper over the supported primitive shapes.
Definition shape.hpp:160
Affine transformation stored as a 2x3 matrix.
Definition transformation.hpp:32
Closed triangle stored by three vertices.
Definition triangle.hpp:53