#ifndef CUTES_VMATH_H #define CUTES_VMATH_H #include "stddef.h" #include #if defined _WIN32 && ! defined isnanf # define isnanf(x) _isnanf(x) # define HAVE_ISNANF #endif #if VMATH_SDL == 1 #include typedef SDL_FPoint Vector; typedef SDL_Point IVector; #else typedef struct Vector { float x; float y; } Vector; typedef struct IVector { int x; int y; } IVector; #endif // Vector Constant Macros #define ZeroVector (Vector){0.0f, 0.0f} #define InfinityVector (Vector){INFINITY, INFINITY} #define OneVector (Vector){1.0f,1.0f} #define UpVector (Vector){0.0f,-1.0f} #define RightVector (Vector){1.0f,0.0f} #define LeftVector (Vector){-1.0f,0.0f} #define DownVector (Vector){0.0f,1.0f} #define MakeVector(__X, __Y) (Vector){__X, __Y} #define VectorFrom(__A) (Vector){__A, __A} // Integer Vector Constant Macros #define ZeroIVector (IVector){0,0} #define OneIVector (IVector){1,1} #define UpIVector (IVector){-1,0} #define DownIVector (IVector){1,0} #define RightIVector (IVector){1,0} #define LeftIVector (IVector){-1,0} #define MakeIVector(__X, __Y) (IVector){__X, __Y} #define IVectorFrom(__A) (IVector){__A, __A} /// // Floating point vector maths functions. /// static inline int veqf(Vector a, Vector b) { const float e = 0.0001f; return fabsf(a.x - b.x) + fabsf(a.y - b.y) < e; } static inline int visnanf(Vector a) { return isnanf(a.x) || isnanf(a.y); } static inline Vector vaddf(Vector a, Vector b) { return (Vector){a.x + b.x, a.y + b.y}; } static inline Vector vsubf(Vector a, Vector b) { return (Vector){a.x - b.x, a.y - b.y}; } static inline Vector vmulff(Vector a, float b) { return (Vector){a.x * b, a.y * b}; } static inline Vector vmulf(Vector a, Vector b) { return (Vector) {a.x * b.x, a.y * b.y}; } static inline Vector vinvf(Vector a) { return (Vector){-a.x, -a.y}; } static inline Vector vperpendicularf(Vector a) { return (Vector){a.y, -a.x}; } static inline float vmagnitudef(Vector a) { if(veqf(a, ZeroVector)) return 0.f; a.x = fabsf(a.x); a.y = fabsf(a.y); return sqrtf(a.x*a.x + a.y*a.y); } static inline float vsqrmagnitudef(Vector a) { a.x = fabsf(a.x); a.y = fabsf(a.y); return a.x*a.x + a.y*a.y; } static inline Vector vnormalizedf(Vector a) { if(veqf(a, ZeroVector)) return ZeroVector; return vmulff(a, 1.0f/vmagnitudef(a)); } static inline float vdotf(Vector a, Vector b) { return (a.x*b.x) + (a.y*b.y); } static inline float vdistancef(Vector a, Vector b) { return vmagnitudef(vsubf(a, b)); } static inline float vsqrdistf(Vector a, Vector b) { return vsqrmagnitudef(vsubf(a, b)); } static inline Vector vreciprocalf(Vector a) { return (Vector){1.0f/a.x, 1.0f/a.y}; } static inline Vector vrotatef(Vector a, float t) { return (Vector){ cosf(t) * a.x - sinf(t) * a.y, sinf(t) * a.x + cosf(t) * a.y }; } static inline float vanglebetweenf(Vector a, Vector b) { return vdotf(a, b) / (vmagnitudef(a) * vmagnitudef(b)); } static inline Vector vprojectf(Vector onto, Vector from) { float dot = vdotf(onto, from); return vmulff(onto, dot); } static inline Vector vlerpf(Vector start, Vector end, float t) { if(veqf(start, end)) return end; t = fminf(fmaxf(0.0f, t), 1.0f); return vaddf(start, vmulff(vsubf(end, start), t)); } static inline Vector vmovetowardsf(Vector start, Vector end, float delta) { return vlerpf(start, end, delta / vdistancef(end, start)); } static inline Vector vaveragef(Vector* array, size_t count) { Vector acc = ZeroVector; for(size_t i = 0; i < count; ++i) { acc = vaddf(acc, array[i]); } return vmulff(acc, 1.0f/(float)count); } static inline int veqi(IVector a, IVector b) { return a.x == b.x && a.y == b.y; } static inline IVector vaddi(IVector a, IVector b) { return (IVector){a.x + b.x, a.y + b.y}; } static inline IVector vsubi(IVector a, IVector b) { return (IVector){a.x - b.x, a.y - b.y}; } static inline IVector vmuli(IVector a, IVector b) { return (IVector){a.x * b.x, a.y * b.y}; } #endif // !CUTES_VMATH_H