进行三维图形绘制的第一步是物体建模,考虑到物体的运动(仿射变换),三维物体到二维平面的的投影(投影变换)和物体本身的建模(建立点表和面表),这里先进行物体的仿射变换。
通过三维仿射变换实现物体的运动,由于物体的平移变换无法通过三维矩阵实现,所以这里通过四维矩阵来实现。
#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;
}