/* * box.h * DIN Is Noise is copyright (c) 2006-2021 Jagannathan Sampath * DIN Is Noise is released under GNU Public License 2.0 * For more information, please visit https://dinisnoise.org/ */ #ifndef __box #define __box #include struct edge { enum {NONE=-1, BOTTOM, RIGHT, TOP, LEFT}; }; template struct box { T left, bottom; T right, top; T width, height; T midx, midy; double width_1, height_1; box () { left = bottom = right = top = width = height = midx = midy = 0; width_1 = height_1 = 0.0; } box (T l, T b, T r, T t) { operator() (l, b, r, t); } inline void operator() (T l, T b, T r, T t) { left = l; bottom = b; right = r; top = t; calc (); } inline bool operator== (const box& b1) { return (left == b1.left && right == b1.right && bottom == b1.bottom && top == b1.top); } inline int calc () { int ret = 0; if (left > right) { std::swap (left, right); ret = 1; } if (bottom > top) { std::swap (bottom, top); ret = 1; } width = right - left; height = top - bottom; midx = (T) ((left + right) / 2.0); midy = (T) ((bottom + top) / 2.0); if (width != 0) width_1 = 1.0 / width; if (height != 0) height_1 = 1.0 / height; return ret; } inline void move (T dx, T dy) { left += dx; right += dx; bottom += dy; top += dy; calc (); } inline void resize (T dx, T dy) { right += dx; left -= dx; top += dy; bottom -= dy; calc (); } inline void lower_corner (T x, T y) { left = x; bottom = y; right = left + width; top = bottom + height; calc (); } int within_delta (T u, T v, T d2) { T vu = v - u; T vu2 = vu * vu; if (vu2 > d2) return 0; else return 1; } inline int get_edge_hit (T x, T y, T d2) { if (within_delta (top, y, d2)) return edge::TOP; else if (within_delta (bottom, y, d2)) return edge::BOTTOM; else if (within_delta (left, x, d2)) return edge::LEFT; else if (within_delta (right, x, d2)) return edge::RIGHT; else return edge::NONE; } inline void set_edge (int e, T x, T y) { if (e == edge::LEFT) { if (x < right) left = x; } else if (e == edge::RIGHT) { if (x > left) right = x; } else if (e == edge::BOTTOM) { if (y < top) bottom = y; } else if (e == edge::TOP) { if (y > bottom) top = y; } else return; calc (); } }; template inline bool inbox (const box& b, T x, T y) { return ((x >= b.left) && (x <= b.right) && (y >= b.bottom) && (y <= b.top)); } #endif