kepler_ra/techtron/graphic/line.rs
1// MIT License
2
3// Copyright (c) 2023 Techtron-Lab
4
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21// SOFTWARE.
22
23
24// Bresenham Line algorithm
25
26
27pub fn generate_line2d(x1: i32, y1: i32, x2: i32, y2: i32) -> Vec<[i32;2]> {
28 let dx = (x2 - x1).abs();
29 let sx = if x1 < x2 {1} else {-1};
30 let dy = -(y2 - y1).abs();
31 let sy = if y1 < y2 {1} else {-1};
32
33 let mut line_points = Vec::new();
34 let mut error = dx + dy;
35
36 let mut x = x1;
37 let mut y = y1;
38
39 loop {
40 line_points.push([x, y]);
41
42 if x == x2 && y == y2 {break;}
43 let e2 = 2 * error;
44 if e2 >= dy {
45 if x == x2 {break;}
46 error += dy;
47 x += sx;
48 }
49 if e2 <= dx {
50 if y == y2 {break;}
51 error += dx;
52 y += sy;
53 }
54 }
55 return line_points;
56}
57
58
59#[cfg(test)]
60mod test {
61 use super::*;
62 #[test]
63 fn test_bresenham_line() {
64 let line = generate_line2d(-2, -2, 2, 2);
65 println!("{:?}", line);
66
67 let line = generate_line2d(2, 2, -2, -2);
68 println!("{:?}", line);
69
70 let line = generate_line2d(-5, -2, 2, 10);
71 println!("{:?}", line);
72 }
73}