1use crate::geom::{tri, vertex, Cuboid, Range, Rect, Tri, Vertex, Vertex2d, Vertex3d};
2use core::ops::{Deref, Index};
3
4pub const NUM_VERTICES: u8 = 4;
6
7pub const NUM_TRIANGLES: u8 = 2;
9
10pub const TRIANGLE_INDEX_TRIS: TrianglesIndexTris = [[0, 1, 2], [0, 2, 3]];
12pub type TrianglesIndexTris = [[usize; tri::NUM_VERTICES as usize]; NUM_TRIANGLES as usize];
13
14pub const NUM_TRIANGLE_INDICES: u8 = 6;
16
17pub const TRIANGLE_INDICES: [usize; NUM_TRIANGLE_INDICES as usize] = [0, 1, 2, 0, 2, 3];
19
20#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
22pub struct Quad<V = vertex::Default>(pub [V; NUM_VERTICES as usize]);
23
24#[derive(Clone, Debug)]
26pub struct Triangles<V = vertex::Default> {
27 a: Option<Tri<V>>,
28 b: Option<Tri<V>>,
29}
30
31#[derive(Clone, Debug)]
33pub struct Vertices<V = vertex::Default> {
34 quad: Quad<V>,
35 index: u8,
36}
37
38impl<V> Quad<V>
39where
40 V: Vertex,
41{
42 pub fn vertices(self) -> Vertices<V> {
44 vertices(self)
45 }
46
47 pub fn centroid(&self) -> V
49 where
50 V: vertex::Average,
51 {
52 centroid(self)
53 }
54
55 #[inline]
102 pub fn triangles(&self) -> (Tri<V>, Tri<V>) {
103 triangles(self)
104 }
105
106 pub fn triangles_iter(&self) -> Triangles<V> {
108 triangles_iter(self)
109 }
110
111 pub fn bounding_rect(self) -> Rect<V::Scalar>
113 where
114 V: Vertex2d,
115 {
116 let (a, b, c, d) = self.into();
117 let ([ax, ay], b, c, d) = (a.point2(), b.point2(), c.point2(), d.point2());
118 let rect = Rect {
119 x: Range::new(ax, ax),
120 y: Range::new(ay, ay),
121 };
122 rect.stretch_to_point(b)
123 .stretch_to_point(c)
124 .stretch_to_point(d)
125 }
126
127 pub fn bounding_cuboid(self) -> Cuboid<V::Scalar>
129 where
130 V: Vertex3d,
131 {
132 let (a, b, c, d) = self.into();
133 let ([ax, ay, az], b, c, d) = (a.point3(), b.point3(), c.point3(), d.point3());
134 let cuboid = Cuboid {
135 x: Range::new(ax, ax),
136 y: Range::new(ay, ay),
137 z: Range::new(az, az),
138 };
139 cuboid
140 .stretch_to_point(b)
141 .stretch_to_point(c)
142 .stretch_to_point(d)
143 }
144
145 pub fn map_vertices<F, V2>(self, mut map: F) -> Quad<V2>
147 where
148 F: FnMut(V) -> V2,
149 {
150 let (a, b, c, d) = self.into();
151 Quad([map(a), map(b), map(c), map(d)])
152 }
153}
154
155pub fn vertices<V>(quad: Quad<V>) -> Vertices<V> {
157 let index = 0;
158 Vertices { quad, index }
159}
160
161pub fn centroid<V>(quad: &Quad<V>) -> V
163where
164 V: vertex::Average,
165{
166 crate::geom::centroid(quad.iter().cloned()).unwrap()
167}
168
169#[inline]
217pub fn triangles<V>(q: &Quad<V>) -> (Tri<V>, Tri<V>)
218where
219 V: Vertex,
220{
221 let a = Tri::from_index_tri(&q.0, &TRIANGLE_INDEX_TRIS[0]);
222 let b = Tri::from_index_tri(&q.0, &TRIANGLE_INDEX_TRIS[1]);
223 (a, b)
224}
225
226pub fn triangles_iter<V>(points: &Quad<V>) -> Triangles<V>
228where
229 V: Vertex,
230{
231 let (a, b) = triangles(points);
232 Triangles {
233 a: Some(a),
234 b: Some(b),
235 }
236}
237
238impl<V> Iterator for Triangles<V> {
239 type Item = Tri<V>;
240 fn next(&mut self) -> Option<Self::Item> {
241 self.a.take().or_else(|| self.b.take())
242 }
243 fn size_hint(&self) -> (usize, Option<usize>) {
244 let len = self.len();
245 (len, Some(len))
246 }
247}
248
249impl<V> DoubleEndedIterator for Triangles<V> {
250 fn next_back(&mut self) -> Option<Self::Item> {
251 self.b.take().or_else(|| self.a.take())
252 }
253}
254
255impl<V> ExactSizeIterator for Triangles<V> {
256 fn len(&self) -> usize {
257 match (&self.a, &self.b) {
258 (&Some(_), &Some(_)) => 2,
259 (&None, &Some(_)) => 0,
260 _ => 1,
261 }
262 }
263}
264
265impl<V> Iterator for Vertices<V>
266where
267 V: Clone,
268{
269 type Item = V;
270 fn next(&mut self) -> Option<Self::Item> {
271 if self.index < NUM_VERTICES {
272 let v = self.quad[self.index as usize].clone();
273 self.index += 1;
274 Some(v)
275 } else {
276 None
277 }
278 }
279
280 fn size_hint(&self) -> (usize, Option<usize>) {
281 let len = self.len();
282 (len, Some(len))
283 }
284}
285
286impl<V> ExactSizeIterator for Vertices<V>
287where
288 V: Clone,
289{
290 fn len(&self) -> usize {
291 NUM_VERTICES as usize - self.index as usize
292 }
293}
294
295impl<V> Deref for Quad<V> {
296 type Target = [V; NUM_VERTICES as usize];
297 fn deref(&self) -> &Self::Target {
298 &self.0
299 }
300}
301
302impl<V> From<[V; NUM_VERTICES as usize]> for Quad<V>
303where
304 V: Vertex,
305{
306 fn from(points: [V; NUM_VERTICES as usize]) -> Self {
307 Quad(points)
308 }
309}
310
311impl<V> From<(V, V, V, V)> for Quad<V>
312where
313 V: Vertex,
314{
315 fn from((a, b, c, d): (V, V, V, V)) -> Self {
316 Quad([a, b, c, d])
317 }
318}
319
320impl<V> Into<[V; NUM_VERTICES as usize]> for Quad<V>
321where
322 V: Vertex,
323{
324 fn into(self) -> [V; NUM_VERTICES as usize] {
325 self.0
326 }
327}
328
329impl<V> Into<(V, V, V, V)> for Quad<V>
330where
331 V: Vertex,
332{
333 fn into(self) -> (V, V, V, V) {
334 (self[0], self[1], self[2], self[3])
335 }
336}
337
338impl<V> AsRef<Quad<V>> for Quad<V>
339where
340 V: Vertex,
341{
342 fn as_ref(&self) -> &Quad<V> {
343 self
344 }
345}
346
347impl<V> AsRef<[V; NUM_VERTICES as usize]> for Quad<V>
348where
349 V: Vertex,
350{
351 fn as_ref(&self) -> &[V; NUM_VERTICES as usize] {
352 &self.0
353 }
354}
355
356impl<V> Index<usize> for Quad<V>
357where
358 V: Vertex,
359{
360 type Output = V;
361 fn index(&self, index: usize) -> &Self::Output {
362 &self.0[index]
363 }
364}