forked from louis-e/arnis
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbresenham.rs
More file actions
91 lines (80 loc) · 2.21 KB
/
bresenham.rs
File metadata and controls
91 lines (80 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/// Generates the coordinates for a line between two points using the Bresenham algorithm.
/// The result is a vector of 3D coordinates (x, y, z).
pub fn bresenham_line(
x1: i32,
y1: i32,
z1: i32,
x2: i32,
y2: i32,
z2: i32,
) -> Vec<(i32, i32, i32)> {
// Calculate max possible points needed
let dx = if x2 > x1 { x2 - x1 } else { x1 - x2 };
let dy = if y2 > y1 { y2 - y1 } else { y1 - y2 };
let dz = if z2 > z1 { z2 - z1 } else { z1 - z2 };
// Pre-allocate vector with exact size needed
let capacity = dx.max(dy).max(dz) + 1;
let mut points = Vec::with_capacity(capacity as usize);
points.reserve_exact(capacity as usize);
let xs = if x1 < x2 { 1 } else { -1 };
let ys = if y1 < y2 { 1 } else { -1 };
let zs = if z1 < z2 { 1 } else { -1 };
let mut x = x1;
let mut y = y1;
let mut z = z1;
// Determine dominant axis once, outside the loop
if dx >= dy && dx >= dz {
let mut p1 = 2 * dy - dx;
let mut p2 = 2 * dz - dx;
while x != x2 {
points.push((x, y, z));
if p1 >= 0 {
y += ys;
p1 -= 2 * dx;
}
if p2 >= 0 {
z += zs;
p2 -= 2 * dx;
}
p1 += 2 * dy;
p2 += 2 * dz;
x += xs;
}
} else if dy >= dx && dy >= dz {
let mut p1 = 2 * dx - dy;
let mut p2 = 2 * dz - dy;
while y != y2 {
points.push((x, y, z));
if p1 >= 0 {
x += xs;
p1 -= 2 * dy;
}
if p2 >= 0 {
z += zs;
p2 -= 2 * dy;
}
p1 += 2 * dx;
p2 += 2 * dz;
y += ys;
}
} else {
let mut p1 = 2 * dy - dz;
let mut p2 = 2 * dx - dz;
while z != z2 {
points.push((x, y, z));
if p1 >= 0 {
y += ys;
p1 -= 2 * dz;
}
if p2 >= 0 {
x += xs;
p2 -= 2 * dz;
}
p1 += 2 * dy;
p2 += 2 * dx;
z += zs;
}
}
points.push((x2, y2, z2));
points
}