RogueLife/src/geometry.c

90 lines
1.7 KiB
C

#include "geometry.h"
#include <gint/display.h>
//---
// 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;
}