📄 matrix3d.cpp
字号:
/////////////////////////////////////////////////////////////////////////////////
//
// Matrix3d.cpp: implementation of the CMatrix3d class.
//
#include "stdafx.h"
#include "Matrix3d.h"
#include "math.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMatrix3d::CMatrix3d()
{
Identity();
}
CMatrix3d::~CMatrix3d()
{}
//单位矩阵
void CMatrix3d::Identity()
{
a[0][0] = 1.0f; a[0][1] = 0.0f; a[0][2] = 0.0f; a[0][3] = 0.0f;
a[1][0] = 0.0f; a[1][1] = 1.0f; a[1][2] = 0.0f; a[1][3] = 0.0f;
a[2][0] = 0.0f; a[2][1] = 0.0f; a[2][2] = 1.0f; a[2][3] = 0.0f;
a[3][0] = 0.0f; a[3][1] = 0.0f; a[3][2] = 0.0f; a[3][3] = 1.0f;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//
// 运算符重载
//
//////////////////////////////////////////////////////////////////////////////////////////////
//重载"="运算符(置换)
CMatrix3d CMatrix3d::operator = (const CMatrix3d& m)
{
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
a[i][j] = m.a[i][j];
return *this;
}
//重载"=="运算符
BOOL CMatrix3d::operator == (const CMatrix3d& m)
{
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
if(ABS(a[i][j] - m.a[i][j]) > 0.0001f)
return FALSE;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////////////////////
//
// 设置与获取
//
//////////////////////////////////////////////////////////////////////////////////////////////
//设置变换矩阵(置换)
void CMatrix3d::Set(const float* pfMatrix)
{
for(int i = 0;i < 4;i++)
for(int j = 0;j < 4;j++)
a[i][j] = pfMatrix[ (4 * i + j) ];
}
//获取变换矩阵
void CMatrix3d::Get(float* pfMatrix) const
{
ASSERT(pfMatrix);
for(int i = 0;i < 4;i++)
for(int j = 0;j < 4;j++)
pfMatrix[ (4 * i + j) ] = a[i][j];
}
//////////////////////////////////////////////////////////////////////////////////////////////
//
// 计算机图形学几何线性变换
//
//////////////////////////////////////////////////////////////////////////////////////////////
//齐次坐标变换矩阵
//平移变换, 平移量(x, y, z)
void CMatrix3d::Translate(float x, float y, float z)
{
a[3][0] += x;
a[3][1] += y;
a[3][2] += z;
}
//缩放变换
//fsx, fsy, fsz----为缩放因子
//在应用时, 要特别注意, 它只改变主对角线上的元素
//因而, 多用于第一次变换
void CMatrix3d::Scale(float fs)
{
a[0][0] *= fs;
a[1][1] *= fs;
a[2][2] *= fs;
}
//缩放变换
//fsx, fsy, fsz----为缩放因子
//在应用时, 要特别注意, 它只改变主对角线上的元素
//因而, 多用于第一次变换
void CMatrix3d::Scale(float fsx, float fsy, float fsz)
{
a[0][0] *= fsx;
a[1][1] *= fsy;
a[2][2] *= fsz;
}
//缩放变换
//fsx, fsy, fsz----为缩放因子
//x, y, z为缩放变换的参考点, 缺省设置为世界坐标系的坐标原点
void CMatrix3d::Scale(float fsx, float fsy, float fsz, float x, float y, float z)
{
CMatrix3d m;
m.a[0][0] = fsx;
m.a[1][1] = fsy;
m.a[2][2] = fsz;
m.a[3][0] = (1- fsx) * x;
m.a[3][1] = (1- fsy) * y;
m.a[3][2] = (1- fsz) * z;
//矩阵右乘
this->Multiply(m, G3D_MATRIX_MULTIPLIER_POSTCONCAT);
}
//绕 x 轴旋转
//fTheta为角度单位, 参考点为坐标原点
void CMatrix3d::RotateX(float fTheta)
{
//将角度转化为弧度
float fRad = (float)((fTheta * PIE) / 180.0);
CMatrix3d m;
m.a[1][1] = (float)cos(fRad);
m.a[1][2] = (float)sin(fRad);
m.a[2][1] = -m.a[1][2];
m.a[2][2] = m.a[1][1];
//矩阵右乘
this->Multiply(m, G3D_MATRIX_MULTIPLIER_POSTCONCAT);
}
//绕 x 轴旋转
//fTheta为角度单位, 参考点为坐标(x, y, z)
void CMatrix3d::RotateX(float fTheta, float x, float y, float z)
{
//矩阵乘法满足结合律
this->Translate(-x, -y, -z);
this->RotateX(fTheta);
this->Translate(x, y, z);
}
//绕 y 轴旋转
//fTheta为角度单位, 参考点为坐标原点
void CMatrix3d::RotateY(float fTheta)
{
//将角度转化为弧度
float fRad = (float)((fTheta * PIE) / 180.0);
CMatrix3d m;
m.a[0][0] = (float)cos(fRad);
m.a[2][0] = (float)sin(fRad);
m.a[0][2] = -m.a[2][0];
m.a[2][2] = m.a[0][0];
//矩阵右乘
this->Multiply(m, G3D_MATRIX_MULTIPLIER_POSTCONCAT);
}
//绕 y 轴旋转
//fTheta为角度单位, 参考点为坐标(x, y, z)
void CMatrix3d::RotateY(float fTheta, float x, float y, float z)
{
this->Translate(-x, -y, -z);
this->RotateY(fTheta);
this->Translate(x, y, z);
}
//绕 z 轴旋转
//fTheta为角度单位, 参考点为坐标原点
void CMatrix3d::RotateZ(float fTheta)
{
//将角度转化为弧度
float fRad = (float)((fTheta * PIE) / 180.0);
CMatrix3d m;
m.a[0][0] = (float)cos(fRad);
m.a[0][1] = (float)sin(fRad);
m.a[1][0] = -m.a[0][1];
m.a[1][1] = m.a[0][0];
//矩阵右乘
this->Multiply(m, G3D_MATRIX_MULTIPLIER_POSTCONCAT);
}
//绕 z 轴旋转
//fTheta为角度单位, 参考点为坐标(x, y, z)
void CMatrix3d::RotateZ(float fTheta, float x, float y, float z)
{
this->Translate(-x, -y, -z);
this->RotateZ(fTheta);
this->Translate(x, y, z);
}
//绕任意轴(x, y, z)旋转角度fTheta, 轴过坐标原点
void CMatrix3d::Rotate(float fTheta, float x, float y, float z)
{
//将轴单位化
float fMag = (float)sqrt(x * x + y * y + z * z);
if(fMag < 0.0001f)
{
//轴变成坐标原点, 返回, 该次变换不对物体的几何位置产生影响
return;
}
//旋转轴的方向数,单位向量
float fx = (x / fMag), fy = (y / fMag), fz = (z / fMag);
//将角度转化为弧度
float fRad = (float)((fTheta * PIE) / 180.0);
//角度的正弦和余弦
float c = (float)cos(fRad);
float s = (float)sin(fRad);
//变换矩阵m
CMatrix3d m;
//多次变换的合成,参考相应的计算机图形学书籍
m.a[0][0] = fx * fx * (1.0f - c) + c;
m.a[0][1] = fx * fy * (1.0f - c) - fz * s;
m.a[0][2] = fx * fz * (1.0f - c) + fy * s;
m.a[1][0] = fy * fx * (1.0f - c) + fz * s;
m.a[1][1] = fy * fy * (1.0f - c) + c;
m.a[1][2] = fy * fz * (1.0f - c) - fx * s;
m.a[2][0] = fz * fx * (1.0f - c) - fy * s;
m.a[2][1] = fz * fy * (1.0f - c) + fx * s;
m.a[2][2] = fz * fz * (1.0f - c) + c;
//与原有变换进行合成
this->Multiply(m, G3D_MATRIX_MULTIPLIER_POSTCONCAT);
}
//旋转, 轴由方向axis和点ptOn定义
void CMatrix3d::Rotate(float fTheta, VECTOR3D axis, VERTEX3D ptOn)
{
this->Translate(-ptOn.x, -ptOn.y, -ptOn.z);
this->Rotate(fTheta, axis.x, axis.y, axis.z);
this->Translate(ptOn.x, ptOn.y, ptOn.z);
}
//相对 x 轴错切, 相对点为坐标原点
//使用公式: x1 = x0 , y1 = y0 + a * x0, z1 = z0 + b * x0
void CMatrix3d::SkewX(float fsy, float fsz)
{
CMatrix3d m;
m.a[0][1] = fsy; m.a[0][2] = fsz;
this->Multiply(m, G3D_MATRIX_MULTIPLIER_POSTCONCAT);
}
//相对 x 轴错切, 相对点为(x, y, z)
void CMatrix3d::SkewX(float fsy, float fsz, float x, float y, float z)
{
this->Translate(-x, -y, -z);
this->SkewX(fsy, fsz);
this->Translate(x, y, z);
}
//相对 y 轴错切, 相对点为坐标原点
//使用公式: x1 = x0 + a * y0, y1 = y0, z1 = z0 + b * y0
void CMatrix3d::SkewY(float fsx, float fsz)
{
CMatrix3d m;
m.a[1][0] = fsx; m.a[1][2] = fsz;
this->Multiply(m, G3D_MATRIX_MULTIPLIER_POSTCONCAT);
}
//相对 y 轴错切, 相对点为(x, y, z)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -