Pangolin
Header-only C++20 plane computational geometry library
Loading...
Searching...
No Matches
pgl::Shape< PointType > Struct Template Reference

Runtime variant wrapper over the supported primitive shapes. More...

#include <shape.hpp>

Inheritance diagram for pgl::Shape< PointType >:
[legend]

Public Types

using PointType_ = PointType
using NumberType = PointType::NumberType
using LabelType = PointType::LabelType
using Variant

Public Member Functions

constexpr Shape ()=default
 Creates a point-valued default shape.
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
constexpr Shape (T &&value)
 Constructs a shape from one supported alternative.
template<class Result>
requires (detail::is_shape_variant_v<PointType, Result> || detail::is_shape_optional_variant_v<PointType, Result>)
constexpr Shape (const Result &result)
 Constructs a shape from a variant over supported alternatives.
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
constexpr Shapeoperator= (T &&value)
 Replaces the stored alternative.
constexpr bool operator== (const Shape &) const =default
 Compares wrapped values.
template<AnyShapeConcept OtherShape>
constexpr bool samePointSet (const OtherShape &other) const
 Tests whether another shape defines exactly the same point set.
constexpr auto operator<=> (const Shape &) const =default
 Orders wrapped values by the underlying variant ordering.
constexpr const Variantvariant () const
 Returns the underlying variant.
constexpr Variantvariant ()
 Returns the underlying variant.
constexpr bool empty () const
 Tests whether the wrapped shape covers no point at all.
constexpr bool isDegenerate () const
 Tests whether the wrapped shape is degenerate.
constexpr Rectangle< PointType > bbox () const
 Returns the wrapped shape's axis-aligned bounding box.
constexpr std::size_t size () const
 Returns the number of indexable elements of the wrapped shape.
constexpr PointType_ get (std::ptrdiff_t index) const
 Returns the i-th vertex (modulo size()) of the wrapped shape.
constexpr PointType_ operator[] (std::size_t index) const
 Returns the vertex at index of the wrapped shape.
constexpr std::ptrdiff_t index (const PointType_ &point) const
 Returns the smallest index i with (*this)[i] == point, or -1 if no vertex of the wrapped shape equals point.
constexpr std::ptrdiff_t index (const NumberType &value) const
 Returns the smallest index i with (*this)[i] == value, or -1 if no coordinate equals value.
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
constexpr bool holdsAlternative () const
 Tests whether the wrapper currently stores a given alternative.
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
constexpr const std::remove_cvref_t< T > * getIf () const
 Returns a pointer to the stored alternative when it matches T.
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
constexpr std::remove_cvref_t< T > * getIf ()
 Returns a mutable pointer to the stored alternative when it matches T.
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
constexpr operator T () const
 Converts to the currently stored alternative.
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr bool contains (const Other &other) const
 Tests whether this shape contains the other shape (A ⊇ B).
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr bool boundaryContains (const Other &other) const
 Tests whether this shape's boundary contains the other shape (∂A ⊇ B).
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr bool interiorContains (const Other &other) const
 Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr bool intersects (const Other &other) const
 Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr bool interiorsIntersect (const Other &other) const
 Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr bool separates (const Other &other) const
 Tests whether removing this shape disconnects the other shape (B∖A is disconnected).
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr bool crosses (const Other &other) const
 Tests whether the two shapes mutually separate each other (each disconnects the other).
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr Shape< Point< ResultNumber, LabelType > > intersection (const Other &other) const
 Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
PolygonSet< Point< ResultNumber, LabelType > > regularizedIntersection (const Other &other) const
 Returns the regularized intersection of two region-valued shapes.
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
PolygonSet< Point< ResultNumber, LabelType > > regularizedUnion (const Other &other) const
 Returns the regularized union closure(A° ∪ B°).
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
PolygonSet< Point< ResultNumber, LabelType > > difference (const Other &other) const
 Returns the regularized set difference of the two shapes (A ∖ B).
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
PolygonSet< Point< ResultNumber, LabelType > > symmetricDifference (const Other &other) const
 Returns the regularized symmetric difference of the two shapes (A △ B).
template<class ResultNumber = double, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr ResultNumber squaredDistance (const Other &other) const
 Returns the squared Euclidean distance to the given shape.
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr ResultNumber squaredHausdorffDistance (const Other &other) const
 Returns the squared Euclidean Hausdorff distance to the given shape.
template<class ResultNumber = double, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr ResultNumber distanceL1 (const Other &other) const
 Returns the Manhattan (L1) distance to the given shape.
template<class ResultNumber = double, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr ResultNumber distanceLInf (const Other &other) const
 Returns the Chebyshev (LInf) distance to the given shape.
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr ResultNumber hausdorffDistanceL1 (const Other &other) const
 Returns the Manhattan (L1) Hausdorff distance to the given shape.
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
constexpr ResultNumber hausdorffDistanceLInf (const Other &other) const
 Returns the Chebyshev (LInf) Hausdorff distance to the given shape.
template<class OtherShape>
requires MinkowskiSummableConcept<Shape<PointType>, OtherShape>
constexpr auto minkowskiSum (const OtherShape &other) const
 Returns the Minkowski sum of this shape and another (A ⊕ B).
template<class OtherShape>
requires MinkowskiSummableConcept<Shape<PointType>, OtherShape>
constexpr auto minkowskiErosion (const OtherShape &other) const
 Returns the Minkowski erosion of this shape by another (A ⊖ B).
template<PointConcept OtherPoint>
constexpr Shapeoperator+= (const OtherPoint &translation)
 Translates the stored shape in place.
template<PointConcept OtherPoint>
constexpr Shapeoperator-= (const OtherPoint &translation)
 Translates the stored shape in place by a negated point.
template<class Scalar>
requires (!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
constexpr Shapeoperator*= (const Scalar &scalar)
 Scales the stored shape in place around the origin.
template<class Scalar>
requires (!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
constexpr Shapeoperator/= (const Scalar &scalar)
 Divides the stored shape in place around the origin.
constexpr Shape rotated90 (int k=1) const
 Returns the wrapped shape rotated by 90k degrees around the origin.
constexpr void rotate90 (int k=1)
 Rotates the wrapped shape by 90k degrees around the origin in place.
template<class OtherNumber>
constexpr Shape scaledUpX (const OtherNumber scalar) const
 Returns the wrapped shape with its x-coordinates scaled up.
template<class OtherNumber>
constexpr void scaleUpX (const OtherNumber scalar)
 Scales the wrapped shape's x-coordinates up in place.
template<class OtherNumber>
constexpr Shape scaledUpY (const OtherNumber scalar) const
 Returns the wrapped shape with its y-coordinates scaled up.
template<class OtherNumber>
constexpr void scaleUpY (const OtherNumber scalar)
 Scales the wrapped shape's y-coordinates up in place.
template<class OtherNumber>
constexpr Shape scaledDownX (const OtherNumber scalar) const
 Returns the wrapped shape with its x-coordinates scaled down.
template<class OtherNumber>
constexpr void scaleDownX (const OtherNumber scalar)
 Scales the wrapped shape's x-coordinates down in place.
template<class OtherNumber>
constexpr Shape scaledDownY (const OtherNumber scalar) const
 Returns the wrapped shape with its y-coordinates scaled down.
template<class OtherNumber>
constexpr void scaleDownY (const OtherNumber scalar)
 Scales the wrapped shape's y-coordinates down in place.
Per-alternative accessors

Named shorthands for holdsAlternative and getIf, one family per stored alternative: isPoint() / getIfPoint(), isSegment() / getIfSegment(), and so on through every alternative of Variant.

These test which alternative is stored, not the geometry of the stored value. This differs from the same-named methods on the concrete shapes, where isPoint() asks whether the shape's point set is a single point: a Shape holding a Triangle whose vertices coincide reports isTriangle() and not isPoint(). Reach through with getIfTriangle()->isPoint() to ask the geometric question.

getIf... returns a pointer into the stored variant, nullptr when another alternative is active. The EmptyShape alternative has no such pair; use holdsAlternative<EmptyShape<PointType>>(), since empty() asks the geometric question and is also true for, say, an empty Rectangle.

constexpr bool isPoint () const
 Tests whether the stored alternative is Point.
constexpr const PointType * getIfPoint () const
 Returns a pointer to the stored Point, or nullptr when another alternative is active.
constexpr PointType * getIfPoint ()
 Returns a pointer to the stored Point, or nullptr when another alternative is active.
constexpr bool isSegment () const
 Tests whether the stored alternative is Segment.
constexpr const Segment< PointType > * getIfSegment () const
 Returns a pointer to the stored Segment, or nullptr when another alternative is active.
constexpr Segment< PointType > * getIfSegment ()
 Returns a pointer to the stored Segment, or nullptr when another alternative is active.
constexpr bool isOrientedSegment () const
 Tests whether the stored alternative is OrientedSegment.
constexpr const OrientedSegment< PointType > * getIfOrientedSegment () const
 Returns a pointer to the stored OrientedSegment, or nullptr when another alternative is active.
constexpr OrientedSegment< PointType > * getIfOrientedSegment ()
 Returns a pointer to the stored OrientedSegment, or nullptr when another alternative is active.
constexpr bool isLine () const
 Tests whether the stored alternative is Line.
constexpr const Line< PointType > * getIfLine () const
 Returns a pointer to the stored Line, or nullptr when another alternative is active.
constexpr Line< PointType > * getIfLine ()
 Returns a pointer to the stored Line, or nullptr when another alternative is active.
constexpr bool isOrientedLine () const
 Tests whether the stored alternative is OrientedLine.
constexpr const OrientedLine< PointType > * getIfOrientedLine () const
 Returns a pointer to the stored OrientedLine, or nullptr when another alternative is active.
constexpr OrientedLine< PointType > * getIfOrientedLine ()
 Returns a pointer to the stored OrientedLine, or nullptr when another alternative is active.
constexpr bool isRay () const
 Tests whether the stored alternative is Ray.
constexpr const Ray< PointType > * getIfRay () const
 Returns a pointer to the stored Ray, or nullptr when another alternative is active.
constexpr Ray< PointType > * getIfRay ()
 Returns a pointer to the stored Ray, or nullptr when another alternative is active.
constexpr bool isHalfplane () const
 Tests whether the stored alternative is Halfplane.
constexpr const Halfplane< PointType > * getIfHalfplane () const
 Returns a pointer to the stored Halfplane, or nullptr when another alternative is active.
constexpr Halfplane< PointType > * getIfHalfplane ()
 Returns a pointer to the stored Halfplane, or nullptr when another alternative is active.
constexpr bool isRectangle () const
 Tests whether the stored alternative is Rectangle.
constexpr const Rectangle< PointType > * getIfRectangle () const
 Returns a pointer to the stored Rectangle, or nullptr when another alternative is active.
constexpr Rectangle< PointType > * getIfRectangle ()
 Returns a pointer to the stored Rectangle, or nullptr when another alternative is active.
constexpr bool isTriangle () const
 Tests whether the stored alternative is Triangle.
constexpr const Triangle< PointType > * getIfTriangle () const
 Returns a pointer to the stored Triangle, or nullptr when another alternative is active.
constexpr Triangle< PointType > * getIfTriangle ()
 Returns a pointer to the stored Triangle, or nullptr when another alternative is active.
constexpr bool isDisk () const
 Tests whether the stored alternative is Disk.
constexpr const Disk< PointType > * getIfDisk () const
 Returns a pointer to the stored Disk, or nullptr when another alternative is active.
constexpr Disk< PointType > * getIfDisk ()
 Returns a pointer to the stored Disk, or nullptr when another alternative is active.
constexpr bool isConvex () const
 Tests whether the stored alternative is Convex.
constexpr const Convex< PointType > * getIfConvex () const
 Returns a pointer to the stored Convex, or nullptr when another alternative is active.
constexpr Convex< PointType > * getIfConvex ()
 Returns a pointer to the stored Convex, or nullptr when another alternative is active.
constexpr bool isMonotoneChain () const
 Tests whether the stored alternative is MonotoneChain.
constexpr const MonotoneChain< PointType > * getIfMonotoneChain () const
 Returns a pointer to the stored MonotoneChain, or nullptr when another alternative is active.
constexpr MonotoneChain< PointType > * getIfMonotoneChain ()
 Returns a pointer to the stored MonotoneChain, or nullptr when another alternative is active.
constexpr bool isPolyline () const
 Tests whether the stored alternative is Polyline.
constexpr const Polyline< PointType > * getIfPolyline () const
 Returns a pointer to the stored Polyline, or nullptr when another alternative is active.
constexpr Polyline< PointType > * getIfPolyline ()
 Returns a pointer to the stored Polyline, or nullptr when another alternative is active.
constexpr bool isPolygon () const
 Tests whether the stored alternative is Polygon.
constexpr const Polygon< PointType > * getIfPolygon () const
 Returns a pointer to the stored Polygon, or nullptr when another alternative is active.
constexpr Polygon< PointType > * getIfPolygon ()
 Returns a pointer to the stored Polygon, or nullptr when another alternative is active.
constexpr bool isHalfplaneIntersection () const
 Tests whether the stored alternative is HalfplaneIntersection.
constexpr const HalfplaneIntersection< PointType > * getIfHalfplaneIntersection () const
 Returns a pointer to the stored HalfplaneIntersection, or nullptr when another alternative is active.
constexpr HalfplaneIntersection< PointType > * getIfHalfplaneIntersection ()
 Returns a pointer to the stored HalfplaneIntersection, or nullptr when another alternative is active.
constexpr bool isPolygonWithHoles () const
 Tests whether the stored alternative is PolygonWithHoles.
constexpr const PolygonWithHoles< PointType > * getIfPolygonWithHoles () const
 Returns a pointer to the stored PolygonWithHoles, or nullptr when another alternative is active.
constexpr PolygonWithHoles< PointType > * getIfPolygonWithHoles ()
 Returns a pointer to the stored PolygonWithHoles, or nullptr when another alternative is active.
constexpr bool isPolygonSet () const
 Tests whether the stored alternative is PolygonSet.
constexpr const PolygonSet< PointType > * getIfPolygonSet () const
 Returns a pointer to the stored PolygonSet, or nullptr when another alternative is active.
constexpr PolygonSet< PointType > * getIfPolygonSet ()
 Returns a pointer to the stored PolygonSet, or nullptr when another alternative is active.

Detailed Description

template<class PointType = Point<>>
struct pgl::Shape< PointType >

Runtime variant wrapper over the supported primitive shapes.

Type-erased wrapper over the finite set of supported primitive shapes.

Shape<PointType> stores one geometry in a variant and forwards common predicates through visitation.

Template Parameters
PointTypePoint type shared by every stored alternative.

Member Typedef Documentation

◆ LabelType

template<class PointType = Point<>>
using pgl::Shape< PointType >::LabelType = PointType::LabelType

Label type of the stored point type.

◆ NumberType

template<class PointType = Point<>>
using pgl::Shape< PointType >::NumberType = PointType::NumberType

Coordinate type of the stored point type.

◆ PointType_

template<class PointType = Point<>>
using pgl::Shape< PointType >::PointType_ = PointType

Point type shared by all alternatives.

◆ Variant

template<class PointType = Point<>>
using pgl::Shape< PointType >::Variant
Initial value:
std::variant<
PointType,
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
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
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
Closed triangle stored by three vertices.
Definition triangle.hpp:53

Variant type used for storage and visitation. The leading EmptyShape is the empty state of a default-constructed Shape.

Constructor & Destructor Documentation

◆ Shape() [1/3]

template<class PointType = Point<>>
pgl::Shape< PointType >::Shape ( )
constexprdefault

Creates a point-valued default shape.

◆ Shape() [2/3]

template<class PointType = Point<>>
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
pgl::Shape< PointType >::Shape ( T && value)
inlineconstexpr

Constructs a shape from one supported alternative.

Template Parameters
TAlternative type.
Parameters
valueShape value to store.

◆ Shape() [3/3]

template<class PointType = Point<>>
template<class Result>
requires (detail::is_shape_variant_v<PointType, Result> || detail::is_shape_optional_variant_v<PointType, Result>)
pgl::Shape< PointType >::Shape ( const Result & result)
inlineconstexpr

Constructs a shape from a variant over supported alternatives.

Accepts a std::variant whose alternatives are all supported shape types, or such a variant wrapped in a std::optional. The active alternative is forwarded to the single-alternative constructor; a valueless std::optional yields the empty shape. The variant's alternatives are checked at compile time, so a variant that could hold a non-shape is rejected.

Template Parameters
Resultstd::variant of alternatives, or std::optional thereof.
Parameters
resultVariant (optionally absent) to unwrap.

Member Function Documentation

◆ bbox()

template<class PointType = Point<>>
Rectangle< PointType > pgl::Shape< PointType >::bbox ( ) const
inlinenodiscardconstexpr

Returns the wrapped shape's axis-aligned bounding box.

Dispatches to the alternative's bbox().

Exceptions
std::logic_errorif the wrapped alternative is unbounded and therefore has no bbox() — the EmptyShape, Line, OrientedLine, Ray, and Halfplane alternatives, and a HalfplaneIntersection whose own bbox() throws when the region is unbounded or empty.

◆ boundaryContains()

template<class PointType = Point<>>
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
bool pgl::Shape< PointType >::boundaryContains ( const Other & other) const
inlineconstexpr

Tests whether this shape's boundary contains the other shape (∂A ⊇ B).

Template Parameters
OtherShape or a supported alternative type.
Parameters
otherOperand to test.
Returns
Result of dispatching boundaryContains.

◆ contains()

template<class PointType = Point<>>
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
bool pgl::Shape< PointType >::contains ( const Other & other) const
inlineconstexpr

Tests whether this shape contains the other shape (A ⊇ B).

Template Parameters
OtherShape or a supported alternative type.
Parameters
otherOperand to test.
Returns
Result of dispatching contains.

◆ crosses()

template<class PointType = Point<>>
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
bool pgl::Shape< PointType >::crosses ( const Other & other) const
inlineconstexpr

Tests whether the two shapes mutually separate each other (each disconnects the other).

Template Parameters
OtherShape or a supported alternative type.
Parameters
otherOperand to test.
Returns
Result of dispatching crosses when available.

◆ difference()

template<class PointType = Point<>>
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
PolygonSet< Point< ResultNumber, LabelType > > pgl::Shape< PointType >::difference ( const Other & other) const
inlinenodiscard

Returns the regularized set difference of the two shapes (A ∖ B).

Visits the stored alternative (and other when it is itself a Shape) and delegates to the concrete difference requesting ResultNumber coordinates. See Polygon::difference for the contract.

Like regularizedUnion and unlike intersection this does not re-wrap its answer: every pair that has a difference at all answers with a PolygonSet, so the static type is already exact.

This is the one of the three that is not symmetric, and the one whose grid is therefore not square. A ∖ B is contained in A, so it is bounded as soon as the receiver is, however far B reaches — which is why an unbounded subtrahend is accepted here where regularizedUnion cannot take one on either side.

Template Parameters
ResultNumberCoordinate type of the result (defaults to division_result_t for this wrapper's coordinate type).
OtherShape or a supported alternative type.
Parameters
otherShape to remove.
Returns
The pieces of the difference, in canonical order.
Exceptions
std::logic_errorwhen the pair selected at run time has no difference a PolygonSet can hold. The left alternative must be PolygonalRegionConcept — a Rectangle, Triangle, Convex, Polygon, PolygonWithHoles or PolygonSet — and the right one must be one of those or a Halfplane or HalfplaneIntersection, which have area but need not be bounded. Everything else throws: an alternative with no area would leave the whole of A behind rather than remove anything, and a Disk is round.

◆ distanceL1()

template<class PointType = Point<>>
template<class ResultNumber = double, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
ResultNumber pgl::Shape< PointType >::distanceL1 ( const Other & other) const
inlineconstexpr

Returns the Manhattan (L1) distance to the given shape.

Visits the stored alternative (and other when it is itself a Shape) and delegates to the concrete distanceL1 requesting ResultNumber coordinates.

Template Parameters
ResultNumberCoordinate type of the result (defaults to double, because the wrapped alternative may be a Disk).
OtherShape or a supported alternative type.
Parameters
otherShape to measure the distance to.
Returns
The L1 distance as ResultNumber.
Exceptions
std::logic_errorwhen distanceL1 is undefined for the pair selected at runtime — anything involving an EmptyShape, and any Disk pair other than Disk-Point (not yet implemented).
Warning
Disk::distanceL1 (like Disk::squaredDistance) reports in detail::floating_result_t<ResultNumber>, so an exact ResultNumber is served in double and then static_cast back rather than computed exactly.
With an integer ResultNumber the exact distance is generally a fraction for a non-axis-aligned segment, ray, or line, so the internal division truncates. Request a floating-point or pgl::Rational result type for an accurate value.

◆ distanceLInf()

template<class PointType = Point<>>
template<class ResultNumber = double, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
ResultNumber pgl::Shape< PointType >::distanceLInf ( const Other & other) const
inlineconstexpr

Returns the Chebyshev (LInf) distance to the given shape.

Visits the stored alternative (and other when it is itself a Shape) and delegates to the concrete distanceL1 requesting ResultNumber coordinates.

Template Parameters
ResultNumberCoordinate type of the result (defaults to double, because the wrapped alternative may be a Disk).
OtherShape or a supported alternative type.
Parameters
otherShape to measure the distance to.
Returns
The L1 distance as ResultNumber.
Exceptions
std::logic_errorwhen distanceL1 is undefined for the pair selected at runtime — anything involving an EmptyShape, and any Disk pair other than Disk-Point (not yet implemented).
Warning
Disk::distanceL1 (like Disk::squaredDistance) reports in detail::floating_result_t<ResultNumber>, so an exact ResultNumber is served in double and then static_cast back rather than computed exactly.
With an integer ResultNumber the exact distance is generally a fraction for a non-axis-aligned segment, ray, or line, so the internal division truncates. Request a floating-point or pgl::Rational result type for an accurate value.

◆ empty()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::empty ( ) const
inlinenodiscardconstexpr

Tests whether the wrapped shape covers no point at all.

The EmptyShape alternative of a default-constructed wrapper is always empty. Every other alternative that has an empty state of its own – Rectangle, Convex, Polygon, PolygonWithHoles, PolygonSet, HalfplaneIntersection, Polyline, and MonotoneChain – answers its own empty(), so a wrapper holding an empty Rectangle is empty as well. An alternative that is defined by points it always covers is never empty and answers false.

This is a question about the stored geometry, not about which alternative is stored; holdsAlternative<EmptyShape<PointType>>() asks the latter.

Returns
true when the wrapped shape is the empty set of points.

◆ get()

template<class PointType = Point<>>
PointType_ pgl::Shape< PointType >::get ( std::ptrdiff_t index) const
inlinenodiscardconstexpr

Returns the i-th vertex (modulo size()) of the wrapped shape.

Dispatches via std::visit to the alternative's get(index). Only defined for alternatives whose get yields a PointType_ — i.e., every alternative except Point itself, whose get yields a coordinate, HalfplaneIntersection, whose get yields a half-plane, and PolygonWithHoles and PolygonSet, which have no single indexable vertex sequence. Throws std::logic_error for those four alternatives.

◆ getIf() [1/2]

template<class PointType = Point<>>
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
std::remove_cvref_t< T > * pgl::Shape< PointType >::getIf ( )
inlineconstexpr

Returns a mutable pointer to the stored alternative when it matches T.

Template Parameters
TAlternative type.
Returns
Pointer to the stored value or nullptr.

◆ getIf() [2/2]

template<class PointType = Point<>>
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
const std::remove_cvref_t< T > * pgl::Shape< PointType >::getIf ( ) const
inlineconstexpr

Returns a pointer to the stored alternative when it matches T.

Template Parameters
TAlternative type.
Returns
Pointer to the stored value or nullptr.

◆ getIfConvex() [1/2]

template<class PointType = Point<>>
Convex< PointType > * pgl::Shape< PointType >::getIfConvex ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Convex, or nullptr when another alternative is active.

◆ getIfConvex() [2/2]

template<class PointType = Point<>>
const Convex< PointType > * pgl::Shape< PointType >::getIfConvex ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Convex, or nullptr when another alternative is active.

◆ getIfDisk() [1/2]

template<class PointType = Point<>>
Disk< PointType > * pgl::Shape< PointType >::getIfDisk ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Disk, or nullptr when another alternative is active.

◆ getIfDisk() [2/2]

template<class PointType = Point<>>
const Disk< PointType > * pgl::Shape< PointType >::getIfDisk ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Disk, or nullptr when another alternative is active.

◆ getIfHalfplane() [1/2]

template<class PointType = Point<>>
Halfplane< PointType > * pgl::Shape< PointType >::getIfHalfplane ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Halfplane, or nullptr when another alternative is active.

◆ getIfHalfplane() [2/2]

template<class PointType = Point<>>
const Halfplane< PointType > * pgl::Shape< PointType >::getIfHalfplane ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Halfplane, or nullptr when another alternative is active.

◆ getIfHalfplaneIntersection() [1/2]

template<class PointType = Point<>>
HalfplaneIntersection< PointType > * pgl::Shape< PointType >::getIfHalfplaneIntersection ( )
inlinenodiscardconstexpr

Returns a pointer to the stored HalfplaneIntersection, or nullptr when another alternative is active.

◆ getIfHalfplaneIntersection() [2/2]

template<class PointType = Point<>>
const HalfplaneIntersection< PointType > * pgl::Shape< PointType >::getIfHalfplaneIntersection ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored HalfplaneIntersection, or nullptr when another alternative is active.

◆ getIfLine() [1/2]

template<class PointType = Point<>>
Line< PointType > * pgl::Shape< PointType >::getIfLine ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Line, or nullptr when another alternative is active.

◆ getIfLine() [2/2]

template<class PointType = Point<>>
const Line< PointType > * pgl::Shape< PointType >::getIfLine ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Line, or nullptr when another alternative is active.

◆ getIfMonotoneChain() [1/2]

template<class PointType = Point<>>
MonotoneChain< PointType > * pgl::Shape< PointType >::getIfMonotoneChain ( )
inlinenodiscardconstexpr

Returns a pointer to the stored MonotoneChain, or nullptr when another alternative is active.

◆ getIfMonotoneChain() [2/2]

template<class PointType = Point<>>
const MonotoneChain< PointType > * pgl::Shape< PointType >::getIfMonotoneChain ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored MonotoneChain, or nullptr when another alternative is active.

◆ getIfOrientedLine() [1/2]

template<class PointType = Point<>>
OrientedLine< PointType > * pgl::Shape< PointType >::getIfOrientedLine ( )
inlinenodiscardconstexpr

Returns a pointer to the stored OrientedLine, or nullptr when another alternative is active.

◆ getIfOrientedLine() [2/2]

template<class PointType = Point<>>
const OrientedLine< PointType > * pgl::Shape< PointType >::getIfOrientedLine ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored OrientedLine, or nullptr when another alternative is active.

◆ getIfOrientedSegment() [1/2]

template<class PointType = Point<>>
OrientedSegment< PointType > * pgl::Shape< PointType >::getIfOrientedSegment ( )
inlinenodiscardconstexpr

Returns a pointer to the stored OrientedSegment, or nullptr when another alternative is active.

◆ getIfOrientedSegment() [2/2]

template<class PointType = Point<>>
const OrientedSegment< PointType > * pgl::Shape< PointType >::getIfOrientedSegment ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored OrientedSegment, or nullptr when another alternative is active.

◆ getIfPoint() [1/2]

template<class PointType = Point<>>
PointType * pgl::Shape< PointType >::getIfPoint ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Point, or nullptr when another alternative is active.

◆ getIfPoint() [2/2]

template<class PointType = Point<>>
const PointType * pgl::Shape< PointType >::getIfPoint ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Point, or nullptr when another alternative is active.

◆ getIfPolygon() [1/2]

template<class PointType = Point<>>
Polygon< PointType > * pgl::Shape< PointType >::getIfPolygon ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Polygon, or nullptr when another alternative is active.

◆ getIfPolygon() [2/2]

template<class PointType = Point<>>
const Polygon< PointType > * pgl::Shape< PointType >::getIfPolygon ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Polygon, or nullptr when another alternative is active.

◆ getIfPolygonSet() [1/2]

template<class PointType = Point<>>
PolygonSet< PointType > * pgl::Shape< PointType >::getIfPolygonSet ( )
inlinenodiscardconstexpr

Returns a pointer to the stored PolygonSet, or nullptr when another alternative is active.

◆ getIfPolygonSet() [2/2]

template<class PointType = Point<>>
const PolygonSet< PointType > * pgl::Shape< PointType >::getIfPolygonSet ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored PolygonSet, or nullptr when another alternative is active.

◆ getIfPolygonWithHoles() [1/2]

template<class PointType = Point<>>
PolygonWithHoles< PointType > * pgl::Shape< PointType >::getIfPolygonWithHoles ( )
inlinenodiscardconstexpr

Returns a pointer to the stored PolygonWithHoles, or nullptr when another alternative is active.

◆ getIfPolygonWithHoles() [2/2]

template<class PointType = Point<>>
const PolygonWithHoles< PointType > * pgl::Shape< PointType >::getIfPolygonWithHoles ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored PolygonWithHoles, or nullptr when another alternative is active.

◆ getIfPolyline() [1/2]

template<class PointType = Point<>>
Polyline< PointType > * pgl::Shape< PointType >::getIfPolyline ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Polyline, or nullptr when another alternative is active.

◆ getIfPolyline() [2/2]

template<class PointType = Point<>>
const Polyline< PointType > * pgl::Shape< PointType >::getIfPolyline ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Polyline, or nullptr when another alternative is active.

◆ getIfRay() [1/2]

template<class PointType = Point<>>
Ray< PointType > * pgl::Shape< PointType >::getIfRay ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Ray, or nullptr when another alternative is active.

◆ getIfRay() [2/2]

template<class PointType = Point<>>
const Ray< PointType > * pgl::Shape< PointType >::getIfRay ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Ray, or nullptr when another alternative is active.

◆ getIfRectangle() [1/2]

template<class PointType = Point<>>
Rectangle< PointType > * pgl::Shape< PointType >::getIfRectangle ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Rectangle, or nullptr when another alternative is active.

◆ getIfRectangle() [2/2]

template<class PointType = Point<>>
const Rectangle< PointType > * pgl::Shape< PointType >::getIfRectangle ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Rectangle, or nullptr when another alternative is active.

◆ getIfSegment() [1/2]

template<class PointType = Point<>>
Segment< PointType > * pgl::Shape< PointType >::getIfSegment ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Segment, or nullptr when another alternative is active.

◆ getIfSegment() [2/2]

template<class PointType = Point<>>
const Segment< PointType > * pgl::Shape< PointType >::getIfSegment ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Segment, or nullptr when another alternative is active.

◆ getIfTriangle() [1/2]

template<class PointType = Point<>>
Triangle< PointType > * pgl::Shape< PointType >::getIfTriangle ( )
inlinenodiscardconstexpr

Returns a pointer to the stored Triangle, or nullptr when another alternative is active.

◆ getIfTriangle() [2/2]

template<class PointType = Point<>>
const Triangle< PointType > * pgl::Shape< PointType >::getIfTriangle ( ) const
inlinenodiscardconstexpr

Returns a pointer to the stored Triangle, or nullptr when another alternative is active.

◆ hausdorffDistanceL1()

template<class PointType = Point<>>
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
ResultNumber pgl::Shape< PointType >::hausdorffDistanceL1 ( const Other & other) const
inlineconstexpr

Returns the Manhattan (L1) Hausdorff distance to the given shape.

Visits the stored alternative (and other when it is itself a Shape) and delegates to the concrete hausdorffDistanceL1 requesting ResultNumber coordinates.

Template Parameters
ResultNumberCoordinate type of the result (defaults to division_result_t for this wrapper's coordinate type).
OtherShape or a supported alternative type.
Parameters
otherShape to measure the Hausdorff distance to.
Returns
The L1 Hausdorff distance as ResultNumber.
Exceptions
std::logic_errorwhen hausdorffDistanceL1 is undefined for the pair selected at runtime. Defined only for Point, Segment, OrientedSegment, Rectangle, Triangle, and Convex; any pair involving Line, OrientedLine, Ray, Halfplane, Disk, MonotoneChain, Polyline, Polygon, HalfplaneIntersection, PolygonWithHoles, or PolygonSet always throws.
Warning
With an integer ResultNumber the exact distance is generally a fraction, so the internal division truncates. Request a floating-point or pgl::Rational result type for an accurate value.

◆ hausdorffDistanceLInf()

template<class PointType = Point<>>
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
ResultNumber pgl::Shape< PointType >::hausdorffDistanceLInf ( const Other & other) const
inlineconstexpr

Returns the Chebyshev (LInf) Hausdorff distance to the given shape.

Visits the stored alternative (and other when it is itself a Shape) and delegates to the concrete hausdorffDistanceL1 requesting ResultNumber coordinates.

Template Parameters
ResultNumberCoordinate type of the result (defaults to division_result_t for this wrapper's coordinate type).
OtherShape or a supported alternative type.
Parameters
otherShape to measure the Hausdorff distance to.
Returns
The L1 Hausdorff distance as ResultNumber.
Exceptions
std::logic_errorwhen hausdorffDistanceL1 is undefined for the pair selected at runtime. Defined only for Point, Segment, OrientedSegment, Rectangle, Triangle, and Convex; any pair involving Line, OrientedLine, Ray, Halfplane, Disk, MonotoneChain, Polyline, Polygon, HalfplaneIntersection, PolygonWithHoles, or PolygonSet always throws.
Warning
With an integer ResultNumber the exact distance is generally a fraction, so the internal division truncates. Request a floating-point or pgl::Rational result type for an accurate value.

◆ holdsAlternative()

template<class PointType = Point<>>
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
bool pgl::Shape< PointType >::holdsAlternative ( ) const
inlineconstexpr

Tests whether the wrapper currently stores a given alternative.

Template Parameters
TAlternative type.
Returns
true if the stored value has that type.

◆ index() [1/2]

template<class PointType = Point<>>
std::ptrdiff_t pgl::Shape< PointType >::index ( const NumberType & value) const
inlinenodiscardconstexpr

Returns the smallest index i with (*this)[i] == value, or -1 if no coordinate equals value.

Dispatches via std::visit to Point::index(value). The argument type selects this overload only for the Point alternative, whose operator[] yields a coordinate; every other alternative indexes points via the index(const PointType_&) overload. Throws std::logic_error if the wrapped value is not a Point.

◆ index() [2/2]

template<class PointType = Point<>>
std::ptrdiff_t pgl::Shape< PointType >::index ( const PointType_ & point) const
inlinenodiscardconstexpr

Returns the smallest index i with (*this)[i] == point, or -1 if no vertex of the wrapped shape equals point.

Dispatches via std::visit to the alternative's index(point). The argument type selects this overload for every alternative except Point — whose operator[] yields a coordinate, handled by the index(const NumberType&) overload. Throws std::logic_error if the wrapped value is a Point, a HalfplaneIntersection, whose elements are half-planes rather than points, or a PolygonWithHoles or a PolygonSet, neither of which has a single indexable vertex sequence.

◆ interiorContains()

template<class PointType = Point<>>
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
bool pgl::Shape< PointType >::interiorContains ( const Other & other) const
inlineconstexpr

Tests whether this shape's interior contains the other shape (A∖∂A ⊇ B).

Template Parameters
OtherShape or a supported alternative type.
Parameters
otherOperand to test.
Returns
Result of dispatching interiorContains.

◆ interiorsIntersect()

template<class PointType = Point<>>
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
bool pgl::Shape< PointType >::interiorsIntersect ( const Other & other) const
inlineconstexpr

Tests whether the interiors of the two shapes intersect ((A∖∂A) ∩ (B∖∂B) ≠ ∅).

Template Parameters
OtherShape or a supported alternative type.
Parameters
otherOperand to test.
Returns
Result of dispatching interiorsIntersect.

◆ intersection()

template<class PointType = Point<>>
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
Shape< Point< ResultNumber, LabelType > > pgl::Shape< PointType >::intersection ( const Other & other) const
inlineconstexpr

Returns the intersection of the two shapes (A ∩ B), empty when they are disjoint.

Visits the stored alternative (and other when it is itself a Shape), delegates to the concrete intersection requesting ResultNumber coordinates, and re-wraps the result. An empty intersection becomes an EmptyShape. The returned wrapper is parameterized on the result point type, which may differ from this wrapper's.

Template Parameters
ResultNumberCoordinate type of the result (defaults to division_result_t for this wrapper's coordinate type).
OtherShape or a supported alternative type.
Parameters
otherShape to intersect with.
Returns
The intersection wrapped in a Shape<Point<ResultNumber, LabelType>>.
Exceptions
std::logic_errorwhen the result cannot be represented by a single Shape — i.e. a disconnected intersection with no single alternative to hold it, or a pair whose intersection is unsupported (anything against a Disk, and a HalfplaneIntersection against a MonotoneChain or Polyline). Two Halfplanes, and a HalfplaneIntersection against a Halfplane, Rectangle, Triangle, Convex, or another HalfplaneIntersection, wrap their (possibly unbounded or empty) HalfplaneIntersection result. A HalfplaneIntersection against a Polygon wraps the single component of its component vector, in either order. A PolygonWithHoles against a one-dimensional alternative — a Point, Segment, OrientedSegment, Line, OrientedLine, Ray, MonotoneChain or Polyline — a PolygonWithHoles wraps the single point-or-segment piece instead, in either order, and throws when there are several, a hole being exactly what makes that likely. A PolygonWithHoles or a PolygonSet against an area alternative wraps the single piece of its literal intersection the same way, and throws just as readily: an intersection of regions comes apart into a piece per area component plus one per stretch of shared boundary. Reach for the separately named regularizedIntersection when only the areas are wanted — it answers with a PolygonSet, so a result in several pieces is never what makes it throw. Its overload grid is narrower than this one's, though: it needs a PolygonWithHoles or a PolygonSet on one side, so it throws for a pair drawn only from Rectangle, Triangle, Convex and Polygon, where regularizedUnion, difference and symmetricDifference all answer.
Warning
Divides coordinates after casting to ResultNumber.

◆ intersects()

template<class PointType = Point<>>
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
bool pgl::Shape< PointType >::intersects ( const Other & other) const
inlineconstexpr

Tests whether this shape and the other shape intersect (A ∩ B ≠ ∅).

Template Parameters
OtherShape or a supported alternative type.
Parameters
otherOperand to test.
Returns
Result of dispatching intersects.

◆ isConvex()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isConvex ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Convex.

◆ isDegenerate()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isDegenerate ( ) const
inlinenodiscardconstexpr

Tests whether the wrapped shape is degenerate.

Returns
Result of dispatching isDegenerate when available.

◆ isDisk()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isDisk ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Disk.

◆ isHalfplane()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isHalfplane ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Halfplane.

◆ isHalfplaneIntersection()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isHalfplaneIntersection ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is HalfplaneIntersection.

◆ isLine()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isLine ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Line.

◆ isMonotoneChain()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isMonotoneChain ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is MonotoneChain.

◆ isOrientedLine()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isOrientedLine ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is OrientedLine.

◆ isOrientedSegment()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isOrientedSegment ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is OrientedSegment.

◆ isPoint()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isPoint ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Point.

◆ isPolygon()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isPolygon ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Polygon.

◆ isPolygonSet()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isPolygonSet ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is PolygonSet.

◆ isPolygonWithHoles()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isPolygonWithHoles ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is PolygonWithHoles.

◆ isPolyline()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isPolyline ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Polyline.

◆ isRay()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isRay ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Ray.

◆ isRectangle()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isRectangle ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Rectangle.

◆ isSegment()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isSegment ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Segment.

◆ isTriangle()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::isTriangle ( ) const
inlinenodiscardconstexpr

Tests whether the stored alternative is Triangle.

◆ minkowskiErosion()

template<class PointType>
requires MinkowskiSummableConcept<Shape<PointType>, OtherShape>
template<class OtherShape>
requires MinkowskiSummableConcept<Shape<PointType>, OtherShape>
auto pgl::Shape< PointType >::minkowskiErosion ( const OtherShape< PointType > & other) const
nodiscardconstexpr

Returns the Minkowski erosion of this shape by another (A ⊖ B).

The erosion is the point set {x : x ⊕ B ⊆ A}, the translations of other that keep it inside this shape – equivalently ⋂ {A - b : b ∈ B}. It is the morphological dual of minkowskiSum and is defined for the same pairs, but it is not commutative.

Eroding by a Point is the translation by its negation, so it returns this shape's own type; the other pairs come back as the convex region they are, a HalfplaneIntersection, which holds a lower-dimensional erosion and the empty one as readily as a two-dimensional one. The pair of stored alternatives decides, and only at run time.

Eroding by a shape that covers no point is the whole plane, which a HalfplaneIntersection returns and the tighter result types cannot.

Template Parameters
OtherShapeType of the shape to erode by.
Parameters
otherShape to erode by.
Returns
The erosion, in the tightest type that represents it.

◆ minkowskiSum()

template<class PointType>
requires MinkowskiSummableConcept<Shape<PointType>, OtherShape>
template<class OtherShape>
requires MinkowskiSummableConcept<Shape<PointType>, OtherShape>
auto pgl::Shape< PointType >::minkowskiSum ( const OtherShape< PointType > & other) const
nodiscardconstexpr

Returns the Minkowski sum of this shape and another (A ⊕ B).

The sum is the point set {a + b : a ∈ A, b ∈ B}. Summing with a Point is a translation, so it returns this shape's own type; two bounded convex shapes sum to a Convex, or to a Rectangle when both are rectangles. See MinkowskiSummableConcept for the pairs a Minkowski sum is defined for.

Template Parameters
OtherShapeType of the other shape.
Parameters
otherShape to sum with.
Returns
The Minkowski sum, in the tightest type that represents it.

◆ operator T()

template<class PointType = Point<>>
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
pgl::Shape< PointType >::operator T ( ) const
inlineexplicitconstexpr

Converts to the currently stored alternative.

Lets an unwrapped alternative be recovered directly, e.g. Point cross = shape; when shape holds a Point.

Template Parameters
TAlternative type to extract.
Returns
A copy of the stored value.
Exceptions
std::bad_variant_accessif the wrapper holds a different alternative.

◆ operator*=()

template<class PointType = Point<>>
template<class Scalar>
requires (!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
Shape & pgl::Shape< PointType >::operator*= ( const Scalar & scalar)
inlineconstexpr

Scales the stored shape in place around the origin.

Visits the active alternative and scales it by scalar; the empty shape is left unchanged. The stored alternative type is preserved.

Template Parameters
ScalarScaling factor type.
Parameters
scalarScaling factor.
Returns
This wrapper.

◆ operator+=()

template<class PointType = Point<>>
template<PointConcept OtherPoint>
Shape & pgl::Shape< PointType >::operator+= ( const OtherPoint & translation)
inlineconstexpr

Translates the stored shape in place.

Visits the active alternative and translates it by translation; the empty shape is left unchanged. The stored alternative type is preserved.

Template Parameters
OtherPointTranslation point type.
Parameters
translationTranslation vector.
Returns
This wrapper.

◆ operator-=()

template<class PointType = Point<>>
template<PointConcept OtherPoint>
Shape & pgl::Shape< PointType >::operator-= ( const OtherPoint & translation)
inlineconstexpr

Translates the stored shape in place by a negated point.

Visits the active alternative and translates it by translation; the empty shape is left unchanged. The stored alternative type is preserved.

Template Parameters
OtherPointTranslation point type.
Parameters
translationTranslation vector.
Returns
This wrapper.

◆ operator/=()

template<class PointType = Point<>>
template<class Scalar>
requires (!detail::is_point_v<Scalar> && !TransformationConcept<Scalar>)
Shape & pgl::Shape< PointType >::operator/= ( const Scalar & scalar)
inlineconstexpr

Divides the stored shape in place around the origin.

Visits the active alternative and divides it by scalar; the empty shape is left unchanged. The stored alternative type is preserved.

Template Parameters
ScalarScaling factor type.
Parameters
scalarScaling factor.
Returns
This wrapper.

◆ operator<=>()

template<class PointType = Point<>>
auto pgl::Shape< PointType >::operator<=> ( const Shape< PointType > & ) const
constexprdefault

Orders wrapped values by the underlying variant ordering.

◆ operator=()

template<class PointType = Point<>>
template<class T>
requires (detail::ShapeAlternative<PointType, T>)
Shape & pgl::Shape< PointType >::operator= ( T && value)
inlineconstexpr

Replaces the stored alternative.

Template Parameters
TAlternative type.
Parameters
valueNew shape value.
Returns
This wrapper.

◆ operator==()

template<class PointType = Point<>>
bool pgl::Shape< PointType >::operator== ( const Shape< PointType > & ) const
constexprdefault

Compares wrapped values.

◆ operator[]()

template<class PointType = Point<>>
PointType_ pgl::Shape< PointType >::operator[] ( std::size_t index) const
inlinenodiscardconstexpr

Returns the vertex at index of the wrapped shape.

Dispatches via std::visit to the alternative's operator[](index). Only defined for alternatives whose operator[] yields a PointType_ — i.e., every alternative except Point itself, whose operator[] yields a coordinate, HalfplaneIntersection, whose operator[] yields a half-plane, and PolygonWithHoles and PolygonSet, which have no single indexable vertex sequence. Throws std::logic_error for those four alternatives.

◆ regularizedIntersection()

template<class PointType = Point<>>
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
PolygonSet< Point< ResultNumber, LabelType > > pgl::Shape< PointType >::regularizedIntersection ( const Other & other) const
inlinenodiscard

Returns the regularized intersection of two region-valued shapes.

Visits the stored alternative and delegates to the concrete regularizedIntersection. The result is closure(A° ∩ B°) as a PolygonSet; lower-dimensional contacts are discarded. See PolygonWithHoles::regularizedIntersection for the full contract.

Unlike its three siblings, this one is not defined for every pair of bounded regions. One operand must be a PolygonWithHoles or a PolygonSet; the other may then be any of the six bounded region types, a Halfplane, or a HalfplaneIntersection — an unbounded operand is fine here because A ∩ B is bounded as soon as A is. A pair drawn only from Rectangle, Triangle, Convex and Polygon throws, even though regularizedUnion, difference and symmetricDifference cover all thirty-six ordered pairs of the six. Calling asPolygonWithHoles() on either operand first reaches the operation.

Exceptions
std::logic_errorwhen neither operand is a PolygonWithHoles or a PolygonSet, or when the other operand is not one of the regions listed above — the pair then has no region-valued regularized intersection.

◆ regularizedUnion()

template<class PointType = Point<>>
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
PolygonSet< Point< ResultNumber, LabelType > > pgl::Shape< PointType >::regularizedUnion ( const Other & other) const
inlinenodiscard

Returns the regularized union closure(A° ∪ B°).

Visits the stored alternative (and other when it is itself a Shape) and delegates to the concrete regularizedUnion requesting ResultNumber coordinates. See Polygon::regularizedUnion for the contract.

Unlike intersection this does not re-wrap its answer, because it does not have to: every pair that has a union at all answers with a PolygonSet, so the static type is already exact and the caller is spared an unwrap. Nor can it fail the way an intersection can — a union that comes apart into several pieces is still one set — so the throw below is only ever about the pair, never about the result.

Template Parameters
ResultNumberCoordinate type of the result (defaults to division_result_t for this wrapper's coordinate type).
OtherShape or a supported alternative type.
Parameters
otherShape to unite with.
Returns
The pieces of the union, in canonical order.
Exceptions
std::logic_errorwhen the pair selected at run time has no union a PolygonSet can hold. It succeeds exactly when both alternatives are PolygonalRegionConcept — a Rectangle, Triangle, Convex, Polygon, PolygonWithHoles or PolygonSet — for all thirty-six ordered pairs of them, in either order. Every other alternative throws whatever it is paired with: an EmptyShape, Point, Segment, OrientedSegment, MonotoneChain or Polyline has no area, so the union keeps a piece no set of regions can express; a Line, OrientedLine, Ray, Halfplane or HalfplaneIntersection may be unbounded; and a Disk is round.

◆ rotate90()

template<class PointType = Point<>>
void pgl::Shape< PointType >::rotate90 ( int k = 1)
inlineconstexpr

Rotates the wrapped shape by 90k degrees around the origin in place.

Parameters
kNumber of 90-degree CCW rotations (may be negative).

◆ rotated90()

template<class PointType = Point<>>
Shape pgl::Shape< PointType >::rotated90 ( int k = 1) const
inlinenodiscardconstexpr

Returns the wrapped shape rotated by 90k degrees around the origin.

Parameters
kNumber of 90-degree CCW rotations (may be negative).
Returns
Rotated shape, preserving the stored alternative type.

◆ samePointSet()

template<class PointType>
template<AnyShapeConcept OtherShape>
bool pgl::Shape< PointType >::samePointSet ( const OtherShape< PointType > & other) const
nodiscardconstexpr

Tests whether another shape defines exactly the same point set.

◆ scaledDownX()

template<class PointType = Point<>>
template<class OtherNumber>
Shape pgl::Shape< PointType >::scaledDownX ( const OtherNumber scalar) const
inlinenodiscardconstexpr

Returns the wrapped shape with its x-coordinates scaled down.

Exceptions
std::logic_errorif the wrapped alternative cannot be scaled along a single axis (the Disk alternative, whose result would be an ellipse).

◆ scaledDownY()

template<class PointType = Point<>>
template<class OtherNumber>
Shape pgl::Shape< PointType >::scaledDownY ( const OtherNumber scalar) const
inlinenodiscardconstexpr

Returns the wrapped shape with its y-coordinates scaled down.

Exceptions
std::logic_errorif the wrapped alternative cannot be scaled along a single axis (the Disk alternative, whose result would be an ellipse).

◆ scaleDownX()

template<class PointType = Point<>>
template<class OtherNumber>
void pgl::Shape< PointType >::scaleDownX ( const OtherNumber scalar)
inlineconstexpr

Scales the wrapped shape's x-coordinates down in place.

Exceptions
std::logic_errorif the wrapped alternative cannot be scaled along a single axis (the Disk alternative).

◆ scaleDownY()

template<class PointType = Point<>>
template<class OtherNumber>
void pgl::Shape< PointType >::scaleDownY ( const OtherNumber scalar)
inlineconstexpr

Scales the wrapped shape's y-coordinates down in place.

Exceptions
std::logic_errorif the wrapped alternative cannot be scaled along a single axis (the Disk alternative).

◆ scaledUpX()

template<class PointType = Point<>>
template<class OtherNumber>
Shape pgl::Shape< PointType >::scaledUpX ( const OtherNumber scalar) const
inlinenodiscardconstexpr

Returns the wrapped shape with its x-coordinates scaled up.

Exceptions
std::logic_errorif the wrapped alternative cannot be scaled along a single axis (the Disk alternative, whose result would be an ellipse).

◆ scaledUpY()

template<class PointType = Point<>>
template<class OtherNumber>
Shape pgl::Shape< PointType >::scaledUpY ( const OtherNumber scalar) const
inlinenodiscardconstexpr

Returns the wrapped shape with its y-coordinates scaled up.

Exceptions
std::logic_errorif the wrapped alternative cannot be scaled along a single axis (the Disk alternative, whose result would be an ellipse).

◆ scaleUpX()

template<class PointType = Point<>>
template<class OtherNumber>
void pgl::Shape< PointType >::scaleUpX ( const OtherNumber scalar)
inlineconstexpr

Scales the wrapped shape's x-coordinates up in place.

Exceptions
std::logic_errorif the wrapped alternative cannot be scaled along a single axis (the Disk alternative).

◆ scaleUpY()

template<class PointType = Point<>>
template<class OtherNumber>
void pgl::Shape< PointType >::scaleUpY ( const OtherNumber scalar)
inlineconstexpr

Scales the wrapped shape's y-coordinates up in place.

Exceptions
std::logic_errorif the wrapped alternative cannot be scaled along a single axis (the Disk alternative).

◆ separates()

template<class PointType = Point<>>
template<class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
bool pgl::Shape< PointType >::separates ( const Other & other) const
inlineconstexpr

Tests whether removing this shape disconnects the other shape (B∖A is disconnected).

Template Parameters
OtherShape or a supported alternative type.
Parameters
otherOperand to test.
Returns
Result of dispatching separates when available.

◆ size()

template<class PointType = Point<>>
std::size_t pgl::Shape< PointType >::size ( ) const
inlinenodiscardconstexpr

Returns the number of indexable elements of the wrapped shape.

Dispatches to the alternative's size() so the result matches the valid range of its operator[].

Exceptions
std::logic_errorfor the PolygonWithHoles and PolygonSet alternatives, neither of which has a single indexable sequence: a region's vertices are spread over its outer ring and its holes, and a set's over its components. Reach through with getIfPolygonWithHoles() and use vertexCount(), outer(), or holes(); with getIfPolygonSet() and use vertexCount(), componentCount(), or component().

◆ squaredDistance()

template<class PointType = Point<>>
template<class ResultNumber = double, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
ResultNumber pgl::Shape< PointType >::squaredDistance ( const Other & other) const
inlineconstexpr

Returns the squared Euclidean distance to the given shape.

Visits the stored alternative (and other when it is itself a Shape) and delegates to the concrete squaredDistance requesting ResultNumber coordinates.

Template Parameters
ResultNumberCoordinate type of the result (defaults to double, because the wrapped alternative may be a Disk).
OtherShape or a supported alternative type.
Parameters
otherShape to measure the distance to.
Returns
The squared Euclidean distance as ResultNumber.
Exceptions
std::logic_errorwhen squaredDistance is undefined for the pair selected at runtime — anything involving an EmptyShape.
Warning
A pair involving a Disk computes in double; requesting a non-floating ResultNumber does not make that leg exact.
With an integer ResultNumber the exact squared distance is generally a fraction, so the internal division truncates and the result is inexact. Request a floating-point or pgl::Rational result type for an accurate value.

◆ squaredHausdorffDistance()

template<class PointType = Point<>>
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
ResultNumber pgl::Shape< PointType >::squaredHausdorffDistance ( const Other & other) const
inlineconstexpr

Returns the squared Euclidean Hausdorff distance to the given shape.

Visits the stored alternative (and other when it is itself a Shape) and delegates to the concrete squaredHausdorffDistance requesting ResultNumber coordinates.

Template Parameters
ResultNumberCoordinate type of the result (defaults to division_result_t for this wrapper's coordinate type).
OtherShape or a supported alternative type.
Parameters
otherShape to measure the Hausdorff distance to.
Returns
The squared Hausdorff distance as ResultNumber.
Exceptions
std::logic_errorwhen squaredHausdorffDistance is undefined for the pair selected at runtime. Line, OrientedLine, Ray, Halfplane, Disk, MonotoneChain, Polyline, Polygon, HalfplaneIntersection, PolygonWithHoles, and PolygonSet never define it (unbounded shapes have a generally infinite Hausdorff distance; the others simply have no overload yet), so any pair involving one of those always throws.
Warning
With an integer ResultNumber the exact squared distance is generally a fraction, so the internal division truncates and the result is inexact. Request a floating-point or pgl::Rational result type for an accurate value.

◆ symmetricDifference()

template<class PointType = Point<>>
template<class ResultNumber = division_result_t<NumberType>, class Other>
requires (std::same_as<std::remove_cvref_t<Other>, Shape> || detail::ShapeAlternative<PointType, Other>)
PolygonSet< Point< ResultNumber, LabelType > > pgl::Shape< PointType >::symmetricDifference ( const Other & other) const
inlinenodiscard

Returns the regularized symmetric difference of the two shapes (A △ B).

Visits the stored alternative (and other when it is itself a Shape) and delegates to the concrete symmetricDifference requesting ResultNumber coordinates. See Polygon::symmetricDifference for the contract. It answers with a PolygonSet on the same grid, and throws off it, exactly as regularizedUnion and difference do.

Template Parameters
ResultNumberCoordinate type of the result (defaults to division_result_t for this wrapper's coordinate type).
OtherShape or a supported alternative type.
Parameters
otherThe other shape.
Returns
The pieces of the symmetric difference, in canonical order.
Exceptions
std::logic_errorwhen the pair selected at run time has no symmetric difference a PolygonSet can hold, which is the same set of pairs regularizedUnion throws on.

◆ variant() [1/2]

template<class PointType = Point<>>
Variant & pgl::Shape< PointType >::variant ( )
inlineconstexpr

Returns the underlying variant.

Returns
Mutable reference to the stored variant.

◆ variant() [2/2]

template<class PointType = Point<>>
const Variant & pgl::Shape< PointType >::variant ( ) const
inlineconstexpr

Returns the underlying variant.

Returns
Const reference to the stored variant.