📄 _matrix33.h
字号:
#ifndef _MATRIX33_H
#define _MATRIX33_H
//------------------------------------------------------------------------------
/**
A generic matrix33 class.
@author
- RadonLabs GmbH
@since
- 2005.7.06
@remarks
- 瘤肯 眠啊
*/
#include "_vector3.h"
#include "quaternion.h"
#include "euler.h"
#include "matrixdefs.h"
#include <memory.h>
static float _matrix33_ident[9] =
{
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
};
//------------------------------------------------------------------------------
class _matrix33
{
public:
/// constructor 1
_matrix33();
/// constructor 2
_matrix33(const _vector3& v0, const _vector3& v1, const _vector3& v2);
/// constructor 3
_matrix33(const _matrix33& mx);
/// constructor 4
_matrix33(float _m11, float _m12, float _m13, float _m21, float _m22, float _m23, float _m31, float _m32, float _m33);
/// constructor 5
_matrix33(const quaternion& q);
/// get as quaternion
quaternion get_quaternion() const;
/// get as euler representation
_vector3 to_euler() const;
/// set as euler
void from_euler(const _vector3& ea);
/// unrestricted lookat
void lookat(const _vector3& from, const _vector3& to, const _vector3& up);
/// restricted lookat (billboard)
void billboard(const _vector3& from, const _vector3& to, const _vector3& up);
/// set 1
void set(float m11, float m12, float m13, float m21, float m22, float m23, float m31, float m32, float m33);
/// set 2
void set(const _vector3& v0, const _vector3& v1, const _vector3& v2);
/// set 3
void set(const _matrix33& m1);
/// set to identity
void ident();
/// set to transpose
void transpose();
/// is orthonormal?
bool orthonorm(float limit);
/// scale
void scale(const _vector3& s);
/// rotate about global x
void rotate_x(const float a);
/// rotates matrix about global y
void rotate_y(const float a);
/// rotate about global z
void rotate_z(const float a);
/// rotate about local x (not very fast)
void rotate_local_x(const float a);
/// rotate about local y (not very fast)
void rotate_local_y(const float a);
/// rotate about local z (not very fast)
void rotate_local_z(const float a);
/// rotate about any axis
void rotate(const _vector3& vec, float a);
/// get x component
_vector3 x_component(void) const;
/// get y component
_vector3 y_component(void) const;
/// get z component
_vector3 z_component(void) const;
// inplace matrix multiply
void operator *= (const _matrix33& m1);
/// multiply source vector into target vector
void mult(const _vector3& src, _vector3& dst) const;
/// translate, this treats the matrix as a 2x2 rotation + translate matrix
void translate(const _vector2& t);
float m[3][3];
};
//------------------------------------------------------------------------------
/**
*/
static
inline
_matrix33
operator * (const _matrix33& m0, const _matrix33& m1)
{
_matrix33 m2(
m0.m[0][0]*m1.m[0][0] + m0.m[0][1]*m1.m[1][0] + m0.m[0][2]*m1.m[2][0],
m0.m[0][0]*m1.m[0][1] + m0.m[0][1]*m1.m[1][1] + m0.m[0][2]*m1.m[2][1],
m0.m[0][0]*m1.m[0][2] + m0.m[0][1]*m1.m[1][2] + m0.m[0][2]*m1.m[2][2],
m0.m[1][0]*m1.m[0][0] + m0.m[1][1]*m1.m[1][0] + m0.m[1][2]*m1.m[2][0],
m0.m[1][0]*m1.m[0][1] + m0.m[1][1]*m1.m[1][1] + m0.m[1][2]*m1.m[2][1],
m0.m[1][0]*m1.m[0][2] + m0.m[1][1]*m1.m[1][2] + m0.m[1][2]*m1.m[2][2],
m0.m[2][0]*m1.m[0][0] + m0.m[2][1]*m1.m[1][0] + m0.m[2][2]*m1.m[2][0],
m0.m[2][0]*m1.m[0][1] + m0.m[2][1]*m1.m[1][1] + m0.m[2][2]*m1.m[2][1],
m0.m[2][0]*m1.m[0][2] + m0.m[2][1]*m1.m[1][2] + m0.m[2][2]*m1.m[2][2]
);
return m2;
}
//------------------------------------------------------------------------------
/**
*/
static
inline
_vector3 operator * (const _matrix33& m, const _vector3& v)
{
return _vector3(
m.M11*v.x + m.M21*v.y + m.M31*v.z,
m.M12*v.x + m.M22*v.y + m.M32*v.z,
m.M13*v.x + m.M23*v.y + m.M33*v.z);
};
//------------------------------------------------------------------------------
/**
*/
inline
_matrix33::_matrix33()
{
memcpy(&(m[0][0]), _matrix33_ident, sizeof(_matrix33_ident));
}
//------------------------------------------------------------------------------
/**
*/
inline
_matrix33::_matrix33(const _vector3& v0, const _vector3& v1, const _vector3& v2)
{
M11=v0.x; M12=v0.y; M13=v0.z;
M21=v1.x; M22=v1.y; M23=v1.z;
M31=v2.x; M32=v2.y; M33=v2.z;
}
//------------------------------------------------------------------------------
/**
*/
inline
_matrix33::_matrix33(const _matrix33& m1)
{
memcpy(m, &(m1.m[0][0]), 9*sizeof(float));
}
//------------------------------------------------------------------------------
/**
*/
inline
_matrix33::_matrix33(float _m11, float _m12, float _m13,
float _m21, float _m22, float _m23,
float _m31, float _m32, float _m33)
{
M11=_m11; M12=_m12; M13=_m13;
M21=_m21; M22=_m22; M23=_m23;
M31=_m31; M32=_m32; M33=_m33;
}
//------------------------------------------------------------------------------
/**
*/
inline
_matrix33::_matrix33(const quaternion& q)
{
float xx = q.x*q.x; float yy = q.y*q.y; float zz = q.z*q.z;
float xy = q.x*q.y; float xz = q.x*q.z; float yz = q.y*q.z;
float wx = q.w*q.x; float wy = q.w*q.y; float wz = q.w*q.z;
m[0][0] = 1.0f - 2.0f * (yy + zz);
m[1][0] = 2.0f * (xy - wz);
m[2][0] = 2.0f * (xz + wy);
m[0][1] = 2.0f * (xy + wz);
m[1][1] = 1.0f - 2.0f * (xx + zz);
m[2][1] = 2.0f * (yz - wx);
m[0][2] = 2.0f * (xz - wy);
m[1][2] = 2.0f * (yz + wx);
m[2][2] = 1.0f - 2.0f * (xx + yy);
}
//------------------------------------------------------------------------------
/**
*/
inline
quaternion
_matrix33::get_quaternion() const
{
float qa[4];
float tr = m[0][0] + m[1][1] + m[2][2];
if (tr > 0.0f)
{
float s = n_sqrt (tr + 1.0f);
qa[3] = s * 0.5f;
s = 0.5f / s;
qa[0] = (m[1][2] - m[2][1]) * s;
qa[1] = (m[2][0] - m[0][2]) * s;
qa[2] = (m[0][1] - m[1][0]) * s;
}
else
{
int i, j, k, nxt[3] = {1,2,0};
i = 0;
if (m[1][1] > m[0][0]) i=1;
if (m[2][2] > m[i][i]) i=2;
j = nxt[i];
k = nxt[j];
float s = n_sqrt((m[i][i] - (m[j][j] + m[k][k])) + 1.0f);
qa[i] = s * 0.5f;
s = 0.5f / s;
qa[3] = (m[j][k] - m[k][j])* s;
qa[j] = (m[i][j] + m[j][i]) * s;
qa[k] = (m[i][k] + m[k][i]) * s;
}
quaternion q(qa[0],qa[1],qa[2],qa[3]);
return q;
}
//------------------------------------------------------------------------------
/**
*/
inline
_vector3
_matrix33::to_euler() const
{
_vector3 ea;
// work on matrix with flipped row/columns
_matrix33 tmp(*this);
tmp.transpose();
int i,j,k,h,n,s,f;
EulGetOrd(EulOrdXYZs,i,j,k,h,n,s,f);
if (s==EulRepYes)
{
double sy = (float) sqrt(tmp.M12 * tmp.M12 + tmp.M13 * tmp.M13);
if (sy > 16*FLT_EPSILON)
{
ea.x = (float) atan2(tmp.M12, tmp.M13);
ea.y = (float) atan2((float)sy, tmp.M11);
ea.z = (float) atan2(tmp.M21, -tmp.M31);
} else {
ea.x = (float) atan2(-tmp.M23, tmp.M22);
ea.y = (float) atan2((float)sy, tmp.M11);
ea.z = 0;
}
}
else
{
double cy = sqrt(tmp.M11 * tmp.M11 + tmp.M21 * tmp.M21);
if (cy > 16*FLT_EPSILON)
{
ea.x = (float) atan2(tmp.M32, tmp.M33);
ea.y = (float) atan2(-tmp.M31, (float)cy);
ea.z = (float) atan2(tmp.M21, tmp.M11);
}
else
{
ea.x = (float) atan2(-tmp.M23, tmp.M22);
ea.y = (float) atan2(-tmp.M31, (float)cy);
ea.z = 0;
}
}
if (n==EulParOdd) {ea.x = -ea.x; ea.y = - ea.y; ea.z = -ea.z;}
if (f==EulFrmR) {float t = ea.x; ea.x = ea.z; ea.z = t;}
return ea;
}
//------------------------------------------------------------------------------
/**
*/
inline
void
_matrix33::from_euler(const _vector3& ea)
{
_vector3 tea = ea;
double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
int i,j,k,h,n,s,f;
EulGetOrd(EulOrdXYZs,i,j,k,h,n,s,f);
if (f==EulFrmR) {float t = ea.x; tea.x = ea.z; tea.z = t;}
if (n==EulParOdd) {tea.x = -ea.x; tea.y = -ea.y; tea.z = -ea.z;}
ti = tea.x; tj = tea.y; th = tea.z;
ci = cos(ti); cj = cos(tj); ch = cos(th);
si = sin(ti); sj = sin(tj); sh = sin(th);
cc = ci*ch; cs = ci*sh; sc = si*ch; ss = si*sh;
if (s==EulRepYes)
{
M11 = (float)(cj); M12 = (float)(sj*si); M13 = (float)(sj*ci);
M21 = (float)(sj*sh); M22 = (float)(-cj*ss+cc); M23 = (float)(-cj*cs-sc);
M31 = (float)(-sj*ch); M23 = (float)( cj*sc+cs); M33 = (float)( cj*cc-ss);
}
else
{
M11 = (float)(cj*ch); M12 = (float)(sj*sc-cs); M13 = (float)(sj*cc+ss);
M21 = (float)(cj*sh); M22 = (float)(sj*ss+cc); M23 = (float)(sj*cs-sc);
M31 = (float)(-sj); M32 = (float)(cj*si); M33 = (float)(cj*ci);
}
// flip row/column
this->transpose();
}
//------------------------------------------------------------------------------
/**
*/
inline
void
_matrix33::lookat(const _vector3& from, const _vector3& to, const _vector3& up)
{
_vector3 z(from - to);
z.norm();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -