OpenGTA/math/basis.hpp

115 lines
2.4 KiB
C++
Raw Permalink Normal View History

2015-12-03 00:37:02 +00:00
#ifndef GOMEZ_Basis_H
#define GOMEZ_Basis_H
/**
* 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
*/
#include "matrix.hpp"
namespace GomezMath {
// An orthonormal basis with respect to a parent
//
class Basis
{
public:
Matrix R;
public:
Basis ()
{
}
Basis (const Vector & v0,
const Vector & v1, const Vector & v2):R (v0, v1, v2)
{
}
Basis (const Matrix & m):R (m)
{
}
const Vector & operator [] (long i) const
{
return R.C[i];
}
const Vector & x () const
{
return R.C[0];
}
const Vector & y () const
{
return R.C[1];
}
const Vector & z () const
{
return R.C[2];
}
const Matrix & basis () const
{
return R;
}
void basis (const Vector & v0, const Vector & v1, const Vector & v2)
{
this->R[0] = v0;
this->R[1] = v1;
this->R[2] = v2;
}
// Right-Handed Rotations
void rotateAboutX (const Scalar & a)
{
if (0 != a) //dont rotate by 0
{
Vector b1 = this->y () * cos (a) + this->z () * sin (a);
Vector b2 = -this->y () * sin (a) + this->z () * cos (a);
//set basis
this->R[1] = b1;
this->R[2] = b2;
//x is unchanged
}
}
void rotateAboutY (const Scalar & a)
{
if (0 != a) //dont rotate by 0
{
Vector b2 = this->z () * cos (a) + this->x () * sin (a); //rotate z
Vector b0 = -this->z () * sin (a) + this->x () * cos (a); //rotate x
//set basis
this->R[2] = b2;
this->R[0] = b0;
//y is unchanged
}
}
void rotateAboutZ (const Scalar & a)
{
if (0 != a) //dont rotate by 0
{
//dont over-write basis before calculation is done
Vector b0 = this->x () * cos (a) + this->y () * sin (a); //rotate x
Vector b1 = -this->x () * sin (a) + this->y () * cos (a); //rotate y
//set basis
this->R[0] = b0;
this->R[1] = b1;
//z is unchanged
}
}
//rotate the basis about the unit axis u by theta (radians)
void rotate (const Scalar & theta, const Vector & u);
//rotate, length of da is theta, unit direction of da is u
void rotate (const Vector & da);
// Transformations
const Vector transformVectorToLocal (const Vector & v) const
{
return Vector (R.C[0].dot (v), R.C[1].dot (v), R.C[2].dot (v));
}
const Point transformVectorToParent (const Vector & v) const
{
return R.C[0] * v.x + R.C[1] * v.y + R.C[2] * v.z;
}
};
}
#endif