Rev 2097 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* box.h
* DIN Is Noise is copyright (c) 2006-2025 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 <algorithm>
struct edge {
enum {NONE=-1, BOTTOM, RIGHT, TOP, LEFT};
};
template <typename T> 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<T>& 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 <typename T> inline bool inbox (const box<T>& b, T x, T y) {
return ((x >= b.left) && (x <= b.right) && (y >= b.bottom) && (y <= b.top));
}
#endif