1use crate::core::{ColChar, Modifier};
4use std::f64::consts::TAU;
5
6use super::{Face, Mesh3D, Transform3D, Vec3D};
7
8impl Mesh3D {
9 #[must_use]
11 pub fn default_cube() -> Self {
12 Self::new(
13 vec![
14 Vec3D::new(1.0, 1.0, -1.0),
15 Vec3D::new(1.0, 1.0, 1.0),
16 Vec3D::new(1.0, -1.0, -1.0),
17 Vec3D::new(1.0, -1.0, 1.0),
18 Vec3D::new(-1.0, 1.0, -1.0),
19 Vec3D::new(-1.0, 1.0, 1.0),
20 Vec3D::new(-1.0, -1.0, -1.0),
21 Vec3D::new(-1.0, -1.0, 1.0),
22 ],
23 vec![
24 Face::new(vec![2, 3, 1, 0], ColChar::SOLID.with_mod(Modifier::BLUE)),
25 Face::new(vec![4, 5, 7, 6], ColChar::SOLID.with_mod(Modifier::BLUE)),
26 Face::new(vec![1, 3, 7, 5], ColChar::SOLID.with_mod(Modifier::None)),
27 Face::new(vec![4, 6, 2, 0], ColChar::SOLID.with_mod(Modifier::None)),
28 Face::new(vec![6, 7, 3, 2], ColChar::SOLID.with_mod(Modifier::RED)),
29 Face::new(vec![0, 1, 5, 4], ColChar::SOLID.with_mod(Modifier::RED)),
30 ],
31 )
32 }
33
34 #[must_use]
36 pub fn torus(
37 outer_radius: f64,
38 inner_radius: f64,
39 outer_segments: usize,
40 inner_segments: usize,
41 ) -> Self {
42 let mut vertices = vec![];
43 let mut faces = vec![];
44
45 for outer_i in 0..outer_segments {
46 let outer_angle = (outer_i as f64 / outer_segments as f64) * TAU;
47 let outer_transform = Transform3D::from_rotation_y(-outer_angle);
48 let outer_point = Vec3D::new(
49 outer_angle.cos() * outer_radius,
50 0.0,
51 outer_angle.sin() * outer_radius,
52 );
53
54 for inner_i in 0..inner_segments {
55 let inner_angle = (inner_i as f64 / inner_segments as f64) * TAU;
56 let inner_point = Vec3D::new(
57 inner_angle.cos() * inner_radius,
58 inner_angle.sin() * inner_radius,
59 0.0,
60 );
61 vertices.push(outer_point + outer_transform.transform_vector3(inner_point));
62
63 let inc_outer_i = (outer_i + 1) % outer_segments;
64 let inc_inner_i = (inner_i + 1) % inner_segments;
65 faces.push(Face::new(
66 vec![
67 inc_outer_i * inner_segments + inner_i,
68 inc_outer_i * inner_segments + inc_inner_i,
69 outer_i * inner_segments + inc_inner_i,
70 outer_i * inner_segments + inner_i,
71 ],
72 ColChar::SOLID,
73 ));
74 }
75 }
76
77 Self::new(vertices, faces)
78 }
79
80 #[must_use]
88 pub fn gimbal() -> Self {
89 Self::new(
90 vec![
91 Vec3D::ZERO,
92 Vec3D::new(1.0, 0.0, 0.0),
93 Vec3D::new(0.0, 1.0, 0.0),
94 Vec3D::new(0.0, 0.0, 1.0),
95 ],
96 vec![
97 Face::new(vec![0, 1], ColChar::SOLID.with_mod(Modifier::RED)),
98 Face::new(vec![0, 2], ColChar::SOLID.with_mod(Modifier::GREEN)),
99 Face::new(vec![0, 3], ColChar::SOLID.with_mod(Modifier::BLUE)),
100 ],
101 )
102 }
103}