embedded_graphics/primitives/triangle/
points.rs1use crate::{
2 geometry::{Dimensions, Point},
3 primitives::{
4 common::{Scanline, StrokeOffset},
5 triangle::{scanline_iterator::ScanlineIterator, Triangle},
6 },
7};
8
9#[derive(Clone, Eq, PartialEq, Hash, Debug)]
11#[cfg_attr(feature = "defmt", derive(::defmt::Format))]
12pub struct Points {
13 scanline_iter: ScanlineIterator,
14 current_line: Scanline,
15}
16
17impl Points {
18 pub(in crate::primitives) fn new(triangle: &Triangle) -> Self {
19 let scanline_iter = ScanlineIterator::new(
20 triangle,
21 0,
22 StrokeOffset::None,
23 true,
24 &triangle.bounding_box(),
25 );
26
27 let current_line = Scanline::new_empty(0);
28
29 Self {
30 scanline_iter,
31 current_line,
32 }
33 }
34}
35
36impl Iterator for Points {
37 type Item = Point;
38
39 fn next(&mut self) -> Option<Self::Item> {
40 self.current_line.next().or_else(|| {
41 self.current_line = self.scanline_iter.next()?.0;
42
43 self.current_line.next()
44 })
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51 use crate::{
52 pixelcolor::BinaryColor,
53 primitives::{PointsIter, Primitive, PrimitiveStyle},
54 transform::Transform,
55 Pixel,
56 };
57
58 #[test]
59 fn points_iter() {
60 let triangle = Triangle::new(Point::new(5, 10), Point::new(15, 20), Point::new(10, 15));
61
62 let styled_points = triangle
63 .clone()
64 .into_styled(PrimitiveStyle::with_fill(BinaryColor::On))
65 .pixels()
66 .map(|Pixel(p, _)| p);
67
68 assert!(triangle.points().eq(styled_points));
69 }
70
71 #[test]
72 fn off_screen_still_draws_points() {
73 let off_screen = Triangle::new(Point::new(10, 10), Point::new(20, 20), Point::new(30, -30));
74 let on_screen = off_screen.translate(Point::new(0, 35));
75
76 assert!(off_screen
77 .points()
78 .eq(on_screen.points().map(|p| p - Point::new(0, 35))));
79 }
80
81 #[test]
82 fn it_draws_unfilled_tri_line_y() {
83 let mut tri = Triangle::new(Point::new(2, 2), Point::new(2, 4), Point::new(2, 4)).points();
84
85 assert_eq!(tri.next(), Some(Point::new(2, 2)));
86 assert_eq!(tri.next(), Some(Point::new(2, 3)));
87 assert_eq!(tri.next(), Some(Point::new(2, 4)));
88 assert_eq!(tri.next(), None);
89 }
90
91 #[test]
92 fn it_draws_unfilled_tri_line_x() {
93 let mut tri = Triangle::new(Point::new(2, 2), Point::new(4, 2), Point::new(4, 2)).points();
94
95 assert_eq!(tri.next(), Some(Point::new(2, 2)));
96 assert_eq!(tri.next(), Some(Point::new(3, 2)));
97 assert_eq!(tri.next(), Some(Point::new(4, 2)));
98 assert_eq!(tri.next(), None);
99 }
100}