|
|
223ac6 |
|
|
|
223ac6 |
#ifndef GEOMETRY_H
|
|
|
223ac6 |
#define GEOMETRY_H
|
|
|
223ac6 |
|
|
|
223ac6 |
|
|
|
223ac6 |
#include <cmath></cmath>
|
|
|
223ac6 |
|
|
|
223ac6 |
|
|
|
223ac6 |
typedef double Real;
|
|
|
223ac6 |
|
|
|
223ac6 |
const Real precision = 1e-10;
|
|
|
223ac6 |
const Real pi = 3.14159265358979323846;
|
|
|
223ac6 |
const Real sqrt2 = 0.7071067811865475244;
|
|
|
223ac6 |
|
|
|
223ac6 |
inline int solve(Real* roots, Real k0, Real k1) {
|
|
|
223ac6 |
if (fabs(k1) <= precision) return 0;
|
|
|
223ac6 |
if (roots) roots[0] = -k0/k1;
|
|
|
223ac6 |
return 1;
|
|
|
223ac6 |
}
|
|
|
223ac6 |
|
|
|
223ac6 |
inline int solve(Real* roots, Real k0, Real k1, Real k2) {
|
|
|
223ac6 |
if (fabs(k2) <= precision*precision) return solve(roots, k0, k1);
|
|
|
223ac6 |
Real D = k1*k1 - 4*k2*k0;
|
|
|
223ac6 |
if (fabs(D) <= precision*precision) {
|
|
|
223ac6 |
if (roots) roots[0] = -0.5*k1/k2;
|
|
|
223ac6 |
return 1;
|
|
|
223ac6 |
} else
|
|
|
223ac6 |
if (D > 0) {
|
|
|
223ac6 |
if (roots) {
|
|
|
223ac6 |
Real a = sqrt(D);
|
|
|
223ac6 |
Real b = -0.5/k2;
|
|
|
223ac6 |
roots[0] = (k1 - a)*b;
|
|
|
223ac6 |
roots[1] = (k1 + a)*b;
|
|
|
223ac6 |
}
|
|
|
223ac6 |
return 2;
|
|
|
223ac6 |
}
|
|
|
223ac6 |
return 0;
|
|
|
223ac6 |
}
|
|
|
223ac6 |
|
|
|
223ac6 |
|
|
|
223ac6 |
inline Real sign(Real x, Real precision) {
|
|
|
223ac6 |
return x < -precision ? -1
|
|
|
223ac6 |
: x > precision ? 1
|
|
|
223ac6 |
: 0;
|
|
|
223ac6 |
}
|
|
|
223ac6 |
|
|
|
223ac6 |
|
|
|
223ac6 |
Real real_random();
|
|
|
223ac6 |
|
|
|
223ac6 |
inline Real real_random2()
|
|
|
223ac6 |
{ return real_random()*2 - 1; }
|
|
|
223ac6 |
inline Real real_random_normal()
|
|
|
223ac6 |
{ return sqrt(-2*log(real_random())) * sin(2*pi*real_random()); }
|
|
|
223ac6 |
|
|
|
223ac6 |
|
|
|
223ac6 |
class Vector2 {
|
|
|
223ac6 |
public:
|
|
|
223ac6 |
union {
|
|
|
223ac6 |
struct { Real x, y; };
|
|
|
223ac6 |
struct { Real c[2]; };
|
|
|
223ac6 |
};
|
|
|
223ac6 |
|
|
|
223ac6 |
explicit Vector2(Real x = 0, Real y = 0):
|
|
|
223ac6 |
x(x), y(y) { }
|
|
|
223ac6 |
|
|
|
223ac6 |
Real len_sqr() const { return x*x + y*y; }
|
|
|
223ac6 |
Real len() const { return sqrt(len_sqr()); }
|
|
|
223ac6 |
};
|
|
|
223ac6 |
|
|
|
223ac6 |
|
|
|
223ac6 |
class Vector3 {
|
|
|
223ac6 |
public:
|
|
|
223ac6 |
union {
|
|
|
223ac6 |
struct { Real x, y, z; };
|
|
|
223ac6 |
struct { Real r, g, b; };
|
|
|
223ac6 |
struct { Real c[3]; };
|
|
|
223ac6 |
};
|
|
|
223ac6 |
|
|
|
223ac6 |
explicit Vector3(Real x = 0, Real y = 0, Real z = 0):
|
|
|
223ac6 |
x(x), y(y), z(z) { }
|
|
|
223ac6 |
|
|
|
223ac6 |
Vector3 operator+(const Vector3 &v) const
|
|
|
223ac6 |
{ return Vector3(x+v.x, y+v.y, z+v.z); }
|
|
|
223ac6 |
Vector3 operator-(const Vector3 &v) const
|
|
|
223ac6 |
{ return Vector3(x-v.x, y-v.y, z-v.z); }
|
|
|
223ac6 |
|
|
|
223ac6 |
Real operator*(const Vector3 &v) const
|
|
|
223ac6 |
{ return x*v.x + y*v.y + z*v.z; }
|
|
|
223ac6 |
Vector3 operator*(Real k) const
|
|
|
223ac6 |
{ return Vector3(x*k, y*k, z*k); }
|
|
|
223ac6 |
Vector3 operator/(Real k) const
|
|
|
223ac6 |
{ return *this*(1/k); }
|
|
|
223ac6 |
|
|
|
223ac6 |
Vector3& operator+=(const Vector3 &v)
|
|
|
223ac6 |
{ return *this = *this + v; }
|
|
|
223ac6 |
Vector3& operator-=(const Vector3 &v)
|
|
|
223ac6 |
{ return *this = *this - v; }
|
|
|
223ac6 |
|
|
|
223ac6 |
Vector3 operator*=(Real k)
|
|
|
223ac6 |
{ return *this = *this*k; }
|
|
|
223ac6 |
Vector3 operator/=(Real k)
|
|
|
223ac6 |
{ return *this = *this/k; }
|
|
|
223ac6 |
|
|
|
223ac6 |
Vector3 cross(const Vector3 &v) const
|
|
|
223ac6 |
{ return Vector3(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x); }
|
|
|
223ac6 |
Vector3 perp() const
|
|
|
223ac6 |
{ return fabs(y) > fabs(x) ? Vector3(0, z, -y) : Vector3(-z, 0, x); }
|
|
|
223ac6 |
|
|
|
223ac6 |
Real len_sqr() const { return x*x + y*y + z*z; }
|
|
|
223ac6 |
Real len() const { return sqrt(len_sqr()); }
|
|
|
223ac6 |
|
|
|
223ac6 |
Vector3 norm() const
|
|
|
223ac6 |
{ Real l = len(); return l > precision ? *this/l : Vector3(); }
|
|
|
223ac6 |
};
|
|
|
223ac6 |
|
|
|
223ac6 |
|
|
|
223ac6 |
class Vector4 {
|
|
|
223ac6 |
public:
|
|
|
223ac6 |
union {
|
|
|
223ac6 |
struct { Real x, y, z, w; };
|
|
|
223ac6 |
struct { Real r, g, b, a; };
|
|
|
223ac6 |
struct { Real c[4]; };
|
|
|
223ac6 |
};
|
|
|
223ac6 |
|
|
|
223ac6 |
explicit Vector4(Real x = 0, Real y = 0, Real z = 0, Real w = 0):
|
|
|
223ac6 |
x(x), y(y), z(z), w(w) { }
|
|
|
223ac6 |
};
|
|
|
223ac6 |
|
|
|
223ac6 |
|
|
|
223ac6 |
class Matrix4 {
|
|
|
223ac6 |
public:
|
|
|
223ac6 |
union {
|
|
|
223ac6 |
struct {
|
|
|
223ac6 |
Real m00, m01, m02, m03,
|
|
|
223ac6 |
m10, m11, m12, m13,
|
|
|
223ac6 |
m20, m21, m22, m23,
|
|
|
223ac6 |
m30, m31, m32, m33;
|
|
|
223ac6 |
};
|
|
|
223ac6 |
struct { Real m[4][4]; };
|
|
|
223ac6 |
struct { Real a[16]; };
|
|
|
223ac6 |
};
|
|
|
223ac6 |
|
|
|
223ac6 |
explicit Matrix4(
|
|
|
223ac6 |
Real m00 = 1, Real m01 = 0, Real m02 = 0, Real m03 = 0,
|
|
|
223ac6 |
Real m10 = 0, Real m11 = 1, Real m12 = 0, Real m13 = 0,
|
|
|
223ac6 |
Real m20 = 0, Real m21 = 0, Real m22 = 1, Real m23 = 0,
|
|
|
223ac6 |
Real m30 = 0, Real m31 = 0, Real m32 = 0, Real m33 = 1
|
|
|
223ac6 |
):
|
|
|
223ac6 |
m00(m00), m01(m01), m02(m02), m03(m03),
|
|
|
223ac6 |
m10(m10), m11(m11), m12(m12), m13(m13),
|
|
|
223ac6 |
m20(m20), m21(m21), m22(m22), m23(m23),
|
|
|
223ac6 |
m30(m30), m31(m31), m32(m32), m33(m33)
|
|
|
223ac6 |
{ }
|
|
|
223ac6 |
|
|
|
223ac6 |
Vector4 operator*(const Vector4 &v) const {
|
|
|
223ac6 |
return Vector4(
|
|
|
223ac6 |
m00*v.x + m10*v.y + m20*v.z + m30*v.w,
|
|
|
223ac6 |
m01*v.x + m11*v.y + m21*v.z + m31*v.w,
|
|
|
223ac6 |
m02*v.x + m12*v.y + m22*v.z + m32*v.w,
|
|
|
223ac6 |
m03*v.x + m13*v.y + m23*v.z + m33*v.w );
|
|
|
223ac6 |
}
|
|
|
223ac6 |
|
|
|
223ac6 |
Vector3 transform(const Vector3 &v, Real w = 1) const {
|
|
|
223ac6 |
return Vector3(
|
|
|
223ac6 |
m00*v.x + m10*v.y + m20*v.z + m30*w,
|
|
|
223ac6 |
m01*v.x + m11*v.y + m21*v.z + m31*w,
|
|
|
223ac6 |
m02*v.x + m12*v.y + m22*v.z + m32*w );
|
|
|
223ac6 |
}
|
|
|
223ac6 |
|
|
|
223ac6 |
Matrix4 operator*(const Matrix4 &m) const;
|
|
|
223ac6 |
|
|
|
223ac6 |
Real det() const;
|
|
|
223ac6 |
Matrix4 inv() const;
|
|
|
223ac6 |
|
|
|
223ac6 |
static Matrix4 zero();
|
|
|
223ac6 |
static Matrix4 translation(const Vector3 &translate);
|
|
|
223ac6 |
static Matrix4 scaling(const Vector3 &scale);
|
|
|
223ac6 |
static Matrix4 rotation(const Vector3 &axis, Real angle);
|
|
|
223ac6 |
static Matrix4 perspective(Real fovy, Real aspect, Real z_near, Real z_far);
|
|
|
223ac6 |
};
|
|
|
223ac6 |
|
|
|
223ac6 |
#endif
|