Blame | Last modification | View Log | RSS feed
#include "Vec3f.h"
#include "Quaternion.h"
namespace CGLA {
void Quaternion::make_rot(float angle, const Vec3f& v)
{
angle = angle/2;
qv = CGLA::normalize(v);
qv *= sin(angle);
qw = cos(angle);
};
void Quaternion::make_rot(const Vec3f& _v0, const Vec3f& _v1)
{
Vec3f v0 = CGLA::normalize(_v0);
Vec3f v1 = CGLA::normalize(_v1);
qv = cross(v0, v1);
float l = qv.length();
if(l<TINY)
qv = Vec3f(1,0,0);
else
qv.normalize();
float a = acos(dot(v0,v1))/2;
qw = cos(a);
qv *= sin(a);
};
void Quaternion::get_rot(float& angle, Vec3f& v)
{
angle=2*acos(qw);
if (angle<TINY)
v = Vec3f(1,0,0);
else
v = qv / sin(angle);
if (angle>M_PI)
v = -v;
v.normalize();
}
Mat3x3f Quaternion::get_mat3x3f() const
{
float s=2/norm();
float m[9] = {1 - s*(qv[1]*qv[1]+qv[2]*qv[2]),
s*(qv[0]*qv[1]-qw*qv[2]),
s*(qv[0]*qv[2]+qw*qv[1]),
s*(qv[0]*qv[1]+qw*qv[2]),
1 - s*(qv[0]*qv[0]+qv[2]*qv[2]),
s*(qv[1]*qv[2]-qw*qv[0]),
s*(qv[0]*qv[2]-qw*qv[1]),
s*(qv[1]*qv[2]+qw*qv[0]),
1 - s*(qv[0]*qv[0]+qv[1]*qv[1])};
Mat3x3f mat;
mat.set(m);
return mat;
}
//This function just need to call the right initialiser
Mat4x4f Quaternion::get_mat4x4f() const
{
float s=2/norm();
float m[16] = {1 - s*(qv[1]*qv[1]+qv[2]*qv[2]),
s*(qv[0]*qv[1]-qw*qv[2]),
s*(qv[0]*qv[2]+qw*qv[1]),
float(0),
s*(qv[0]*qv[1]+qw*qv[2]),
1 - s*(qv[0]*qv[0]+qv[2]*qv[2]),
s*(qv[1]*qv[2]-qw*qv[0]),
float(0),
s*(qv[0]*qv[2]-qw*qv[1]),
s*(qv[1]*qv[2]+qw*qv[0]),
1 - s*(qv[0]*qv[0]+qv[1]*qv[1]),
float(0),
float(0),
float(0),
float(0),
float(1)};
Mat4x4f mat;
mat.set(m);
return mat;
}
Vec3f Quaternion::apply(const Vec3f& vec) const
{
return Vec3f((*this)*Quaternion(vec)*inverse());
}
}