embedded_graphics/primitives/arc/
points.rs

1use crate::{
2    geometry::Point,
3    primitives::{
4        arc::Arc,
5        common::{DistanceIterator, PlaneSector},
6        OffsetOutline,
7    },
8};
9
10/// Iterator over all points on the arc line.
11#[derive(Clone, PartialEq, Debug)]
12#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
13pub struct Points {
14    iter: DistanceIterator,
15
16    plane_sector: PlaneSector,
17
18    outer_threshold: u32,
19    inner_threshold: u32,
20}
21
22impl Points {
23    pub(in crate::primitives) fn new(arc: &Arc) -> Self {
24        let outer_circle = arc.to_circle();
25        let inner_circle = outer_circle.offset(-1);
26
27        let plane_sector = PlaneSector::new(arc.angle_start, arc.angle_sweep);
28
29        Self {
30            // PERF: The distance iterator should use the smaller arc bounding box
31            iter: outer_circle.distances(),
32            plane_sector,
33            outer_threshold: outer_circle.threshold(),
34            inner_threshold: inner_circle.threshold(),
35        }
36    }
37}
38
39impl Iterator for Points {
40    type Item = Point;
41
42    fn next(&mut self) -> Option<Self::Item> {
43        self.iter
44            .find(|(_, delta, distance)| {
45                *distance < self.outer_threshold
46                    && *distance >= self.inner_threshold
47                    && self.plane_sector.contains(*delta)
48            })
49            .map(|(point, ..)| point)
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56    use crate::{
57        geometry::AngleUnit,
58        pixelcolor::BinaryColor,
59        primitives::{PointsIter, Primitive, PrimitiveStyle},
60        Pixel,
61    };
62
63    #[test]
64    fn points_equals_filled() {
65        let arc = Arc::with_center(Point::new(10, 10), 5, 0.0.deg(), 90.0.deg());
66
67        let styled_points = arc
68            .clone()
69            .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
70            .pixels()
71            .map(|Pixel(p, _)| p);
72
73        assert!(arc.points().eq(styled_points));
74    }
75}