182 lines
4.0 KiB
C
182 lines
4.0 KiB
C
|
#ifndef _fencer_vmath_h
|
||
|
#define _fencer_vmath_h
|
||
|
|
||
|
#include "stddef.h"
|
||
|
#include <math.h>
|
||
|
|
||
|
#if defined _WIN32 && ! defined isnanf
|
||
|
# define isnanf(x) _isnanf(x)
|
||
|
# define HAVE_ISNANF
|
||
|
#endif
|
||
|
|
||
|
#if VMATH_SDL == 1
|
||
|
|
||
|
#include <SDL2/SDL_rect.h>
|
||
|
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 // !_fencer_vmath_h
|