graphics_rs/shapes/
point_cloud.rs1use crate::{
2 math::{vec2::Vec2, vec3::Vec3},
3 tools::camera::Camera,
4 traits::{canvas::Canvas, project::Project, shape::Shape},
5};
6
7pub struct PointCloud {
8 points: Vec<Vec3<i64>>,
9 min: i64,
10 max: i64,
11 fov_factor: i64,
12 camera: Camera<i64>,
13 rotation: Vec3<f64>,
14 size: usize,
15}
16
17impl PointCloud {
18 pub fn new(
19 points: Vec<Vec3<i64>>,
20 min: i64,
21 max: i64,
22 fov_factor: i64,
23 camera: Camera<i64>,
24 rotation: Vec3<f64>,
25 size: usize,
26 ) -> Self {
27 Self {
28 points,
29 min,
30 max,
31 fov_factor,
32 camera,
33 rotation,
34 size,
35 }
36 }
37
38 pub fn project_points(&self) -> Vec<Vec2<i64>> {
39 let mut projected_points = Vec::<Vec2<i64>>::new();
40
41 for point in &self.points {
42 if let Some(point) = self.project(&point.rotate(&self.rotation)) {
43 projected_points.push(point);
44 }
45 }
46
47 projected_points
48 }
49
50 pub fn set_rotation(&mut self, rotation: Vec3<f64>) {
51 self.rotation = rotation
52 }
53
54 pub fn rotation(&mut self) -> &mut Vec3<f64> {
55 &mut self.rotation
56 }
57}
58
59impl Shape for PointCloud {
60 fn draw_to(&mut self, canvas: &mut impl Canvas) {
61 let projected_points = self.project_points();
62
63 for point in &projected_points {
64 let (x, y) = (point.x(), point.y());
65
66 let (x, y) = (
67 x + canvas.width() as i64 / 2,
68 y + canvas.height() as i64 / 2,
69 );
70
71 if x >= 0 && x <= canvas.width() as i64 && y >= 0 && y <= canvas.height() as i64 {
72 let x = x.clamp(usize::MIN as i64, i64::MAX);
73 let y = y.clamp(usize::MIN as i64, i64::MAX);
74 let (x, y) = (x as usize, y as usize);
75
76 let half_size = self.size / 2;
77 canvas.set_pixel(x + half_size, y + half_size);
85 }
86 }
87 }
88}
89
90impl Project<i64> for PointCloud {
91 fn project(&self, v3: &Vec3<i64>) -> Option<Vec2<i64>> {
92 let z = v3.z() - self.camera.position().z();
93 if z == 0 {
94 None
95 } else {
96 let x = v3.x() as f64 * self.fov_factor as f64 / z as f64;
97 let y = v3.y() as f64 * self.fov_factor as f64 / z as f64;
98
99 let (x, y) = (x as i64, y as i64);
100
101 Some(Vec2::new(x, y))
102 }
103 }
104}