visioncortex/
transform.rs1use crate::{BoundingRect, PointI32};
2
3pub trait Transform {
5 fn transform(&self, vec: &PointI32) -> PointI32;
6 fn transform_rect(&self, rect: &BoundingRect) -> BoundingRect;
7}
8
9#[derive(Default)]
11pub struct RectangularTransform {
12 pub a: BoundingRect,
13 pub b: BoundingRect,
14}
15
16impl RectangularTransform {
17 pub fn new() -> Self {
18 Default::default()
19 }
20
21 pub fn new_rect_rect(a: BoundingRect, b: BoundingRect) -> Self {
22 Self {
23 a,
24 b,
25 }
26 }
27
28 pub fn new_point_point(a: PointI32, b: PointI32) -> Self {
29 Self {
30 a: BoundingRect::new_x_y_w_h(a.x, a.y, 1, 1),
31 b: BoundingRect::new_x_y_w_h(b.x, b.y, 1, 1),
32 }
33 }
34
35 pub fn new_point(b: &PointI32) -> Self {
36 Self {
37 a: BoundingRect::new_x_y_w_h(0, 0, 1, 1),
38 b: BoundingRect::new_x_y_w_h(b.x, b.y, 1, 1),
39 }
40 }
41}
42
43impl Transform for RectangularTransform {
44 fn transform(&self, p: &PointI32) -> PointI32 {
45 if self.a.is_empty() || self.b.is_empty() {
46 return *p;
47 }
48 PointI32 {
49 x: (p.x - self.a.left) * self.b.width() / self.a.width() + self.b.left,
50 y: (p.y - self.a.top) * self.b.height() / self.a.height() + self.b.top,
51 }
52 }
53
54 fn transform_rect(&self, r: &BoundingRect) -> BoundingRect {
55 let a = self.transform(&PointI32 {
56 x: r.left,
57 y: r.top,
58 });
59 let b = self.transform(&PointI32 {
60 x: r.right,
61 y: r.bottom,
62 });
63 BoundingRect {
64 left: a.x,
65 top: a.y,
66 right: b.x,
67 bottom: b.y,
68 }
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn rectangular_transform() {
78 assert_eq!(
79 RectangularTransform::new_rect_rect(
80 BoundingRect::new_x_y_w_h(1, 1, 2, 2),
81 BoundingRect::new_x_y_w_h(2, 2, 2, 2)
82 )
83 .transform(&PointI32 { x: 2, y: 2 }),
84 PointI32 { x: 3, y: 3 }
85 );
86
87 assert_eq!(
88 RectangularTransform::new_rect_rect(
89 BoundingRect::new_x_y_w_h(1, 1, 2, 2),
90 BoundingRect::new_x_y_w_h(2, 2, 4, 4)
91 )
92 .transform(&PointI32 { x: 2, y: 2 }),
93 PointI32 { x: 4, y: 4 }
94 );
95 }
96}