1 /*
2 * box.h
3 * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath
4 * DIN Is Noise is released under GNU Public License 2.0
5 * For more information, please visit https://dinisnoise.org/
6 */
7 
8 #ifndef __box
9 #define __box
10 
11 #include <algorithm>
12 
13 struct edge {
14 	enum {NONE=-1, BOTTOM, RIGHT, TOP, LEFT};
15 };
16 
17 template <typename T> struct box {
18 
19   T left, bottom;
20   T right, top;
21   T width, height;
22   T midx, midy;
23 
24   double width_1, height_1;
25 
boxbox26   box () {
27     left = bottom = right = top = width = height = midx = midy = 0;
28     width_1 = height_1 = 0.0;
29   }
30 
boxbox31   box (T l, T b, T r, T t) { operator() (l, b, r, t); }
32 
operatorbox33   inline void operator() (T l, T b, T r, T t) {
34     left = l;
35     bottom = b;
36     right = r;
37     top = t;
38     calc ();
39   }
40 
41   inline bool operator== (const box<T>& b1) {
42     return (left == b1.left && right == b1.right && bottom == b1.bottom && top == b1.top);
43   }
44 
calcbox45   inline int calc () {
46 
47 		int ret = 0;
48 
49     if (left > right) {
50 			std::swap (left, right);
51 			ret = 1;
52 		}
53 
54     if (bottom > top) {
55 			std::swap (bottom, top);
56 			ret = 1;
57 		}
58 
59     width = right - left;
60     height = top - bottom;
61 
62     midx = (T) ((left + right) / 2.0);
63     midy = (T) ((bottom + top) / 2.0);
64 
65     if (width != 0) width_1 = 1.0 / width;
66     if (height != 0) height_1 = 1.0 / height;
67 
68 		return ret;
69 
70   }
71 
movebox72   inline void move (T dx, T dy) {
73     left += dx;
74     right += dx;
75     bottom += dy;
76     top += dy;
77     calc ();
78   }
79 
resizebox80   inline void resize (T dx, T dy) {
81     right += dx;
82     left -= dx;
83     top += dy;
84     bottom -= dy;
85     calc ();
86   }
87 
lower_cornerbox88   inline void lower_corner (T x, T y) {
89     left = x;
90     bottom = y;
91     right = left + width;
92     top = bottom + height;
93     calc ();
94   }
95 
within_deltabox96   int within_delta (T u, T v, T d2) {
97     T vu = v - u;
98 		T vu2 = vu * vu;
99 		if (vu2 > d2) return 0; else return 1;
100   }
101 
get_edge_hitbox102   inline int get_edge_hit (T x, T y, T d2) {
103 		if (within_delta (top, y, d2)) return edge::TOP; else
104 		if (within_delta (bottom, y, d2)) return edge::BOTTOM; else
105 		if (within_delta (left, x, d2)) return edge::LEFT; else
106 		if (within_delta (right, x, d2)) return edge::RIGHT; else
107 		return edge::NONE;
108   }
109 
set_edgebox110   inline void set_edge (int e, T x, T y) {
111 		if (e == edge::LEFT) {
112 			if (x < right) left = x;
113 		} else if (e == edge::RIGHT) {
114 			if (x > left) right = x;
115 		} else if (e == edge::BOTTOM) {
116 			if (y < top) bottom = y;
117 		} else if (e == edge::TOP) {
118 			if (y > bottom) top = y;
119 		} else return;
120     calc ();
121   }
122 
123 };
124 
inbox(const box<T> & b,T x,T y)125 template <typename T> inline bool inbox (const box<T>& b, T x, T y) {
126   return ((x >= b.left) && (x <= b.right) && (y >= b.bottom) && (y <= b.top));
127 }
128 
129 #endif
130