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