RogueLife/src/geometry.c

90 lines
1.6 KiB
C

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