MFC实现三维图像绘制(1)仿射变换

进行三维图形绘制的第一步是物体建模,考虑到物体的运动(仿射变换),三维物体到二维平面的的投影(投影变换)和物体本身的建模(建立点表和面表),这里先进行物体的仿射变换。

通过三维仿射变换实现物体的运动,由于物体的平移变换无法通过三维矩阵实现,所以这里通过四维矩阵来实现。

#pragma once
#include "P3.h"
#define PI 3.1415926//圆周率
#include "math.h"//数学头文件

class CModelTransform3
{
public:
	CModelTransform3(void);
	virtual ~CModelTransform3(void);
	void Identity(void);
	void SetMatrix(CP3* P, int ptNumber);//设置变换点
	void Translate(double tx, double ty, double tz);//平移变换
	void Scale(double sx, double sy, double sz);//缩放
	void Scale(double sx, double sy, double sz,CP3 p);//相对于任意点的缩放
	void Scale(double s);//整体缩放
	void Scale(double s, CP3 p);//相对于任意点的整体缩放
	void RotateX(double beta);//绕X轴旋转
	void RotateY(double beta);//绕Y轴旋转
	void RotateZ(double beta);//绕Z轴旋转
	void RotateX(double beta, CP3 p);//相对于任意点绕X轴旋转
	void RotateY(double beta, CP3 p);//相对于任意点绕Y轴旋转
	void RotateZ(double beta, CP3 p);//相对于任意点绕Z轴旋转
	void ReflectX(void);//关于X轴反射变换
	void ReflectY(void); //关于Y轴反射变换
	void ReflectZ(void);//关于Z轴反射变换
	void ReflectXOY(void);//关于XOY面反射变换
	void ReflectYOZ(void);//关于YOZ面反射变换
	void ReflectZOX(void);//关于ZOX面反射变换
	void ShearX(double b, double c);//沿X方向错切变换
	void ShearY(double d, double f);//沿Y方向错切变换
	void ShearZ(double g, double h);//沿Z方向错切变换
	void MultiplyMatrix(void);
private:
	double M[4][4];//三维变换矩阵
	CP3* P;//三维顶点数组名
	int ptNumber;//三位顶点个数
};

具体代码实现如下

#include "pch.h"
#include "ModelTransform3.h"

CModelTransform3::CModelTransform3(void) {

}

CModelTransform3::~CModelTransform3(void) {

}

void CModelTransform3::Identity(void) {
	M[0][0] = 1.0;M[0][1] = 0.0;M[0][2] = 0.0;M[0][3] = 0.0;
	M[1][0] = 0.0;M[1][1] = 1.0;M[1][2] = 0.0;M[1][3] = 0.0;
	M[2][0] = 0.0;M[2][1] = 0.0;M[2][2] = 1.0;M[2][3] = 0.0;
	M[3][0] = 0.0;M[3][1] = 0.0;M[3][2] = 0.0;M[3][3] = 1.0;
}

void CModelTransform3::SetMatrix(CP3* P, int ptNumber)
{
	// TODO: 在此处添加实现代码.
	this->P = P;
	this->ptNumber = ptNumber;
}


void CModelTransform3::Translate(double tx, double ty, double tz)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[0][3] = tx, M[1][3] = ty, M[2][3] = tz;
	MultiplyMatrix();
}


void CModelTransform3::Scale(double sx, double sy, double sz)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[0][0] = sx, M[1][1] = sy, M[2][2] = sz;
	MultiplyMatrix();
}

void CModelTransform3::Scale(double sx, double sy, double sz,CP3 p)
{
	// TODO: 在此处添加实现代码.
	Translate(-p.x, -p.y, -p.z);
	Scale(sx, sy, sz);
	Translate(p.x, p.y, p.z);
}

void CModelTransform3::Scale(double s)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[0][0] = s, M[1][1] = s, M[2][2] = s;
	MultiplyMatrix();
}

void CModelTransform3::Scale(double s, CP3 p)
{
	// TODO: 在此处添加实现代码.
	Translate(p.x, p.y, p.z);
	Scale(s);
	Translate(p.x, p.y, p.z);
}

void CModelTransform3::RotateX(double beta)
{
	// TODO: 在此处添加实现代码.
	Identity();
	beta = beta * PI / 180;
	M[1][1] = cos(beta), M[1][2] = -sin(beta);
	M[2][1] = sin(beta), M[2][2] = cos(beta);
	MultiplyMatrix();
}


void CModelTransform3::RotateY(double beta)
{
	// TODO: 在此处添加实现代码.
	Identity();
	beta = beta * PI / 180;
	M[0][0] = cos(beta), M[0][2] = sin(beta);
	M[2][0] = -sin(beta), M[2][2] = cos(beta);
	MultiplyMatrix();
}


void CModelTransform3::RotateZ(double beta)
{
	// TODO: 在此处添加实现代码.
	Identity();
	beta = beta * PI / 180;
	M[0][0] = cos(beta), M[0][1] = -sin(beta);
	M[1][0] = sin(beta), M[1][1] = cos(beta);
	MultiplyMatrix();
}

void CModelTransform3::RotateX(double beta, CP3 p)
{
	// TODO: 在此处添加实现代码.
	Translate(-p.x, -p.y, -p.z);
	RotateX(beta);
	Translate(p.x, p.y, p.z);
}


void CModelTransform3::RotateY(double beta, CP3 p)
{
	// TODO: 在此处添加实现代码.
	Translate(-p.x, -p.y, -p.z);
	RotateY(beta);
	Translate(p.x, p.y, p.z);
}


void CModelTransform3::RotateZ(double beta, CP3 p)
{
	// TODO: 在此处添加实现代码.
	Translate(-p.x, -p.y, -p.z);
	RotateZ(beta);
	Translate(p.x, p.y, p.z);
}


void CModelTransform3::ReflectX(void)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[1][1] = -1, M[2][2] = -1;
	MultiplyMatrix();
}


void CModelTransform3::ReflectY(void)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[0][0] = -1, M[2][2] = -1;
	MultiplyMatrix();
}


void CModelTransform3::ReflectZ(void)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[1][1] = -1, M[0][0] = -1;
	MultiplyMatrix();
}


void CModelTransform3::ReflectXOY(void)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[2][2] = -1;
	MultiplyMatrix();
}


void CModelTransform3::ReflectYOZ(void)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[0][0] = -1;
	MultiplyMatrix();
}


void CModelTransform3::ReflectZOX(void)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[1][1] = -1;
	MultiplyMatrix();
}


void CModelTransform3::ShearX(double b, double c)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[0][1] = b, M[0][2] = c;
	MultiplyMatrix();
}


void CModelTransform3::ShearY(double d, double f)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[1][0] = d, M[1][2] = f;
	MultiplyMatrix();
}


void CModelTransform3::ShearZ(double g, double h)
{
	// TODO: 在此处添加实现代码.
	Identity();
	M[2][0] = g, M[2][0] = h;
	MultiplyMatrix();
}


void CModelTransform3::MultiplyMatrix(void)
{
	// TODO: 在此处添加实现代码.
	CP3* PTemp = new CP3[ptNumber];
	for (int i = 0;i < ptNumber;i++)
		PTemp[i] = P[i];
	for (int i = 0;i < ptNumber;i++) {
		P[i].x = M[0][0] * PTemp[i].x + M[0][1] * PTemp[i].y + M[0][2] * PTemp[i].z + M[0][3] * PTemp[i].w;
		P[i].y = M[1][0] * PTemp[i].x + M[1][1] * PTemp[i].y + M[1][2] * PTemp[i].z + M[1][3] * PTemp[i].w;
		P[i].z = M[2][0] * PTemp[i].x + M[2][1] * PTemp[i].y + M[2][2] * PTemp[i].z + M[2][3] * PTemp[i].w;
		P[i].w = M[3][0] * PTemp[i].x + M[3][1] * PTemp[i].y + M[3][2] * PTemp[i].z + M[3][3] * PTemp[i].w;
	}
	delete[] PTemp;
}

    原文作者:仿生葡萄
    原文地址: https://blog.csdn.net/uchiha_rin/article/details/122131287
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞