header_utils
Loading...
Searching...
No Matches
triangles.h
1
4
5#pragma once
6
7#include "geometry_common.h"
8#include "./segment.h"
9
10namespace ghassanpl::geometry
11{
12
13 template <std::floating_point T>
14 struct ttriangle
15 {
16 using tvec = glm::tvec2<T>;
17 using value_type = T;
18
19 tvec a{};
20 tvec b{};
21 tvec c{};
22
23 template <typename FUNC>
24 void for_each_edge(FUNC&& func)
25 {
26 func(tsegment<T>{a, b});
27 func(tsegment<T>{b, c});
28 func(tsegment<T>{c, a});
29 }
30
31 trec2<T> bounding_box() const
32 {
34 res += a; res += b; res += c;
35 return res;
36 }
37
38 T edge_length() const
39 {
40 return glm::distance(a, b) + glm::distance(b, c) + glm::distance(c, a);
41 }
42
43 glm::tvec2<T> edge_point_alpha(T t) const;
44 glm::tvec2<T> edge_point(T t) const;
45 glm::tvec2<T> projected(glm::tvec2<T> pt) const;
46
47 static auto sign(tvec const& p1, tvec const& p2, tvec const& p3) noexcept
48 {
49 return (p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y);
50 }
51
52 winding_order winding() const noexcept
53 {
54 const auto d = sign(a, b, c);
55 return d > 0 ? winding_order::clockwise : winding_order::counter_clockwise;
56 }
57
58 bool contains(tvec pt) const noexcept
59 {
60 const auto d1 = sign(pt, a, b);
61 const auto d2 = sign(pt, b, c);
62 const auto d3 = sign(pt, c, a);
63 const auto has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
64 const auto has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);
65 return !(has_neg && has_pos);
66 }
67
68 auto calculate_area() const noexcept
69 {
70 const auto A = std::sqrt((b.x - a.x) * (b.x - a.x) + (b.y - a.y) * (b.y - a.y));
71 const auto B = std::sqrt((b.x - c.x) * (b.x - c.x) + (b.y - c.y) * (b.y - c.y));
72 const auto C = std::sqrt((b.x - c.x) * (a.x - c.x) + (a.y - c.y) * (a.y - c.y));
73 const auto s = (A + B + C) * T(0.5);
74 return std::sqrt(s * (s - A) * (s - B) * (s - C));
75 }
76 };
77
78 using triangle = ttriangle<float>;
79 static_assert(area_shape<triangle, float>);
80
81 template <std::integral IDX = size_t>
82 struct tindexed_triangle
83 {
84 std::array<IDX, 3> indices{};
85
86 template <std::ranges::random_access_range T>
87 auto a(T&& range) const -> std::ranges::range_value_t<T>
88 {
89 return range[indices[0]];
90 }
91 template <std::ranges::random_access_range T>
92 auto b(T&& range) const -> std::ranges::range_value_t<T>
93 {
94 return range[indices[1]];
95 }
96 template <std::ranges::random_access_range T>
97 auto c(T&& range) const -> std::ranges::range_value_t<T>
98 {
99 return range[indices[2]];
100 }
101
102 template <std::ranges::random_access_range T>
103 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]) }; }
104 };
105
106 using indexed_triangle = tindexed_triangle<size_t>;
107}
constexpr auto bit_count
Equal to the number of bits in the type.
Definition bits.h:33
constexpr decltype(auto) at(random_access_range auto &range, std::integral auto index)
Returns a reference to the value at index of range
Definition ranges.h:59
constexpr __contains_fn contains
contains(range, el)
Definition ranges.h:247