RogueLife/src/geometry.c

131 lines
2.5 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) };
}
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;
}