physdes/
merge_obj.rs

1use crate::generic::MinDist;
2use crate::interval::{Enlarge, Intersect};
3use crate::point::Point;
4use std::cmp;
5
6#[derive(PartialEq, Eq, Copy, Clone, Hash, Debug, Default)]
7pub struct MergeObj<T1, T2> {
8    impl_: Point<T1, T2>,
9}
10
11impl<T1, T2> MergeObj<T1, T2> {
12    pub fn new(xcoord: T1, ycoord: T2) -> MergeObj<T1, T2> {
13        MergeObj {
14            impl_: Point::new(xcoord, ycoord),
15        }
16    }
17
18    pub fn construct(xcoord: i32, ycoord: i32) -> MergeObj<i32, i32> {
19        let impl_ = Point::new(xcoord + ycoord, xcoord - ycoord);
20        MergeObj { impl_ }
21    }
22}
23
24impl<T1, T2> MergeObj<T1, T2>
25where
26    T1: MinDist<T1>,
27    T2: MinDist<T2>,
28{
29    pub fn min_dist_with(&self, other: &MergeObj<T1, T2>) -> u32 {
30        cmp::max(
31            self.impl_.xcoord.min_dist_with(&other.impl_.xcoord),
32            self.impl_.ycoord.min_dist_with(&other.impl_.ycoord),
33        )
34    }
35}
36
37impl<T1, T2> MergeObj<T1, T2>
38where
39    T1: MinDist<T1> + Enlarge<i32, Output = T1> + Intersect<T1, Output = T1>,
40    T2: MinDist<T2> + Enlarge<i32, Output = T2> + Intersect<T2, Output = T2>,
41{
42    pub fn enlarge_with(&self, alpha: i32) -> MergeObj<T1, T2> {
43        let xcoord = self.impl_.xcoord.enlarge_with(alpha);
44        let ycoord = self.impl_.ycoord.enlarge_with(alpha);
45        MergeObj::new(xcoord, ycoord)
46    }
47
48    pub fn intersect_with(&self, other: &MergeObj<T1, T2>) -> MergeObj<T1, T2> {
49        let point = self.impl_.intersect_with(&other.impl_);
50        MergeObj::new(point.xcoord, point.ycoord)
51    }
52
53    pub fn merge_with(&self, other: &MergeObj<T1, T2>) -> MergeObj<T1, T2> {
54        let alpha = self.min_dist_with(other);
55        let half = alpha / 2;
56        let trr1 = self.enlarge_with(half as i32);
57        let trr2 = other.enlarge_with((alpha - half) as i32);
58        trr1.intersect_with(&trr2)
59    }
60}
61
62#[cfg(test)]
63mod test {
64    // #![allow(non_upper_case_globals)]
65
66    use super::*;
67    use crate::interval::Interval;
68    use crate::vector2::Vector2;
69
70    // use crate::generic::Overlap;
71    // use crate::interval::Interval;
72
73    // use core::i32;
74
75    #[test]
76    fn test_merge_obj() {
77        let r1 = MergeObj::<i32, i32>::construct(4, 5);
78        let r2 = MergeObj::<i32, i32>::construct(7, 9);
79
80        assert_ne!(r1, r2);
81        assert_eq!(r1.min_dist_with(&r2), 7);
82        // assert_eq!(min_dist(&r1, &r2), 7);
83    }
84
85    #[test]
86    fn test_merge() {
87        let s1: MergeObj<Interval<i32>, Interval<i32>> =
88            MergeObj::new(Interval::new(200, 600), Interval::new(200, 600));
89        let s2: MergeObj<Interval<i32>, Interval<i32>> =
90            MergeObj::new(Interval::new(500, 900), Interval::new(500, 900));
91        let m1 = s1.merge_with(&s2);
92        println!("{:?}", m1);
93        assert_eq!(
94            m1,
95            MergeObj::new(Interval::new(500, 600), Interval::new(500, 600))
96        );
97    }
98
99    #[test]
100    fn test_merge_2() {
101        let mut a: MergeObj<Interval<i32>, Interval<i32>> =
102            MergeObj::new(Interval::new(4, 5), Interval::new(4, 5));
103        let b: MergeObj<Interval<i32>, Interval<i32>> =
104            MergeObj::new(Interval::new(7, 9), Interval::new(7, 9));
105        let v = Vector2::new(Interval::new(2, 3), Interval::new(2, 3));
106        a.impl_.xcoord.lb += v.x_.lb;
107        a.impl_.xcoord.ub += v.x_.ub;
108        a.impl_.ycoord.lb += v.y_.lb;
109        a.impl_.ycoord.ub += v.y_.ub;
110        a.impl_.xcoord.lb -= v.x_.lb;
111        a.impl_.xcoord.ub -= v.x_.ub;
112        a.impl_.ycoord.lb -= v.y_.lb;
113        a.impl_.ycoord.ub -= v.y_.ub;
114        assert_eq!(a, MergeObj::new(Interval::new(4, 5), Interval::new(4, 5)));
115        let r1 = a.enlarge_with(3);
116        assert_eq!(r1, MergeObj::new(Interval::new(1, 8), Interval::new(1, 8)));
117        let r2 = b.enlarge_with(4);
118        assert_eq!(
119            r2,
120            MergeObj::new(Interval::new(3, 13), Interval::new(3, 13))
121        );
122        let r3 = r1.intersect_with(&r2);
123        assert_eq!(r3, MergeObj::new(Interval::new(3, 8), Interval::new(3, 8)));
124    }
125
126    #[test]
127    fn test_min_dist_with_more_cases() {
128        let r1 = MergeObj::<i32, i32>::construct(0, 0);
129        let r2 = MergeObj::<i32, i32>::construct(3, 4);
130        assert_eq!(r1.min_dist_with(&r2), 7);
131
132        let r3 = MergeObj::<i32, i32>::construct(-3, -4);
133        assert_eq!(r1.min_dist_with(&r3), 7);
134    }
135
136    #[test]
137    fn test_enlarge_with_more_cases() {
138        let s1: MergeObj<Interval<i32>, Interval<i32>> =
139            MergeObj::new(Interval::new(200, 600), Interval::new(200, 600));
140        let enlarged = s1.enlarge_with(100);
141        assert_eq!(
142            enlarged,
143            MergeObj::new(Interval::new(100, 700), Interval::new(100, 700))
144        );
145    }
146
147    #[test]
148    fn test_intersect_with_more_cases() {
149        let s1: MergeObj<Interval<i32>, Interval<i32>> =
150            MergeObj::new(Interval::new(200, 600), Interval::new(200, 600));
151        let s2: MergeObj<Interval<i32>, Interval<i32>> =
152            MergeObj::new(Interval::new(500, 900), Interval::new(500, 900));
153        let intersected = s1.intersect_with(&s2);
154        assert_eq!(
155            intersected,
156            MergeObj::new(Interval::new(500, 600), Interval::new(500, 600))
157        );
158
159        let s3 = MergeObj::new(Interval::new(700, 900), Interval::new(700, 900));
160        let intersected2 = s1.intersect_with(&s3);
161        assert!(intersected2.impl_.xcoord.is_invalid());
162        assert!(intersected2.impl_.ycoord.is_invalid());
163    }
164
165    #[test]
166    fn test_merge_with_more_cases() {
167        let s1: MergeObj<Interval<i32>, Interval<i32>> =
168            MergeObj::new(Interval::new(0, 100), Interval::new(0, 100));
169        let s2: MergeObj<Interval<i32>, Interval<i32>> =
170            MergeObj::new(Interval::new(100, 200), Interval::new(100, 200));
171        let merged = s1.merge_with(&s2);
172        assert_eq!(
173            merged,
174            MergeObj::new(Interval::new(100, 100), Interval::new(100, 100))
175        );
176    }
177}