graphics_rs/shapes/
triangle.rs

1use crate::{
2    math::num_utils::NumUtils,
3    traits::{canvas::Canvas, shape::Shape},
4};
5
6pub struct Triangle {
7    x1: usize,
8    y1: usize,
9    x2: usize,
10    y2: usize,
11    x3: usize,
12    y3: usize,
13}
14
15impl Triangle {
16    pub fn new(x1: usize, y1: usize, x2: usize, y2: usize, x3: usize, y3: usize) -> Self {
17        Self {
18            x1,
19            x2,
20            y1,
21            y2,
22            x3,
23            y3,
24        }
25    }
26}
27
28impl Shape for Triangle {
29    fn draw_to(&mut self, canvas: &mut impl Canvas) {
30        let (mut x1, mut y1, mut x2, mut y2, mut x3, mut y3) = (
31            self.x1 as f64,
32            self.y1 as f64,
33            self.x2 as f64,
34            self.y2 as f64,
35            self.x3 as f64,
36            self.y3 as f64,
37        );
38
39        NumUtils::order_triangle_vertices_by_y(
40            &mut x1, &mut y1, &mut x2, &mut y2, &mut x3, &mut y3,
41        );
42
43        let dx12 = x2 - x1;
44        let dy12 = y2 - y1;
45        let dx13 = x3 - x1;
46        let dy13 = y3 - y1;
47
48        for row in y1 as i64..=y2 as i64 {
49            if row >= 0 && row < canvas.height() as i64 {
50                let mut s1 = if dy12 != 0f64 {
51                    (row as f64 - y1) * dx12 / dy12 + x1
52                } else {
53                    x1
54                };
55                let mut s2 = if dy13 != 0f64 {
56                    (row as f64 - y1) * dx13 / dy13 + x1
57                } else {
58                    x1
59                };
60                if s1 > s2 {
61                    std::mem::swap(&mut s1, &mut s2)
62                }
63                for col in s1 as i64..=s2 as i64 {
64                    if col >= 0 && col < canvas.width() as i64 {
65                        canvas.set_pixel(row as usize, col as usize);
66                    }
67                }
68            }
69        }
70
71        let dx32 = x2 - x3;
72        let dy32 = y2 - y3;
73        let dx31 = x1 - x3;
74        let dy31 = y1 - y3;
75
76        for row in y2 as i64..=y3 as i64 {
77            if row >= 0 && row < canvas.height() as i64 {
78                let mut s1 = if dy32 != 0f64 {
79                    (row as f64 - y3) * dx32 / dy32 + x3
80                } else {
81                    x3
82                };
83                let mut s2 = if dy31 != 0f64 {
84                    (row as f64 - y3) * dx31 / dy31 + x3
85                } else {
86                    x3
87                };
88                if s1 > s2 {
89                    std::mem::swap(&mut s1, &mut s2)
90                }
91                for col in s1 as i64..=s2 as i64 {
92                    if col >= 0 && col < canvas.width() as i64 {
93                        canvas.set_pixel(row as usize, col as usize);
94                    }
95                }
96            }
97        }
98    }
99}