⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 matrix3d.cpp

📁 计算机图形学原理及算法教程(VC++版)程序代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////////
//	
// 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 + -