#include "geometry.h" #include //--- // Geometric primitives //--- fpoint_t point_i2f(ipoint_t p) { return (fpoint_t){ fix(p.x), fix(p.y) }; } frect_t rect_i2f(irect_t r) { return (frect_t){ fix(r.l), fix(r.r), fix(r.t), fix(r.b) }; } ipoint_t point_f2i(fpoint_t p) { return (ipoint_t){ ffloor(p.x), ffloor(p.y) }; } irect_t rect_f2i(frect_t r) { return (irect_t){ fround(r.l), fround(r.r), fround(r.t), fround(r.b) }; } fpoint_t point_i2f_center(ipoint_t p) { return (fpoint_t){ fix(p.x) + fix(0.5), fix(p.y) + fix(0.5) }; } //--- // Rect operations //--- fpoint_t rect_center(frect_t r) { return (fpoint_t){ (r.l + r.r) / 2, (r.t + r.b) / 2 }; } frect_t rect_scale(frect_t r, fixed_t factor) { return (frect_t){ .l = fmul(r.l, factor), .r = fmul(r.r, factor), .t = fmul(r.t, factor), .b = fmul(r.b, factor), }; } frect_t rect_translate(frect_t r, fpoint_t vec) { return (frect_t){ .l = r.l + vec.x, .r = r.r + vec.x, .t = r.t + vec.y, .b = r.b + vec.y, }; } void rect_draw(frect_t r0, int color) { irect_t 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(frect_t r1, frect_t r2) { return (r1.l < r2.r) && (r2.l < r1.r) && (r1.t < r2.b) && (r2.t < r1.b); } frect_t rect_rotate(frect_t 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 = (frect_t){ -r.b, -r.t, r.l, r.r }; } return r; }