1mod point;
2pub use point::Point;
3
4use std::ops::{Add, Sub};
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct Rect<T> {
8 pub p1: Point<T>,
9 pub p2: Point<T>,
10}
11
12impl<T> Rect<T> {
13 pub fn new(p1: Point<T>, p2: Point<T>) -> Self {
14 Rect { p1, p2 }
15 }
16
17 pub fn from_coords(x1: T, y1: T, x2: T, y2: T) -> Self {
18 Rect {
19 p1: Point { x: x1, y: y1 },
20 p2: Point { x: x2, y: y2 },
21 }
22 }
23
24}
25
26impl<T> Rect<T>
27where
28 T: Copy + Ord,
29{
30 pub fn normalized(self) -> Self {
31 let min_x = self.p1.x.min(self.p2.x);
32 let max_x = self.p1.x.max(self.p2.x);
33 let min_y = self.p1.y.min(self.p2.y);
34 let max_y = self.p1.y.max(self.p2.y);
35
36 Rect {
37 p1: Point { x: min_x, y: min_y },
38 p2: Point { x: max_x, y: max_y },
39 }
40 }
41
42 pub fn contains(&self, point: Point<T>) -> bool {
43 let r = self.normalized();
44 point.x >= r.p1.x && point.x <= r.p2.x &&
45 point.y >= r.p1.y && point.y <= r.p2.y
46 }
47}
48
49impl<T> Rect<T>
50where
51 T: Copy + Ord + Sub<Output = T>,
52{
53 pub fn width(&self) -> T {
54 let r = self.normalized();
55 r.p2.x - r.p1.x
56 }
57
58 pub fn height(&self) -> T {
59 let r = self.normalized();
60 r.p2.y - r.p1.y
61 }
62}
63
64
65impl<T> Rect<T>
66where
67 T: Copy + Ord + Add<Output = T> + Sub<Output = T> + std::ops::Mul<Output = T>,
68{
69 pub fn area(&self) -> T {
70 self.width() * self.height()
71 }
72}
73