/// 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>.. /// 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 { 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 } } }