Blame projects/asteroid/geometry.h

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