graphics_rs/shapes/
point_cloud.rs

1use 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.draw_shape(&mut Rect::new(
78                //     x + half_size,
79                //     y + half_size,
80                //     self.size,
81                //     self.size,
82                // ));
83
84                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}