/* Fixed point implementation of 2 dimensional pnttors. */ #ifndef COM_PNT_H #define COM_PNT_H #include "def.h" #include "fix.h" #include "vec.h" #include typedef union { com_def_alignedas(16) com_def_vector(com_fix_t, a, 2); com_def_alignedas(16) struct { com_fix_t x; com_fix_t y; } s; } com_pnt_t; static inline com_pnt_t com_pnt_from(com_fix_t x, com_fix_t y) { return (com_pnt_t){.s = {.x = x, .y = y}}; } static inline com_pnt_t com_pnt_from_vec(com_vec_t a) { return (com_pnt_t){.s = {.x = a.a[0], .y = a.a[1]}}; } static inline com_pnt_t com_pnt_identity(void) { return (com_pnt_t){.s = { .x = COM_FIX_FRACUNIT, .y = COM_FIX_FRACUNIT, }}; } static inline com_pnt_t com_pnt_add(com_pnt_t a, com_pnt_t b) { return (com_pnt_t){ .s = {.x = com_fix_add(a.s.x, b.s.x), .y = com_fix_add(a.s.y, b.s.y)}}; } static inline com_pnt_t com_pnt_sub(com_pnt_t a, com_pnt_t b) { return (com_pnt_t){ .s = {.x = com_fix_sub(a.s.x, b.s.x), .y = com_fix_sub(a.s.y, b.s.y)}}; } static inline com_pnt_t com_pnt_mul(com_pnt_t a, com_pnt_t b) { return (com_pnt_t){ .s = {.x = com_fix_mul(a.s.x, b.s.x), .y = com_fix_mul(a.s.y, b.s.y)}}; } /* Note: this does not clamp for over/underflow cases */ static inline com_pnt_t com_pnt_div(com_pnt_t a, com_pnt_t b) { return (com_pnt_t){ .s = {.x = com_fix_div(a.s.x, b.s.x), .y = com_fix_div(a.s.y, b.s.y)}}; } /* Scale pnttor by a fixed point number */ static inline com_pnt_t com_pnt_scl(com_pnt_t a, com_fix_t b) { return (com_pnt_t){ .s = {.x = com_fix_mul(a.s.x, b), .y = com_fix_mul(a.s.y, b)}}; } static inline com_fix_t com_pnt_min(com_pnt_t a) { return com_fix_min(a.a[0], a.a[1]); } static inline com_fix_t com_pnt_max(com_pnt_t a) { return com_fix_max(a.a[0], a.a[1]); } /* TODO: Safeguard by com_fix_mul()? */ /* Tests whether a point is lying right to a line produced by l0 and l1. This assumes that l0 and l1 are in clockwise order. Result is positive or zero if it holds true, otherwise it's negative. */ static inline com_fix_t com_pnt_edge_orient(com_pnt_t l0, com_pnt_t l1, com_pnt_t p) { return (l0.s.x - l1.s.x) * (p.s.y - l1.s.y) - (l0.s.y - l1.s.y) * (p.s.x - l1.s.x); } static inline void com_pnt_print(com_pnt_t a) { com_fix_print(a.a[0]); com_fix_print(a.a[1]); } #endif