177 lines
3.4 KiB
C++
177 lines
3.4 KiB
C++
#ifndef GOMEZ_Vector_H
|
||
#define GOMEZ_Vector_H
|
||
#include <cmath>
|
||
/**
|
||
* Taken from:
|
||
* http://www.gamasutra.com/features/19990702/data_structures_01.htm
|
||
* http://www.gamasutra.com/features/19991018/Gomez_1.htm
|
||
*
|
||
* Both by Miguel Gomez
|
||
*/
|
||
|
||
namespace GomezMath {
|
||
|
||
// A floating point number
|
||
//
|
||
typedef float Scalar;
|
||
|
||
//
|
||
// A 3D vector
|
||
//
|
||
class Vector
|
||
{
|
||
public:
|
||
Scalar x, y, z; //x,y,z coordinates
|
||
public:
|
||
Vector ():x (0), y (0), z (0)
|
||
{
|
||
}
|
||
Vector (const Scalar & a, const Scalar & b, const Scalar & c):x (a), y (b),
|
||
z (c)
|
||
{
|
||
}
|
||
//index a component
|
||
//NOTE: returning a reference allows
|
||
//you to assign the indexed element
|
||
Scalar & operator [](const long i)
|
||
{
|
||
return *((&x) + i);
|
||
}
|
||
//compare
|
||
const bool operator == (const Vector & v) const
|
||
{
|
||
return (v.x == x && v.y == y && v.z == z);
|
||
}
|
||
const bool operator != (const Vector & v) const
|
||
{
|
||
return !(v == *this);
|
||
}
|
||
//negate
|
||
const Vector operator - () const
|
||
{
|
||
return Vector (-x, -y, -z);
|
||
}
|
||
//assign
|
||
const Vector & operator = (const Vector & v)
|
||
{
|
||
x = v.x;
|
||
y = v.y;
|
||
z = v.z;
|
||
return *this;
|
||
}
|
||
//increment
|
||
const Vector & operator += (const Vector & v)
|
||
{
|
||
x += v.x;
|
||
y += v.y;
|
||
z += v.z;
|
||
return *this;
|
||
}
|
||
//decrement
|
||
const Vector & operator -= (const Vector & v)
|
||
{
|
||
x -= v.x;
|
||
y -= v.y;
|
||
z -= v.z;
|
||
return *this;
|
||
}
|
||
//self-multiply
|
||
const Vector & operator *= (const Scalar & s)
|
||
{
|
||
x *= s;
|
||
y *= s;
|
||
z *= s;
|
||
return *this;
|
||
}
|
||
//self-divide
|
||
const Vector & operator /= (const Scalar & s)
|
||
{
|
||
const Scalar r = 1 / s;
|
||
x *= r;
|
||
y *= r;
|
||
z *= r;
|
||
return *this;
|
||
}
|
||
//add
|
||
const Vector operator + (const Vector & v) const
|
||
{
|
||
return Vector (x + v.x, y + v.y, z + v.z);
|
||
}
|
||
//subtract
|
||
const Vector operator - (const Vector & v) const
|
||
{
|
||
return Vector (x - v.x, y - v.y, z - v.z);
|
||
}
|
||
//post-multiply by a scalar
|
||
const Vector operator * (const Scalar & s) const
|
||
{
|
||
return Vector (x * s, y * s, z * s);
|
||
}
|
||
//pre-multiply by a scalar
|
||
friend inline const Vector operator * (const Scalar & s, const Vector & v)
|
||
{
|
||
return v * s;
|
||
}
|
||
//divide
|
||
const Vector operator / (Scalar s) const
|
||
{
|
||
s = 1 / s;
|
||
return Vector (s * x, s * y, s * z);
|
||
}
|
||
//cross product
|
||
const Vector cross (const Vector & v) const
|
||
{
|
||
//Davis, Snider, "Introduction to Vector Analysis", p. 44
|
||
return Vector (y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
|
||
}
|
||
//scalar dot product
|
||
const Scalar dot (const Vector & v) const
|
||
{
|
||
return x * v.x + y * v.y + z * v.z;
|
||
}
|
||
//length
|
||
const Scalar length () const
|
||
{
|
||
return (Scalar) sqrt ((double) this->dot (*this));
|
||
}
|
||
//unit vector
|
||
const Vector unit () const
|
||
{
|
||
return (*this) / length ();
|
||
}
|
||
//make this a unit vector
|
||
void normalize ()
|
||
{
|
||
(*this) /= length ();
|
||
}
|
||
//equal within an error ‘e’
|
||
const bool nearlyEquals (const Vector & v, const Scalar e) const
|
||
{
|
||
return fabs (x - v.x) < e && fabs (y - v.y) < e && fabs (z - v.z) < e;
|
||
}
|
||
|
||
// component-wise maximum
|
||
const Vector max(const Vector & other) const {
|
||
Vector _res;
|
||
_res.x = (x > other.x) ? x : other.x;
|
||
_res.y = (y > other.y) ? y : other.y;
|
||
_res.z = (z > other.x) ? z : other.z;
|
||
return _res;
|
||
}
|
||
|
||
const Vector abs() const {
|
||
Vector _res;
|
||
_res.x = (x >= 0) ? x : -x;
|
||
_res.y = (y >= 0) ? y : -y;
|
||
_res.z = (z >= 0) ? z : -z;
|
||
return _res;
|
||
}
|
||
};
|
||
//
|
||
// A 3D position
|
||
//
|
||
typedef Vector Point;
|
||
|
||
}
|
||
#endif
|