git-svn-id: https://clonekeenplus.svn.sourceforge.net/svnroot/clonekeenplus/cgenius/trunk@87 4df4b0f3-56ce-47cb-b001-ed939b7d65a6
267 lines
6.5 KiB
C++
267 lines
6.5 KiB
C++
/////////////////////////////////////////
|
|
//
|
|
// OpenLieroX
|
|
//
|
|
// Auxiliary Software class library
|
|
//
|
|
// based on the work of JasonB
|
|
// enhanced by Dark Charlie and Albert Zeyer
|
|
//
|
|
// code under LGPL
|
|
//
|
|
/////////////////////////////////////////
|
|
|
|
|
|
// Mathematics Library
|
|
// Created 20/12/01
|
|
// Jason Boettcher
|
|
// Albert Zeyer
|
|
|
|
|
|
#ifndef __MATHLIB_H__
|
|
#define __MATHLIB_H__
|
|
|
|
#include <cmath>
|
|
|
|
#include "CVec.h"
|
|
|
|
|
|
// Constants
|
|
#define PI 3.14159265358979323846
|
|
|
|
|
|
|
|
|
|
// Routines
|
|
float GetRandomNum(); // get a random float from [-1,1]
|
|
float GetRandomPosNum(); // get a random float from [0,1]
|
|
int GetRandomInt(int max); // get a random int from [0,max]
|
|
int Round(float x);
|
|
|
|
/*#ifdef _MSC_VER
|
|
float cos(float _v) {return cosf(_v); }
|
|
float sin(float _v) {return sinf(_v); }
|
|
float tan(float _v) {return tanf(_v); }
|
|
float atan(float _v) {return atanf(_v); }
|
|
float sqrt(float _v) {return sqrtf(_v); }
|
|
#endif*/
|
|
|
|
|
|
float CalculateDistance(CVec p1, CVec p2);
|
|
float NormalizeVector(CVec *vec);
|
|
CVec GetRandomVec();
|
|
void GetVecsFromAngle(int yaw,CVec *forward, CVec *right);
|
|
float VectorAngle(CVec vec1, CVec vec2);
|
|
float VectorLength(CVec vec);
|
|
float fastSQRT(float x);
|
|
|
|
#define SIGN(x) (((x) > 0)?1:(((x) < 0)?-1:0))
|
|
#define SQR(x) ((x)*(x))
|
|
|
|
#undef MIN
|
|
#undef MAX
|
|
|
|
template <typename T> T MIN(T a, T b) { return a < b ? a : b; }
|
|
template <typename T> T MAX(T a, T b) { return a > b ? a : b; }
|
|
inline unsigned long MIN(unsigned long a, unsigned int b) { return a < b ? a : b; }
|
|
template <typename T> T CLAMP(const T& num, const T& lower_bound, const T& upper_bound) {
|
|
return num < lower_bound ? lower_bound : (num > upper_bound ? upper_bound : num); }
|
|
template <typename T> int CLAMP_DIRECT(T& num, const T& lower_bound, const T& upper_bound) {
|
|
if(num < lower_bound) {
|
|
num = lower_bound;
|
|
return -1;
|
|
} else if(num > upper_bound) {
|
|
num = upper_bound;
|
|
return 1;
|
|
} else return 0;
|
|
}
|
|
template <typename T> void REDUCE_CONST(T& v, const T& red_const) {
|
|
if(v > 0) v = MAX((T)0, v - red_const); else if(v < 0) v = MIN((T)0, v + red_const); }
|
|
template <typename T> void RESET_SMALL(T& v, const T& limit) {
|
|
if((v > 0 && v < limit) || (v < 0 && v > -limit)) v = 0; }
|
|
|
|
template <typename T> void MOD(T& a, const T& b) { a %= b; if(a < 0) a += b; }
|
|
template <typename T> void FMOD(T& a, const T& b) { a -= b * floor(a / b); if(a < 0) a += b; }
|
|
|
|
|
|
template<typename _T>
|
|
class SquareMatrix {
|
|
public:
|
|
VectorD2<_T> v1, v2;
|
|
SquareMatrix(VectorD2<_T> _v1 = VectorD2<_T>(0,0), VectorD2<_T> _v2 = VectorD2<_T>(0,0)) {
|
|
v1 = _v1; v2 = _v2;
|
|
}
|
|
|
|
static SquareMatrix Identity() {
|
|
return SquareMatrix(VectorD2<_T>(1,0), VectorD2<_T>(0,1));
|
|
}
|
|
|
|
static SquareMatrix RotateMatrix(float angle) {
|
|
SquareMatrix m;
|
|
m.v1.x = cos(angle);
|
|
m.v1.y = sin(angle);
|
|
m.v2.x = -m.v1.y;
|
|
m.v2.y = m.v1.x;
|
|
return m;
|
|
}
|
|
|
|
CVec operator()(const VectorD2<_T>& v) const {
|
|
return CVec(v.x*v1.x + v.y*v2.x, v.x*v1.y + v.y*v2.y);
|
|
}
|
|
SquareMatrix operator*(const SquareMatrix& m) const {
|
|
return SquareMatrix((*this)(m.v1), (*this)(m.v2));
|
|
}
|
|
SquareMatrix operator*(const float m) const {
|
|
return SquareMatrix(v1*m, v2*m);
|
|
}
|
|
SquareMatrix operator*(const int m) const {
|
|
return SquareMatrix(v1*m, v2*m);
|
|
}
|
|
SquareMatrix operator/(const float m) const {
|
|
return SquareMatrix(v1/m, v2/m);
|
|
}
|
|
SquareMatrix operator/(const int m) const {
|
|
return SquareMatrix(v1/m, v2/m);
|
|
}
|
|
_T det() const {
|
|
return v1.x*v2.y - v1.y*v2.x;
|
|
}
|
|
SquareMatrix inverse() const {
|
|
_T tdet = det();
|
|
if(tdet == 0)
|
|
return SquareMatrix();
|
|
else
|
|
return SquareMatrix(VectorD2<_T>(v2.y,-v1.y),VectorD2<_T>(-v2.x,v1.x))/tdet;
|
|
}
|
|
|
|
// v1 is the upper-left, v2 the right-bottom
|
|
bool isInDefinedArea(const VectorD2<_T>& p) const {
|
|
return v1.x <= p.x && p.x <= v2.x && v1.y <= p.y && p.y <= v2.y;
|
|
}
|
|
|
|
VectorD2<_T> getCenter() const {
|
|
return (v1 + v2) / 2;
|
|
}
|
|
|
|
SquareMatrix getInsersectionWithArea(const SquareMatrix& a) const {
|
|
return SquareMatrix(
|
|
VectorD2<_T>( MAX(a.v1.x, v1.x), MAX(a.v1.y, v1.y) ),
|
|
VectorD2<_T>( MIN(a.v2.x, v2.x), MIN(a.v2.y, v2.y) )
|
|
);
|
|
}
|
|
|
|
};
|
|
|
|
|
|
class Parabola {
|
|
public:
|
|
float a, b, c; // a*x^2 + b*x + c
|
|
public:
|
|
Parabola() : a(0), b(0), c(0) {}
|
|
Parabola(float pa, float pb, float pc) : a(pa), b(pb), c(pc) {}
|
|
Parabola(const Parabola& p) { a = p.a; b = p.b; c = p.c; }
|
|
Parabola(CVec p1, CVec p2, CVec p3);
|
|
Parabola(CVec p1, float angleP1, CVec p2);
|
|
|
|
inline bool operator==(const Parabola& p) const {
|
|
return (a == p.a && b == p.b && c == p.c);
|
|
}
|
|
|
|
float getLength(CVec p1, CVec p2);
|
|
float getLength(float pa, float pb);
|
|
bool isPointAtParabola(CVec p1) {
|
|
return (p1.y == (a * p1.x * p1.x ) + (b * p1.x) + c);
|
|
}
|
|
};
|
|
|
|
|
|
// Random number generator with save()/restore() methods that will save and restore generator's state
|
|
// This generator should produce the same numbers on any CPU architecture, if initialized with the same seed.
|
|
// Ripped from Gnu Math library
|
|
// I don't want to use Mersenne Twister 'cuz it has a state of 624 ints which should be copied with Save()/Restore()
|
|
|
|
class SyncedRandom
|
|
{
|
|
public:
|
|
|
|
SyncedRandom( unsigned long s = getRandomSeed() )
|
|
{
|
|
if (!s)
|
|
s = 1UL; /* default seed is 1 */
|
|
|
|
z1 = LCG (s);
|
|
if (z1 < 2UL)
|
|
z1 += 2UL;
|
|
z2 = LCG (z1);
|
|
if (z2 < 8UL)
|
|
z2 += 8UL;
|
|
z3 = LCG (z2);
|
|
if (z3 < 16UL)
|
|
z3 += 16UL;
|
|
z4 = LCG (z3);
|
|
if (z4 < 128UL)
|
|
z4 += 128UL;
|
|
|
|
/* Calling RNG ten times to satify recurrence condition */
|
|
getInt(); getInt(); getInt(); getInt(); getInt();
|
|
getInt(); getInt(); getInt(); getInt(); getInt();
|
|
};
|
|
|
|
// Returns unsigned int in a range 0 : UINT_MAX
|
|
unsigned long getInt()
|
|
{
|
|
unsigned long b1, b2, b3, b4;
|
|
|
|
b1 = ((((z1 << 6UL) & MASK) ^ z1) >> 13UL);
|
|
z1 = ((((z1 & 4294967294UL) << 18UL) & MASK) ^ b1);
|
|
|
|
b2 = ((((z2 << 2UL) & MASK) ^ z2) >> 27UL);
|
|
z2 = ((((z2 & 4294967288UL) << 2UL) & MASK) ^ b2);
|
|
|
|
b3 = ((((z3 << 13UL) & MASK) ^ z3) >> 21UL);
|
|
z3 = ((((z3 & 4294967280UL) << 7UL) & MASK) ^ b3);
|
|
|
|
b4 = ((((z4 << 3UL) & MASK) ^ z4) >> 12UL);
|
|
z4 = ((((z4 & 4294967168UL) << 13UL) & MASK) ^ b4);
|
|
|
|
return (z1 ^ z2 ^ z3 ^ z4);
|
|
};
|
|
|
|
// Returns float in range 0 : 1 (1 non-inclusive)
|
|
float getFloat()
|
|
{
|
|
return getInt() / 4294967296.0f;
|
|
};
|
|
|
|
void save()
|
|
{
|
|
save_z1 = z1;
|
|
save_z2 = z2;
|
|
save_z3 = z3;
|
|
save_z4 = z4;
|
|
};
|
|
|
|
void restore()
|
|
{
|
|
z1 = save_z1;
|
|
z2 = save_z2;
|
|
z3 = save_z3;
|
|
z4 = save_z4;
|
|
};
|
|
|
|
// Returns random seed based on time() and SDL_GetTicks() functions
|
|
static unsigned long getRandomSeed();
|
|
|
|
private:
|
|
|
|
static const unsigned long MASK = 0xffffffffUL;
|
|
unsigned long LCG(unsigned long n) { return ((69069UL * n) & MASK); };
|
|
|
|
unsigned long z1, z2, z3, z4;
|
|
|
|
unsigned long save_z1, save_z2, save_z3, save_z4;
|
|
};
|
|
|
|
|
|
#endif // __MATHLIB_H__
|