graphics_rs/shapes/
line.rs

1use crate::traits::{canvas::Canvas, shape::Shape};
2
3pub struct Line {
4    x1: usize,
5    y1: usize,
6    x2: usize,
7    y2: usize,
8}
9
10impl Line {
11    pub fn new(x1: usize, y1: usize, x2: usize, y2: usize) -> Self {
12        Self { x1, x2, y1, y2 }
13    }
14}
15
16impl Shape for Line {
17    fn draw_to(&mut self, canvas: &mut impl Canvas) {
18        let x1 = canvas.clamp_col(self.x1 as i64);
19        let x2 = canvas.clamp_col(self.x2 as i64);
20        let y1 = canvas.clamp_row(self.y1 as i64);
21        let y2 = canvas.clamp_row(self.y2 as i64);
22
23        let (x1, x2, y1, y2) = if x2 < x1 {
24            (x2, x2, y2, y1)
25        } else {
26            (x1, x2, y1, y2)
27        };
28
29        let dx = x2 - x1;
30        let dy = y2 - y1;
31
32        if dx == 0 {
33            for row in y1..y2 {
34                if canvas.fits_inside(row, x1) {
35                    canvas.set_pixel(row as usize, x1 as usize);
36                }
37            }
38        } else {
39            let slope = dy as f64 / dx as f64;
40
41            for col in x1..x2 {
42                let y = col as f64 * slope + y1 as f64;
43                let row = y as i64;
44
45                if canvas.fits_inside(row, col) {
46                    canvas.set_pixel(row as usize, col as usize);
47                }
48            }
49        }
50    }
51}