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
use {Point, SignedNum};
pub struct BresenhamCircle<T> {
x: T,
y: T,
center_x: T,
center_y: T,
radius: T,
error: T,
quadrant: u8,
}
impl<T: SignedNum> BresenhamCircle<T> {
#[inline]
pub fn new(center_x: T, center_y: T, radius: T) -> Self {
Self {
center_x,
center_y,
radius,
x: -radius,
y: T::zero(),
error: T::cast(2) - T::cast(2) * radius,
quadrant: 1,
}
}
}
impl<T: SignedNum> Iterator for BresenhamCircle<T> {
type Item = Point<T>;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
if self.x < T::zero() {
let point = match self.quadrant {
1 => (self.center_x - self.x, self.center_y + self.y),
2 => (self.center_x - self.y, self.center_y - self.x),
3 => (self.center_x + self.x, self.center_y - self.y),
4 => (self.center_x + self.y, self.center_y + self.x),
_ => unreachable!(),
};
if self.quadrant == 4 {
self.radius = self.error;
if self.radius <= self.y {
self.y += T::one();
self.error += self.y * T::cast(2) + T::one();
}
if self.radius > self.x || self.error > self.y {
self.x += T::one();
self.error += self.x * T::cast(2) + T::one();
}
}
self.quadrant = self.quadrant % 4 + 1;
Some(point)
} else {
None
}
}
}