1#![deny(missing_docs)]
2
3extern crate float;
6
7use float::Float;
8
9pub trait Rect: Sized {
11 type Scalar: Float;
13 fn from_x_y_w_h(Self::Scalar, Self::Scalar, Self::Scalar, Self::Scalar)
15 -> Self;
16 #[inline(always)]
18 fn from_u32(rect: [u32; 4]) -> Self {
19 use float::FromPrimitive;
20
21 Rect::from_x_y_w_h(
22 FromPrimitive::from_u32(rect[0]),
23 FromPrimitive::from_u32(rect[1]),
24 FromPrimitive::from_u32(rect[2]),
25 FromPrimitive::from_u32(rect[3])
26 )
27 }
28 #[inline(always)]
30 fn from_i32(rect: [i32; 4]) -> Self {
31 use float::FromPrimitive;
32
33 Rect::from_x_y_w_h(
34 FromPrimitive::from_i32(rect[0]),
35 FromPrimitive::from_i32(rect[1]),
36 FromPrimitive::from_i32(rect[2]),
37 FromPrimitive::from_i32(rect[3])
38 )
39 }
40 fn x(&self) -> Self::Scalar;
42 fn y(&self) -> Self::Scalar;
44 fn w(&self) -> Self::Scalar;
46 fn h(&self) -> Self::Scalar;
48 fn set_x(&mut self, val: Self::Scalar);
50 fn set_y(&mut self, val: Self::Scalar);
52 fn set_w(&mut self, val: Self::Scalar);
54 fn set_h(&mut self, val: Self::Scalar);
56 #[inline(always)]
58 fn xy(&self) -> (Self::Scalar, Self::Scalar) { (self.x(), self.y()) }
59 #[inline(always)]
61 fn wh(&self) -> (Self::Scalar, Self::Scalar) { (self.w(), self.h()) }
62 #[inline(always)]
64 fn xw(&self) -> (Self::Scalar, Self::Scalar) { (self.x(), self.w()) }
65 #[inline(always)]
67 fn yh(&self) -> (Self::Scalar, Self::Scalar) { (self.y(), self.h()) }
68 #[inline(always)]
70 fn x1x2(&self) -> (Self::Scalar, Self::Scalar) { (self.x(), self.x() + self.w()) }
71 #[inline(always)]
73 fn y1y2(&self) -> (Self::Scalar, Self::Scalar) { (self.y(), self.y() + self.h()) }
74 #[inline(always)]
76 fn p1p2(&self) -> ([Self::Scalar; 2], [Self::Scalar; 2]) {
77 ([self.x(), self.y()], [self.x() + self.w(), self.y() + self.h()])
78 }
79 #[inline(always)]
81 fn xywh(&self) -> (Self::Scalar, Self::Scalar, Self::Scalar, Self::Scalar) {
82 (self.x(), self.y(), self.w(), self.h())
83 }
84 #[inline(always)]
86 fn center(&self) -> [Self::Scalar; 2] {
87 use float::FromPrimitive;
88
89 let _05: Self::Scalar = FromPrimitive::from_f64(0.5);
90 [self.x() + _05 * self.h(), self.y() + _05 * self.h()]
91 }
92 #[inline(always)]
94 fn is_empty(&self) -> bool {
95 use float::Zero;
96
97 self.w() * self.h() == Zero::zero()
98 }
99 fn margin(&self, val: Self::Scalar) -> Self {
102 use float::{ FromPrimitive, Zero };
103
104 let x: Self::Scalar;
105 let y: Self::Scalar;
106 let w: Self::Scalar;
107 let h: Self::Scalar;
108 let _2: Self::Scalar = FromPrimitive::from_f64(2.0);
109 let _05: Self::Scalar = FromPrimitive::from_f64(0.5);
110 let _0: Self::Scalar = Zero::zero();
111 if self.w() < _2 * val {
112 x = self.x() + _05 * self.w();
113 w = _0;
114 } else {
115 x = self.x() + val;
116 w = self.w() - _2 * val;
117 }
118 if self.h() < _2 * val {
119 y = self.y() + _05 * self.h();
120 h = _0;
121 } else {
122 y = self.y() + val;
123 h = self.h() - _2 * val;
124 }
125 <Self as Rect>::from_x_y_w_h(x, y, w, h)
126 }
127 fn split_left(&self, val: Self::Scalar, factor: Self::Scalar)
129 -> (Self, Self) {
130 use float::One;
131
132 let (x, y, w, h) = self.xywh();
133 if val > w * factor {
134 let _1: Self::Scalar = One::one();
135 (Rect::from_x_y_w_h(x, y, w * factor, h),
136 Rect::from_x_y_w_h(x + w * factor, y, w * (_1 - factor), h))
137 } else {
138 (Rect::from_x_y_w_h(x, y, val, h),
139 Rect::from_x_y_w_h(x + val, y, w - val, h))
140 }
141 }
142 #[inline(always)]
144 fn split_right(&self, val: Self::Scalar, factor: Self::Scalar)
145 -> (Self, Self) {
146 use float::One;
147
148 let (x, y, w, h) = self.xywh();
149 if val > w * factor {
150 let _1: Self::Scalar = One::one();
151 (Rect::from_x_y_w_h(x, y, w * (_1 - factor), h),
152 Rect::from_x_y_w_h(x + w * (_1 - factor), y, w * factor, h))
153 } else {
154 (Rect::from_x_y_w_h(x, y, w - val, h),
155 Rect::from_x_y_w_h(x + w - val, y, val, h))
156 }
157 }
158 fn split_top(&self, val: Self::Scalar, factor: Self::Scalar)
160 -> (Self, Self) {
161 use float::One;
162
163 let (x, y, w, h) = self.xywh();
164 if val > h * factor {
165 let _1: Self::Scalar = One::one();
166 (Rect::from_x_y_w_h(x, y, w, h * factor),
167 Rect::from_x_y_w_h(x, y + h * factor, w, h * (_1 - factor)))
168 } else {
169 (Rect::from_x_y_w_h(x, y, w, val),
170 Rect::from_x_y_w_h(x, y + val, w, h - val))
171 }
172 }
173 #[inline(always)]
175 fn split_bottom(&self, val: Self::Scalar, factor: Self::Scalar)
176 -> (Self, Self) {
177 use float::One;
178
179 let (x, y, w, h) = self.xywh();
180 if val > h * factor {
181 let _1: Self::Scalar = One::one();
182 (Rect::from_x_y_w_h(x, y, w, h * (_1 - factor)),
183 Rect::from_x_y_w_h(x, y + h * (_1 - factor), w, h * factor))
184 } else {
185 (Rect::from_x_y_w_h(x, y, w, h - val),
186 Rect::from_x_y_w_h(x, y + h - val, w, val))
187 }
188 }
189}
190
191impl Rect for [f64; 4] {
192 type Scalar = f64;
193 fn from_x_y_w_h(x: f64, y: f64, w: f64, h: f64) -> [f64; 4] {
194 [x, y, w, h]
195 }
196 fn x(&self) -> f64 { self[0] }
197 fn y(&self) -> f64 { self[1] }
198 fn w(&self) -> f64 { self[2] }
199 fn h(&self) -> f64 { self[3] }
200 fn set_x(&mut self, val: f64) { self[0] = val }
201 fn set_y(&mut self, val: f64) { self[1] = val }
202 fn set_w(&mut self, val: f64) { self[2] = val }
203 fn set_h(&mut self, val: f64) { self[3] = val }
204}
205
206
207impl Rect for [f32; 4] {
208 type Scalar = f32;
209 fn from_x_y_w_h(x: f32, y: f32, w: f32, h: f32) -> [f32; 4] {
210 [x, y, w, h]
211 }
212 fn x(&self) -> f32 { self[0] }
213 fn y(&self) -> f32 { self[1] }
214 fn w(&self) -> f32 { self[2] }
215 fn h(&self) -> f32 { self[3] }
216 fn set_x(&mut self, val: f32) { self[0] = val }
217 fn set_y(&mut self, val: f32) { self[1] = val }
218 fn set_w(&mut self, val: f32) { self[2] = val }
219 fn set_h(&mut self, val: f32) { self[3] = val }
220}
221
222#[cfg(test)]
223mod tests {
224 use super::*;
225
226 #[test]
227 fn is_empty() {
228 assert!([0.0, 0.0, 0.0, 0.0].is_empty());
229 assert!([0.0, 0.0, 1.0, 0.0].is_empty());
230 assert!([0.0, 0.0, 0.0, 1.0].is_empty());
231 assert!(![0.0, 0.0, 1.0, 1.0].is_empty());
232 }
233
234 #[test]
235 fn margin() {
236 assert_eq!([0.0, 0.0, 0.0, 0.0].margin(2.0), [0.0, 0.0, 0.0, 0.0]);
237 assert_eq!([0.0, 0.0, 1.0, 1.0].margin(2.0), [0.5, 0.5, 0.0, 0.0]);
238 assert_eq!([0.0, 0.0, 100.0, 100.0].margin(2.0), [2.0, 2.0, 96.0, 96.0]);
239 assert_eq!([0.0, 0.0, 100.0, 200.0].margin(2.0), [2.0, 2.0, 96.0, 196.0]);
240 }
241
242 #[test]
243 fn xywh() {
244 let rect = [0.0, 1.0, 2.0, 3.0];
245 assert_eq!(rect.x(), 0.0);
246 assert_eq!(rect.y(), 1.0);
247 assert_eq!(rect.w(), 2.0);
248 assert_eq!(rect.h(), 3.0);
249 }
250
251 #[test]
252 fn split_left() {
253 assert_eq!([0.0, 0.0, 0.0, 10.0].split_left(30.0, 0.5),
254 ([0.0, 0.0, 0.0, 10.0], [0.0, 0.0, 0.0, 10.0]));
255 assert_eq!([0.0, 0.0, 10.0, 10.0].split_left(15.0, 0.5),
256 ([0.0, 0.0, 5.0, 10.0], [5.0, 0.0, 5.0, 10.0]));
257 assert_eq!([0.0, 0.0, 100.0, 10.0].split_left(30.0, 0.5),
258 ([0.0, 0.0, 30.0, 10.0], [30.0, 0.0, 70.0, 10.0]));
259 }
260
261 #[test]
262 fn split_top() {
263 assert_eq!([0.0, 0.0, 10.0, 0.0].split_top(30.0, 0.5),
264 ([0.0, 0.0, 10.0, 0.0], [0.0, 0.0, 10.0, 0.0]));
265 assert_eq!([0.0, 0.0, 10.0, 10.0].split_top(15.0, 0.5),
266 ([0.0, 0.0, 10.0, 5.0], [0.0, 5.0, 10.0, 5.0]));
267 assert_eq!([0.0, 0.0, 10.0, 100.0].split_top(30.0, 0.5),
268 ([0.0, 0.0, 10.0, 30.0], [0.0, 30.0, 10.0, 70.0]));
269 }
270}