cube_core/utils/
geometry.rs1#[derive(Debug, Clone, Copy)]
2pub struct Point2D {
3 pub x: isize,
4 pub y: isize,
5}
6
7#[derive(Debug, Clone, Copy)]
8pub struct Point3D {
9 pub x: f32,
10 pub y: f32,
11 pub z: f32,
12}
13
14impl Point3D {
15 pub fn add(&self, other: &Point3D) -> Point3D {
16 Point3D {
17 x: self.x + other.x,
18 y: self.y + other.y,
19 z: self.z + other.z,
20 }
21 }
22
23 pub fn subtract(&self, other: &Point3D) -> Point3D {
24 Point3D {
25 x: self.x - other.x,
26 y: self.y - other.y,
27 z: self.z - other.z,
28 }
29 }
30
31 pub fn scalar_multiply(&self, scalar: f32) -> Point3D {
32 Point3D {
33 x: scalar * self.x,
34 y: scalar * self.y,
35 z: scalar * self.z,
36 }
37 }
38
39 pub fn rotate_around_axis(&self, axis: Point3D, origin: Point3D, angle_rad: f32) -> Point3D {
40 let axis = axis.normalize();
41 let v = self.subtract(&origin);
42 let cos = angle_rad.cos();
43 let sin = angle_rad.sin();
44
45 let dot = v.dot(&axis);
46 let cross = v.cross(&axis);
47
48 let rotated = v.scalar_multiply(cos)
49 .add(&cross.scalar_multiply(sin))
50 .add(&axis.scalar_multiply(dot * (1.0 - cos)));
51
52 rotated.add(&origin)
53 }
54
55 pub fn rotate_y(self, angle: f32) -> Self {
56 let (sin, cos) = (angle.sin(), angle.cos());
57 Self {
58 x: self.x * cos + self.z * sin,
59 y: self.y,
60 z: -self.x * sin + self.z * cos,
61 }
62 }
63
64 pub fn rotate_x(self, angle: f32) -> Self {
65 let (sin, cos) = (angle.sin(), angle.cos());
66 Self {
67 x: self.x,
68 y: self.y * cos - self.z * sin,
69 z: self.y * sin + self.z * cos,
70 }
71 }
72
73 pub fn rotate_z(self, angle: f32) -> Self {
74 let (sin, cos) = (angle.sin(), angle.cos());
75 Self {
76 x: self.x * cos - self.y * sin,
77 y: self.x * sin + self.y * cos,
78 z: self.z,
79 }
80 }
81
82 pub fn translate(self, offset: Point3D) -> Self {
83 Self {
84 x: self.x + offset.x,
85 y: self.y + offset.y,
86 z: self.z + offset.z,
87 }
88 }
89
90 pub fn dot(&self, other: &Point3D) -> f32 {
91 self.x * other.x + self.y * other.y + self.z * other.z
92 }
93
94 pub fn cross(&self, other: &Point3D) -> Point3D {
95 Point3D {
96 x: self.y * other.z - self.z * other.y,
97 y: self.z * other.x - self.x * other.z,
98 z: self.x * other.y - self.y * other.x,
99 }
100 }
101
102 pub fn normalize(&self) -> Point3D {
103 let len = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
104 Point3D {
105 x: self.x / len,
106 y: self.y / len,
107 z: self.z / len,
108 }
109 }
110}
111
112pub struct Triangle (
113 pub Point2D,
114 pub Point2D,
115 pub Point2D,
116);
117
118impl Triangle {
119 pub fn point_in_triangle(&self, p: Point2D) -> bool {
120 let Self(a, b, c) = self;
121 let area = |p1: &Point2D, p2: &Point2D, p3: &Point2D| -> isize {
122 (p1.x * (p2.y - p3.y) +
123 p2.x * (p3.y - p1.y) +
124 p3.x * (p1.y - p2.y)).abs()
125 };
126
127 let total = area(a, b, c);
128 let a1 = area(&p, b, c);
129 let a2 = area(a, &p, c);
130 let a3 = area(a, b, &p);
131
132 a1 + a2 + a3 <= total + 1
133 }
134}