115 lines
2.4 KiB
C++
115 lines
2.4 KiB
C++
#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) //don’t 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) //don’t 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) //don’t rotate by 0
|
||
{
|
||
//don’t 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
|