use crate::{
geometry::{Point, PointExt},
primitives::{
rectangle::{self, Rectangle},
PointsIter,
},
};
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
pub struct DistanceIterator {
center_2x: Point,
points: rectangle::Points,
}
impl DistanceIterator {
pub fn new(center_2x: Point, bounding_box: &Rectangle) -> Self {
Self {
center_2x,
points: bounding_box.points(),
}
}
pub const fn empty() -> Self {
Self {
center_2x: Point::zero(),
points: rectangle::Points::empty(),
}
}
}
impl Iterator for DistanceIterator {
type Item = (Point, Point, u32);
fn next(&mut self) -> Option<Self::Item> {
self.points.next().map(|point| {
let delta = point * 2 - self.center_2x;
let distance = delta.length_squared() as u32;
(point, delta, distance)
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{geometry::Dimensions, primitives::Circle};
#[test]
fn distance_iter() {
let circle = Circle::new(Point::zero(), 3);
let mut iter = DistanceIterator::new(circle.center_2x(), &circle.bounding_box());
assert_eq!(iter.next(), Some((Point::new(0, 0), Point::new(-2, -2), 8)));
assert_eq!(iter.next(), Some((Point::new(1, 0), Point::new(0, -2), 4)));
assert_eq!(iter.next(), Some((Point::new(2, 0), Point::new(2, -2), 8)));
assert_eq!(iter.next(), Some((Point::new(0, 1), Point::new(-2, 0), 4)));
assert_eq!(iter.next(), Some((Point::new(1, 1), Point::new(0, 0), 0)));
assert_eq!(iter.next(), Some((Point::new(2, 1), Point::new(2, 0), 4)));
assert_eq!(iter.next(), Some((Point::new(0, 2), Point::new(-2, 2), 8)));
assert_eq!(iter.next(), Some((Point::new(1, 2), Point::new(0, 2), 4)));
assert_eq!(iter.next(), Some((Point::new(2, 2), Point::new(2, 2), 8)));
assert_eq!(iter.next(), None);
}
#[test]
fn distance_iter_empty() {
let mut iter = DistanceIterator::empty();
assert_eq!(iter.next(), None);
}
}