cube_core/utils/
geometry.rs

1#[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}