header_utils
Loading...
Searching...
No Matches
shape_concepts.h
1
4
5#pragma once
6
7#include "geometry_common.h"
8#include <optional>
9
10namespace ghassanpl::geometry
11{
14
17 template <typename T, typename SHAPE>
18 concept shape = requires (SHAPE const& shape, glm::tvec2<T> pt, T t)
19 {
21 { shape.edge_length() } -> std::convertible_to<T>;
22
25 { shape.edge_point_alpha(t) } -> std::convertible_to<glm::tvec2<T>>;
26
29 { shape.edge_point(t) } -> std::convertible_to<glm::tvec2<T>>;
30
32 { shape.bounding_box() } -> std::convertible_to<trec2<T>>;
33
35 { shape.closest_point_to(pt) } -> std::convertible_to<glm::tvec2<T>>;
36
37 // interval<T> projected_on_axis(glm::tvec2<T> axis) const;
38 };
39
41 template <typename T, shape<T> S> auto distance(S const& sh, glm::tvec2<T> pt) { return glm::distance(sh.closest_point_to(pt), pt); }
42 template <typename T, shape<T> S> auto distance(glm::tvec2<T> pt, S const& sh) { return glm::distance(sh.closest_point_to(pt), pt); }
43
44 template <typename T, shape<T> S> auto distance_squared(S const& sh, glm::tvec2<T> pt) { const auto d = sh.closest_point_to(pt) - pt; return glm::dot(d, d); }
45 template <typename T, shape<T> S> auto distance_squared(glm::tvec2<T> pt, S const& sh) { const auto d = sh.closest_point_to(pt) - pt; return glm::dot(d, d); }
46
47 template <typename T>
48 std::optional<T> axis_overlaps(shape<T> auto const& a, shape<T> auto const& b, glm::vec2 const& axis)
49 {
50 interval<T> first = a.projected_on_axis(axis);
51 interval<T> second = b.projected_on_axis(axis);
52
53 return first.overlaps(second) ? first.overlap(second) : std::nullopt;
54 }
55
57 template <typename T, typename SHAPE>
58 concept area_shape = shape<T, SHAPE> && requires (SHAPE const& shape, glm::tvec2<T> pt, T t) {
59 { shape.contains(pt) } -> std::convertible_to<bool>;
60 { shape.calculate_area() } -> std::convertible_to<T>;
61 { shape.centroid() } -> std::convertible_to<glm::tvec2<T>>;
62 /*
63 { shape.moment_of_inertia() } -> std::convertible_to<T>;
64 { shape.moment_of_inertia(shape.centroid()) } -> std::convertible_to<T>;
65 { shape.moment_of_inertia(shape.centroid(), shape.centroid()) } -> std::convertible_to<T>;
66 */
67 };
68
71 template <typename T, typename SHAPE>
72 concept polygon_shape = shape<T, SHAPE> && requires (SHAPE const& shape) {
73 { shape.for_each_edge([](glm::tvec2<T> const& a, glm::tvec2<T> const& b) {}) };
74 { shape.for_each_vertex([](glm::tvec2<T> const& vertex) {}) };
75 { shape.vertex_count() } -> std::convertible_to<size_t>;
76 { shape.edge_count() } -> std::convertible_to<size_t>;
77 { shape.edge(size_t{}) } -> std::convertible_to<std::optional<std::pair<glm::tvec2<T>, glm::tvec2<T>>>>;
78 { shape.vertex(size_t{}) } -> std::convertible_to<std::optional<glm::tvec2<T>>>;
79 };
80
82 template <typename T, typename SHAPE>
84
86 template <typename POLY>
87 concept indexable_polygonlike = requires (POLY const& polygon, size_t i) {
90 { polygon[i] } -> is_specialization_of<glm::tvec2>;
91 };
92
94
96}
A shape for which the concept of an "area" has a finite interpretation.
Any type that we can index into which will return a tvec2 of some sort. This includes,...
An area_shape with vertices and edges.
A shape with vertices and edges.
Any contiguous non-empty set of 2D points.
auto distance(S const &sh, glm::tvec2< T > pt)
Returns the distance between a shape and a point.
For interval<T> projected_on_axis(glm::tvec2<T> axis) const;.