aboutsummaryrefslogtreecommitdiff
path: root/lib/rect/rect.odin
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rect/rect.odin')
-rw-r--r--lib/rect/rect.odin133
1 files changed, 133 insertions, 0 deletions
diff --git a/lib/rect/rect.odin b/lib/rect/rect.odin
new file mode 100644
index 0000000..197a966
--- /dev/null
+++ b/lib/rect/rect.odin
@@ -0,0 +1,133 @@
+package rect
+
+Rect :: struct($T: typeid) {
+ l, r, t, b: T,
+}
+
+RECTF_INF :: RectF { max(f32), -max(f32), max(f32), -max(f32) }
+
+RectF :: Rect(f32)
+RectI :: Rect(int)
+
+i2f :: proc(rect: RectI) -> RectF {
+ return { f32(rect.l), f32(rect.r), f32(rect.t), f32(rect.b) }
+}
+
+wh :: proc(x, y, w, h: $T) -> (res: Rect(T)) {
+ res.l = x
+ res.r = x + w
+ res.t = y
+ res.b = y + h
+ return
+}
+
+sized :: proc(rect: ^Rect($T), pos: [2]T, size: [2]T) {
+ rect.l = pos.x
+ rect.r = pos.x + size.x
+ rect.t = pos.y
+ rect.b = pos.y + size.y
+}
+
+overlap :: proc(a, b: Rect($T)) -> bool {
+ return b.r >= a.l && b.l <= a.r && b.b >= a.t && b.t <= a.b
+}
+
+inf_push :: proc(rect: ^Rect($T), pos: [2]T) {
+ rect.l = min(rect.l, pos.x)
+ rect.r = max(rect.r, pos.x)
+ rect.t = min(rect.t, pos.y)
+ rect.b = max(rect.b, pos.y)
+}
+
+// center :: proc(rect: Rect($T)) -> [2]T {
+// return { f32(rect.l) + f32(rect.r - rect.l) / 2, f32(rect.t) + f32(rect.b - rect.t) / 2 }
+// }
+
+valid :: proc(rect: Rect($T)) -> bool {
+ return (rect.r - rect.l) > 0 && (rect.b - rect.t) > 0
+}
+
+invalid :: #force_inline proc(rect: Rect($T)) -> bool { return !valid(rect) }
+
+intersection :: proc(a, b: Rect($T)) -> (res: Rect(T)) {
+ res = a
+ if a.l < b.l do res.l = b.l
+ if a.t < b.t do res.t = b.t
+ if a.r > b.r do res.r = b.r
+ if a.b > b.b do res.b = b.b
+ return
+}
+
+margin :: proc(a: Rect($T), value: T) -> Rect(T) {
+ a := a
+ a.l += value
+ a.t += value
+ a.r -= value
+ a.b -= value
+ return a
+}
+
+offset :: proc(rect: Rect($T), x, y: T) -> (res: Rect(T)) {
+ res = rect
+ res.l += x
+ res.r += x
+ res.t += y
+ res.b += y
+ return
+}
+
+contains :: proc(a: Rect($T), x, y: T) -> bool {
+ return a.l <= x && a.r > x && a.t <= y && a.b > y
+}
+
+widthf :: proc(a: RectI) -> f32 {
+ return f32(a.r - a.l)
+}
+
+heightf :: proc(a: RectI) -> f32 {
+ return f32(a.b - a.t)
+}
+
+widthi :: proc(a: RectI) -> int {
+ return int(a.r - a.l)
+}
+
+heighti :: proc(a: RectI) -> int {
+ return int(a.b - a.t)
+}
+
+splitv :: proc(rect: RectF) -> (left, right: RectF) {
+ left = rect
+ right = rect
+ left.r = rect.l + (rect.r - rect.l) / 2
+ right.l = left.r
+ return
+}
+
+cut_left :: proc(rect: ^Rect($T), a: T) -> (res: Rect(T)) {
+ res = rect^
+ res.r = rect.l + a
+ rect.l = res.r
+ return
+}
+
+cut_right :: proc(rect: ^Rect($T), a: T) -> (res: Rect(T)) {
+ res = rect^
+ res.l = rect.r - a
+ rect.r = res.l
+ return
+}
+
+cut_top :: proc(rect: ^Rect($T), a: T) -> (res: Rect(T)) {
+ res = rect^
+ res.b = rect.t + a
+ rect.t = res.b
+ return
+}
+
+cut_bottom :: proc(rect: ^Rect($T), a: T) -> (res: Rect(T)) {
+ res = rect^
+ res.t = rect.b - a
+ rect.b = res.t
+ return
+}