Skip to main content

fey_math/
triangle.rs

1use crate::{Float, Line, Num, Vec2, impl_approx, impl_bytemuck, impl_casts, impl_interp, line};
2use serde::{Deserialize, Serialize};
3
4pub type TriangleF = Triangle<f32>;
5pub type TriangleI = Triangle<i32>;
6
7/// A triangle, represented by 3 points.
8#[repr(transparent)]
9#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
10pub struct Triangle<T>(pub [Vec2<T>; 3]);
11
12impl_bytemuck!(Triangle);
13
14impl_interp!(
15    NAME = Triangle
16    INDICES = [0, 1, 2]
17);
18
19impl_casts!(
20    NAME = Triangle
21    FIELDS = (0)
22);
23
24impl_approx!(
25    NAME = Triangle
26    FIELDS = (0)
27);
28
29/// Create a [`Triangle`].
30#[inline]
31pub const fn triangle<T>(a: Vec2<T>, b: Vec2<T>, c: Vec2<T>) -> Triangle<T> {
32    Triangle([a, b, c])
33}
34
35impl<T> Triangle<T> {
36    /// Create a new triangle.
37    #[inline]
38    pub const fn new(a: Vec2<T>, b: Vec2<T>, c: Vec2<T>) -> Self {
39        Self([a, b, c])
40    }
41
42    #[inline]
43    pub fn map<U>(self, f: impl Fn(Vec2<T>) -> Vec2<U>) -> Triangle<U> {
44        Triangle(self.0.map(f))
45    }
46}
47
48impl<T: Copy> Triangle<T> {
49    /// First point of the triangle.
50    #[inline]
51    pub const fn a(&self) -> Vec2<T> {
52        self.0[0]
53    }
54
55    /// Second point of the triangle
56    #[inline]
57    pub const fn b(&self) -> Vec2<T> {
58        self.0[1]
59    }
60
61    /// Third point of the triangle.
62    #[inline]
63    pub const fn c(&self) -> Vec2<T> {
64        self.0[2]
65    }
66
67    /// The triangle's 3 edges.
68    #[inline]
69    pub fn edges(&self) -> [Line<T>; 3] {
70        [self.edge_ab(), self.edge_bc(), self.edge_ca()]
71    }
72
73    /// The triangle's a -> b edge.
74    #[inline]
75    pub const fn edge_ab(&self) -> Line<T> {
76        line(self.a(), self.b())
77    }
78
79    /// The triangle's b -> c edge.
80    #[inline]
81    pub const fn edge_bc(&self) -> Line<T> {
82        line(self.b(), self.c())
83    }
84
85    /// The triangle's c -> a edge.
86    #[inline]
87    pub const fn edge_ca(&self) -> Line<T> {
88        line(self.c(), self.a())
89    }
90}
91
92impl<T: Num> Triangle<T> {
93    /// A triangle with all points set to `(0, 0)`.
94    pub const ZERO: Self = Self([Vec2::ZERO; 3]);
95
96    /// The vector a -> b of the triangle.
97    #[inline]
98    pub fn ab(&self) -> Vec2<T> {
99        self.b() - self.a()
100    }
101
102    /// The vector b -> c of the triangle.
103    #[inline]
104    pub fn bc(&self) -> Vec2<T> {
105        self.c() - self.b()
106    }
107
108    /// The vector c -> a of the triangle.
109    #[inline]
110    pub fn ca(&self) -> Vec2<T> {
111        self.a() - self.c()
112    }
113}
114
115impl<T: Float> Triangle<T> {
116    /// Return the outward-facing normal of edge a -> b.
117    #[inline]
118    pub fn norm_ab(&self) -> Vec2<T> {
119        self.ab().turn_left().norm()
120    }
121
122    /// Return the outward-facing normal of edge b -> c.
123    #[inline]
124    pub fn norm_bc(&self) -> Vec2<T> {
125        self.bc().turn_left().norm()
126    }
127
128    /// Return the outward-facing normal of edge c -> a.
129    #[inline]
130    pub fn norm_ca(&self) -> Vec2<T> {
131        self.ca().turn_left().norm()
132    }
133
134    #[inline]
135    pub fn transform_by(&self, f: impl FnMut(Vec2<T>) -> Vec2<T>) -> Self {
136        Self(self.0.map(f))
137    }
138}
139
140impl<T> AsRef<[Vec2<T>]> for Triangle<T> {
141    #[inline]
142    fn as_ref(&self) -> &[Vec2<T>] {
143        self.0.as_slice()
144    }
145}
146
147impl<T> From<(Vec2<T>, Vec2<T>, Vec2<T>)> for Triangle<T> {
148    #[inline]
149    fn from((a, b, c): (Vec2<T>, Vec2<T>, Vec2<T>)) -> Self {
150        Self([a, b, c])
151    }
152}
153
154impl<T> From<Triangle<T>> for (Vec2<T>, Vec2<T>, Vec2<T>) {
155    #[inline]
156    fn from(Triangle([a, b, c]): Triangle<T>) -> Self {
157        (a, b, c)
158    }
159}
160
161impl<T> From<[Vec2<T>; 3]> for Triangle<T> {
162    #[inline]
163    fn from(value: [Vec2<T>; 3]) -> Self {
164        Self(value)
165    }
166}
167
168impl<T> From<Triangle<T>> for [Vec2<T>; 3] {
169    #[inline]
170    fn from(value: Triangle<T>) -> Self {
171        value.0
172    }
173}
174