You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
1.9 KiB
77 lines
1.9 KiB
3 months ago
|
/// Iterator providing points for 1/8th of a circle (single octant)
|
||
|
///
|
||
|
/// The iterator supplies coordinates of pixels relative to the
|
||
|
/// circle's center point, along with an alpha value in
|
||
|
/// the range (0..255), indicating the proportion of the pixel
|
||
|
/// that lies inside the circle.
|
||
|
///
|
||
|
/// for p in circle_points(radius) {
|
||
|
/// println!("{}, {}", p.u, p.v); // coordinates <0,radius>..<see_below>
|
||
|
/// println!("{}", p.frac); // distance from the circle <0..255>
|
||
|
/// println!("{}", p.first); // `v` has changed
|
||
|
/// println!("{}", p.last); // next `v` will change
|
||
|
/// }
|
||
|
///
|
||
|
/// `u` axis is the main and increments at each iteration.
|
||
|
///
|
||
|
/// endpoint [t, t] or [t - 1, t] where t = radius * (1 / sqrt(2))
|
||
|
|
||
|
pub fn circle_points(radius: i16) -> CirclePoints {
|
||
|
CirclePoints {
|
||
|
radius,
|
||
|
u: 0,
|
||
|
v: radius,
|
||
|
t1: radius / 16,
|
||
|
first: true,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub struct CirclePoints {
|
||
|
radius: i16,
|
||
|
u: i16,
|
||
|
v: i16,
|
||
|
t1: i16,
|
||
|
first: bool,
|
||
|
}
|
||
|
|
||
|
#[derive(Copy, Clone)]
|
||
|
pub struct CirclePointsItem {
|
||
|
pub u: i16,
|
||
|
pub v: i16,
|
||
|
pub frac: u8,
|
||
|
pub first: bool,
|
||
|
pub last: bool,
|
||
|
}
|
||
|
|
||
|
impl Iterator for CirclePoints {
|
||
|
type Item = CirclePointsItem;
|
||
|
|
||
|
fn next(&mut self) -> Option<Self::Item> {
|
||
|
if self.v >= self.u {
|
||
|
let mut item = CirclePointsItem {
|
||
|
u: self.u,
|
||
|
v: self.v,
|
||
|
frac: 255 - ((self.t1 as i32 * 255) / self.radius as i32) as u8,
|
||
|
first: self.first,
|
||
|
last: false,
|
||
|
};
|
||
|
|
||
|
self.first = false;
|
||
|
self.u += 1;
|
||
|
self.t1 += self.u;
|
||
|
let t2 = self.t1 - self.v;
|
||
|
if t2 >= 0 {
|
||
|
self.t1 = t2;
|
||
|
self.v -= 1;
|
||
|
self.first = true;
|
||
|
}
|
||
|
|
||
|
item.last = item.v != self.v;
|
||
|
|
||
|
Some(item)
|
||
|
} else {
|
||
|
None
|
||
|
}
|
||
|
}
|
||
|
}
|