#include "geometry.h" #include //--- // Geometric primitives //--- vec2 vec_i2f(ivec2 p) { return (vec2){ fix(p.x), fix(p.y) }; } rect rect_i2f(irect r) { return (rect){ fix(r.l), fix(r.r), fix(r.t), fix(r.b) }; } ivec2 vec_f2i(vec2 p) { return (ivec2){ ffloor(p.x), ffloor(p.y) }; } irect rect_f2i(rect r) { return (irect){ fround(r.l), fround(r.r), fround(r.t), fround(r.b) }; } vec2 vec_i2f_center(ivec2 p) { return (vec2){ fix(p.x) + fix(0.5), fix(p.y) + fix(0.5) }; } fixed_t vec_dot(vec2 v, vec2 u) { return fmul(v.x, u.x) + fmul(v.y, u.y); } vec2 vec_rotate_30(vec2 v) { return (vec2){ fmul(fix(0.866), v.x) - v.y / 2, v.x / 2 + fmul(fix(0.866), v.y) }; } vec2 vec_rotate_m30(vec2 v) { return (vec2){ fmul(fix(0.866), v.x) + v.y / 2, -v.x / 2 + fmul(fix(0.866), v.y) }; } vec2 vec_rotate_45(vec2 v) { return (vec2){ fmul(fix(0.707), v.x) - fmul(fix(0.707), v.y), fmul(fix(0.707), v.x) + fmul(fix(0.707), v.y) }; } vec2 vec_rotate_m45(vec2 v) { return (vec2){ fmul(fix(0.707), v.x) + fmul(fix(0.707), v.y), -fmul(fix(0.707), v.x) + fmul(fix(0.707), v.y) }; } vec2 vec_rotate_60(vec2 v) { return (vec2){ v.x / 2 - fmul(fix(0.866), v.y), fmul(fix(0.866), v.x) + v.y / 2 }; } vec2 vec_rotate_m60(vec2 v) { return (vec2){ v.x / 2 + fmul(fix(0.866), v.y), -fmul(fix(0.866), v.x) + v.y / 2 }; } //--- // Rect operations //--- vec2 rect_center(rect r) { return (vec2){ (r.l + r.r) / 2, (r.t + r.b) / 2 }; } rect rect_scale(rect r, fixed_t factor) { return (rect){ .l = fmul(r.l, factor), .r = fmul(r.r, factor), .t = fmul(r.t, factor), .b = fmul(r.b, factor), }; } rect rect_translate(rect r, vec2 vec) { return (rect){ .l = r.l + vec.x, .r = r.r + vec.x, .t = r.t + vec.y, .b = r.b + vec.y, }; } void rect_draw(rect r0, int color) { irect r = rect_f2i(r0); dline(r.l, r.t, r.r, r.t, color); dline(r.l, r.t, r.l, r.b, color); dline(r.r, r.t, r.r, r.b, color); dline(r.l, r.b, r.r, r.b, color); } bool rect_collide(rect r1, rect r2) { return (r1.l < r2.r) && (r2.l < r1.r) && (r1.t < r2.b) && (r2.t < r1.b); } rect rect_rotate(rect r, int from_dir, int to_dir) { /* Normalize to one parameter */ to_dir -= from_dir; if(to_dir < 0) to_dir += 4; /* Perform up to 3 UP->RIGHT rotations */ while(to_dir-- > 0) { r = (rect){ -r.b, -r.t, r.l, r.r }; } return r; }