pico_detect/geometry/
square.rs

1use imageproc::rect::Rect;
2
3use crate::traits::region::Region;
4
5/// Represents a square region in an image with a left, top coordinates and size.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub struct Square {
8    pub(crate) left: i32,
9    pub(crate) top: i32,
10    pub(crate) size: u32,
11}
12
13impl Square {
14    /// Creates a square at the specified coordinates with unit size.
15    #[inline]
16    pub fn at(x: i32, y: i32) -> Self {
17        Self {
18            left: x,
19            top: y,
20            size: 1,
21        }
22    }
23
24    /// Sets the size of the square.
25    #[inline]
26    pub fn of_size(mut self, value: u32) -> Self {
27        self.size = value;
28        self
29    }
30
31    /// Creates a square from a region if it is square.
32    #[inline]
33    pub fn from_region<T: Region>(value: T) -> Option<Self> {
34        value.is_square().then(|| Self {
35            left: value.left(),
36            top: value.top(),
37            size: value.width(),
38        })
39    }
40
41    /// Creates a new square with the specified left, top coordinates and size.
42    #[inline]
43    pub fn new(left: i32, top: i32, size: u32) -> Self {
44        Self { left, top, size }
45    }
46
47    /// Returns the size of the square.
48    #[inline]
49    pub fn size(&self) -> u32 {
50        self.size
51    }
52}
53
54impl Region for Square {
55    #[inline]
56    fn left(&self) -> i32 {
57        self.left
58    }
59
60    #[inline]
61    fn top(&self) -> i32 {
62        self.top
63    }
64
65    #[inline]
66    fn width(&self) -> u32 {
67        self.size
68    }
69
70    #[inline]
71    fn height(&self) -> u32 {
72        self.size
73    }
74
75    #[inline]
76    fn is_square(&self) -> bool {
77        true
78    }
79}
80
81impl From<(i32, i32, u32)> for Square {
82    fn from(value: (i32, i32, u32)) -> Self {
83        Self::new(value.0, value.1, value.2)
84    }
85}
86
87impl From<Square> for Rect {
88    fn from(value: Square) -> Self {
89        Self::at(value.left, value.top).of_size(value.size, value.size)
90    }
91}