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 use super::*;
67 use crate::interval::Interval;
68 use crate::vector2::Vector2;
69
70 #[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 }
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}