7#include "geometry_common.h"
9#include "./triangles.h"
14 template <std::
floating_po
int T>
17 using tvec = glm::tvec2<T>;
20 std::vector<glm::tvec2<T>> vertices;
22 tvec& operator[](
size_t index) {
return vertices.at(index); }
23 tvec
const& operator[](
size_t index)
const {
return vertices.at(index); }
25 auto cbegin()
const {
return std::ranges::cbegin(vertices); }
26 auto cend()
const {
return std::ranges::cend(vertices); }
27 auto begin() {
return std::ranges::begin(vertices); }
28 auto end() {
return std::ranges::end(vertices); }
29 auto begin()
const {
return std::ranges::cbegin(vertices); }
30 auto end()
const {
return std::ranges::cend(vertices); }
31 auto size()
const {
return std::ranges::size(vertices); }
33 bool is_valid()
const noexcept {
return vertices.size() > 2; }
38 constexpr bool is_simple()
const {
return simple; }
39 constexpr bool intersects_itself()
const {
return !simple; }
40 constexpr bool is_convex()
const {
return convex; }
41 constexpr bool is_concave()
const noexcept {
return simple && !convex; }
47 std::
optional<tsegment<T>> edge(
size_t index)
const
49 const auto c = vertices.size();
51 return tsegment<T>{vertices[index], vertices[index + 1]};
54 std::optional<tvec> vertex(
size_t index)
const
56 const auto c = vertices.size();
58 return vertices[index];
61 template <
typename FUNC>
64 const auto c = vertices.size();
67 for (
size_t i = 0;
i < c - 1; ++
i)
73 std::vector<tsegment<T>> result;
74 for_each_edge([&](
auto&&
seg) { result.push_back(
seg); });
83 for_each_edge([&](tvec
const&
v1, tvec
const&
v2) {
84 result += glm::distance(
v1,
v2);
89 tvec edge_point(T
t)
const
91 const auto el = edge_length();
92 return edge_point(
t,
el);
95 tvec edge_point_alpha(T
t)
const
97 const auto el = edge_length();
98 return edge_point(
t *
el,
el);
101 tvec projected(tvec
pt)
const;
103 T calculate_area()
const;
108 for (
auto& v : vertices)
117 const size_t nvert = vertices.size();
120 if (((vertices[
i].y >
test.y) != (vertices[
j].y >
test.y)) &&
121 (
test.x < (vertices[
j].x - vertices[
i].x) * (
test.y - vertices[
i].y) / (vertices[
j].y - vertices[
i].y) + vertices[
i].x))
133 auto c = vertices.size();
135 return c ? vertices[0] : tvec{};
138 for (
size_t i = 0;
i < c - 1; ++
i)
140 const auto d = glm::distance(vertices[
i], vertices[
i + 1]);
142 return glm::mix(vertices[
i], vertices[
i + 1],
t /
d);
152 static_assert(std::ranges::random_access_range<polygon>);
154 template <std::
floating_po
int T, std::
integral IDX =
size_t>
155 struct polygon_triangulation
157 using tvec = glm::tvec2<T>;
158 using value_type = T;
161 std::vector<tindexed_triangle<IDX>> triangles;
163 template <
typename FUNC>
166 for (
auto&
tr : triangles)
168 return tr.as_triangle(poly);
172 T edge_length()
const {
return poly.edge_length(); }
173 tvec edge_point_alpha(T
t)
const {
return poly.edge_point_alpha(
t); }
174 tvec edge_point(T
t)
const {
return poly.edge_point(
t); }
175 trec2<T> bounding_box()
const {
return poly.bounding_box(); }
176 tvec projected(glm::tvec2<T>
pt)
const {
return poly.projected(
pt); }
179 T calculate_area()
const;
184 template <std::
floating_po
int T, std::
integral IDX =
size_t>
185 struct triangulated_polygon
187 using tvec = glm::tvec2<T>;
188 using value_type = T;
191 std::vector<tindexed_triangle<IDX>> triangles;
193 T edge_length()
const {
return poly.edge_length(); }
194 tvec edge_point_alpha(T
t)
const {
return poly.edge_point_alpha(
t); }
195 tvec edge_point(T
t)
const {
return poly.edge_point(
t); }
196 trec2<T> bounding_box()
const {
return poly.bounding_box(); }
197 tvec projected(glm::tvec2<T>
pt)
const {
return poly.projected(
pt); }
200 T calculate_area()
const;
205 template <
typename POLY>
206 auto calculate_indexed_triangle_area(
POLY const& poly, indexed_triangle
const& triangle)
208 const auto a = poly[triangle.indices[0]];
209 const auto b = poly[triangle.indices[1]];
210 const auto c = poly[triangle.indices[2]];
211 using T =
typename POLY::value_type;
212 return geometry::ttriangle<T>{a, b, c}.calculate_area();
215 template <
typename TR>
216 auto calculate_total_area(
TR const&
trpoly)
218 using T =
decltype(
trpoly.poly)::value_type;
221 result += calculate_indexed_triangle_area(
trpoly.poly,
tr);
225 template <
typename T>
230 throw "unimplemented";
236 template <std::
floating_po
int T>
239 using tvec = glm::tvec2<T>;
240 using value_type = T;
241 using mutable_polygon = geometry::tpolygon<T>;
252 : m_poly(std::forward<
ARGS>(
args)...)
257 template <
typename POLY_OR_ARR>
260 , m_triangles(std::
move(triangles))
268 tvec
const& operator[](
size_t index)
const {
return m_poly.vertices.at(index); }
270 auto cbegin()
const noexcept {
return std::ranges::cbegin(m_poly.vertices); }
271 auto cend()
const noexcept {
return std::ranges::cend(m_poly.vertices); }
272 auto begin()
const noexcept {
return std::ranges::cbegin(m_poly.vertices); }
273 auto end()
const noexcept {
return std::ranges::cend(m_poly.vertices); }
274 auto size()
const noexcept {
return std::ranges::size(m_poly.vertices); }
280 T edge_length()
const {
return m_poly.edge_length(); }
281 tvec edge_point_alpha(T
t)
const {
return m_poly.edge_point_alpha(
t); }
282 tvec edge_point(T
t)
const {
return m_poly.edge_point(
t); }
283 trec2<T> bounding_box()
const {
return m_poly.bounding_box(); }
284 tvec projected(glm::tvec2<T>
pt)
const {
return m_poly.projected(
pt); }
288 T calculate_area()
const
291 return m_cached_area;
294 auto const& triangles()
const
300 auto const& areas()
const
303 return m_cached_triangle_areas;
306 bool has_triangle(
size_t i)
const { triangulate();
return i < m_triangles.size(); }
307 auto triangle(
size_t i)
const { triangulate();
return m_triangles.at(
i).as_triangle(m_poly); }
308 T triangle_area(
size_t i)
const { triangulate();
return m_cached_triangle_areas.at(
i); }
312 geometry::tpolygon<T> m_poly;
313 mutable std::vector<indexed_triangle> m_triangles;
314 mutable std::vector<T> m_cached_triangle_areas;
315 mutable T m_cached_area = std::numeric_limits<T>::lowest();
317 void triangulate()
const
319 if (m_triangles.empty() && m_poly.vertices.size() > 2)
321 auto&& [poly, triangles] = geometry::triangulate(m_poly);
322 m_triangles = std::move(triangles);
324 m_cached_triangle_areas.reserve(m_triangles.size());
326 for (
auto&
tr : m_triangles)
328 const auto area = calculate_indexed_triangle_area(poly,
tr);
329 m_cached_triangle_areas.push_back(
area);
343 template <std::
floating_po
int T>
constexpr auto bit_count
Equal to the number of bits in the type.
constexpr __contains_fn contains
contains(range, el)