bracket_geometry/
line_vector.rs

1use crate::prelude::Point;
2use core::iter::Iterator;
3use ultraviolet::Vec2;
4
5/// Define a line using a fast 2D vector. It may not be as pixel-perfect as Bresenham, but with vectorization it is sometimes
6/// faster for a quick line solution.
7pub struct VectorLine {
8    end: Point,
9    current_pos: Vec2,
10    slope: Vec2,
11    finished: bool,
12    really_finished: bool,
13}
14
15impl VectorLine {
16    /// Define a vector line between two points.
17    pub fn new(start: Point, end: Point) -> Self {
18        let current_pos = Vec2::new(start.x as f32 + 0.5, start.y as f32 + 0.5);
19        let destination = Vec2::new(end.x as f32 + 0.5, end.y as f32 + 0.5);
20        let slope = (destination - current_pos).normalized();
21
22        VectorLine {
23            end,
24            current_pos,
25            slope,
26            finished: false,
27            really_finished: false,
28        }
29    }
30}
31
32impl Iterator for VectorLine {
33    type Item = Point;
34
35    fn next(&mut self) -> Option<Self::Item> {
36        if self.finished {
37            if !self.really_finished {
38                self.really_finished = true;
39                Some(Point::new(
40                    self.current_pos.x as i32,
41                    self.current_pos.y as i32,
42                ))
43            } else {
44                None
45            }
46        } else {
47            let current_point = Point::new(self.current_pos.x as i32, self.current_pos.y as i32);
48            self.current_pos += self.slope;
49            let new_point = Point::new(self.current_pos.x as i32, self.current_pos.y as i32);
50            if new_point == self.end {
51                self.finished = true;
52            }
53            Some(current_point)
54        }
55    }
56}