7#include "geometry_common.h"
16 template <std::
floating_po
int T>
19 using tvec = glm::tvec2<T>;
26 template <
typename FUNC>
27 void for_each_edge(FUNC&& func)
const
34 trec2<T> bounding_box()
const
37 res += a; res += b; res += c;
43 return glm::distance(a, b) + glm::distance(b, c) + glm::distance(c, a);
46 tvec edge_point_alpha(T t)
const;
47 tvec edge_point(T t)
const;
48 tvec closest_point_to(tvec pt)
const;
50 static auto sign(tvec
const& p1, tvec
const& p2, tvec
const& p3)
noexcept
52 return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
55 winding_order winding() const noexcept
57 const auto d = sign(a, b, c);
58 return d > 0 ? winding_order::clockwise : winding_order::counter_clockwise;
61 bool contains(tvec pt)
const noexcept
63 const auto d1 = sign(pt, a, b);
64 const auto d2 = sign(pt, b, c);
65 const auto d3 = sign(pt, c, a);
66 const auto has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
67 const auto has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);
68 return !(has_neg && has_pos);
71 auto calculate_area() const noexcept
73 const auto A = std::sqrt((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y));
74 const auto B = std::sqrt((b.x - c.x) * (b.x - c.x) + (b.y - c.y) * (b.y - c.y));
75 const auto C = std::sqrt((b.x - c.x) * (a.x - c.x) + (a.y - c.y) * (a.y - c.y));
76 const auto s = (A + B + C) * T(0.5);
77 return std::sqrt(s * (s - A) * (s - B) * (s - C));
82 return (a + b + c) / T(3);
85 glm::tvec3<T> barycentric_coords_of(glm::tvec2<T> pt)
const
87 const auto v0 = b - a;
88 const auto v1 = c - a;
89 const auto v2 = pt - a;
90 const auto d00 = glm::dot(v0, v0);
91 const auto d01 = glm::dot(v0, v1);
92 const auto d11 = glm::dot(v1, v1);
93 const auto d20 = glm::dot(v2, v0);
94 const auto d21 = glm::dot(v2, v1);
95 const auto denom = d00 * d11 - d01 * d01;
96 const auto v = (d11 * d20 - d01 * d21) / denom;
97 const auto w = (d00 * d21 - d01 * d20) / denom;
98 const auto u = 1 - v - w;
102 glm::tvec2<T> euclidean_coords_of(glm::tvec3<T> barycentric)
const
104 return a * barycentric.x + b * barycentric.y + c * barycentric.z;
125 template <
typename FUNC>
126 void for_each_vertex(FUNC&& func)
const
133 size_t vertex_count()
const {
return 3; }
135 size_t edge_count()
const {
return 3; }
137 auto edge(
size_t index)
const -> std::optional<std::pair<glm::tvec2<T>, glm::tvec2<T>>>
141 case 0:
return std::make_pair(a, b);
142 case 1:
return std::make_pair(b, c);
143 case 2:
return std::make_pair(c, a);
148 auto vertex(
size_t index)
const -> std::optional<tvec>
160 using triangle = ttriangle<float>;
165 template <std::
integral IDX_TYPE =
size_t>
172 template <std::ranges::random_access_range T>
173 auto a(T&& range)
const -> std::ranges::range_value_t<T>
177 template <std::ranges::random_access_range T>
178 auto b(T&& range)
const -> std::ranges::range_value_t<T>
182 template <std::ranges::random_access_range T>
183 auto c(T&& range)
const -> std::ranges::range_value_t<T>
188 template <std::ranges::random_access_range T>
189 auto as_triangle(T&& range)
const -> ttriangle<typename std::ranges::range_value_t<T>::value_type> {
return {
at(range,
indices[0]),
at(range,
indices[1]),
at(range,
indices[2]) }; }
A shape for which the concept of an "area" has a finite interpretation.
A shape with vertices and edges.
constexpr decltype(auto) at(random_access_range auto &range, std::integral auto index)
Returns a reference to the value at index of range.
constexpr __contains_fn contains
contains(range, el)
Stores three indices to a indexable_polygonlike that together form a triangle.
std::array< IDX_TYPE, 3 > indices