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