本文是基于之前的三维变换三维变换完成的
首先需要添加一个向量类CVector
Vector.h
#pragma once
#include"P3.h"
#include<math.h>
class CVector
{
public:
CVector(void);
virtual ~CVector(void);
CVector(double x, double y, double z);
CVector(const CP3& p);
CVector(const CP3& p0,const CP3& p1);
double Magnitide(void);
CVector Normalize(void);
friend CVector operator + (const CVector& v0, const CVector& v1);
friend CVector operator - (const CVector& v0, const CVector& v1);
friend CVector operator * (const CVector& v, double scalar);
friend CVector operator * (double scalar, const CVector& v);
friend CVector operator / (const CVector& v0, double scalar);
friend double DotProduct(const CVector& v0, const CVector& v1);
friend CVector CrossProduct (const CVector& v0, const CVector& v1);
private:
double x, y, z;
};
Vector.app
#include "pch.h"
#include "Vector.h"
CVector::CVector(void)
{
x = 0.0, y = 0.0, z = 1.0;
}
CVector::~CVector(void)
{
}
CVector::CVector(double x, double y, double z)
{
this->x = x;
this->y = y;
this->z = z;
}
CVector::CVector(const CP3& p)
{
x = p.x;
y = p.y;
z = p.z;
}
CVector::CVector(const CP3& p0, const CP3& p1)
{
x = p1.x - p0.x;
y = p1.y - p0.y;
z = p1.z - p0.z;
}
double CVector::Magnitide(void)
{
return sqrt(x * x + y * y + z * z);
}
CVector CVector::Normalize(void)
{
CVector vector;
double magnitude = sqrt(x * x + y * y + z * z);
if (fabs(magnitude) < 1e-4) {
magnitude = 1.0;
}
vector.x = x / magnitude;
vector.y = y / magnitude;
vector.z = z / magnitude;
return vector;
}
CVector operator+(const CVector& v0, const CVector& v1)
{
CVector vector;
vector.x = v1.x + v0.x;
vector.y = v1.y + v0.y;
vector.z = v1.z + v0.z;
return vector;
}
CVector operator-(const CVector& v0, const CVector& v1)
{
CVector vector;
vector.x = v1.x - v0.x;
vector.y = v1.y - v0.y;
vector.z = v1.z - v0.z;
return vector;
}
CVector operator*(const CVector& v, double scalar)
{
CVector vector;
vector.x = v.x * scalar;
vector.y = v.y * scalar;
vector.z = v.z * scalar;
return vector;
}
CVector operator*(double scalar, const CVector& v)
{
CVector vector;
vector.x = v.x * scalar;
vector.y = v.y * scalar;
vector.z = v.z * scalar;
return vector;
}
CVector operator/(const CVector& v0, double scalar)
{
CVector vector;
vector.x = v0.x / scalar;
vector.y = v0.y / scalar;
vector.z = v0.z / scalar;
return vector;
}
double DotProduct(const CVector& v0, const CVector& v1)
{
return (v0.x * v1.x + v0.y * v1.y + v0.z * v1.z);
}
CVector CrossProduct(const CVector& v0, const CVector& v1)
{
CVector vector;
vector.x = v0.y * v1.z - v0.z * v1.y;
vector.y = v0.z * v1.x - v0.x * v1.z;
vector.z = v0.x * v1.y - v0.y * v1.x;
return vector;
}
在这之后我们将Vector.h导入Cube.h,然后加入私有变量 CP3 quardrP[4],并修改Cube.app中的三个Draw函数
void CCube::Draw(CDC* pDC)
{
CP2 ScreenPoint, temp;
CP3 ViewPoint = projection.EyePoint;
for (int nFacet = 0; nFacet < 6; nFacet++)
{
for (int i = 0; i < 4; i++) {
quardrP[i] = P[F[nFacet].Index[i]];
}
CVector ViewVector(quardrP[0], ViewPoint);
ViewVector = ViewVector.Normalize();
CVector Vector01(quardrP[0], quardrP[1]);
CVector Vector02(quardrP[0], quardrP[2]);
CVector Vector03(quardrP[0], quardrP[3]);
CVector FacetNormalA = CrossProduct(Vector01, Vector02);
CVector FacetNormalB = CrossProduct(Vector02, Vector03);
CVector FacetNormal = (FacetNormalA + FacetNormalB);
FacetNormal = FacetNormal.Normalize();
if (DotProduct(ViewVector, FacetNormal) >= 0) {
for (int nPoint = 0; nPoint < 4; nPoint++)
{
ScreenPoint = projection.OrthogonalProjection(P[F[nFacet].Index[nPoint]]);
if (0 == nPoint)
{
pDC->MoveTo(ROUND(ScreenPoint.x), ROUND(ScreenPoint.y));
temp = ScreenPoint;
}
else
{
pDC->LineTo(ROUND(ScreenPoint.x), ROUND(ScreenPoint.y));
}
}
pDC->LineTo(ROUND(temp.x), ROUND(temp.y));
}
}
}
void CCube::Draw2(CDC* pDC)
{
CP2 ScreenPoint, temp;
CP3 ViewPoint = projection.EyePoint;
for (int nFacet = 0; nFacet < 6; nFacet++)
{
for (int i = 0; i < 4; i++) {
quardrP[i] = P[F[nFacet].Index[i]];
}
CVector ViewVector(quardrP[0], ViewPoint);
ViewVector = ViewVector.Normalize();
CVector Vector01(quardrP[0], quardrP[1]);
CVector Vector02(quardrP[0], quardrP[2]);
CVector Vector03(quardrP[0], quardrP[3]);
CVector FacetNormalA = CrossProduct(Vector01, Vector02);
CVector FacetNormalB = CrossProduct(Vector02, Vector03);
CVector FacetNormal = (FacetNormalA + FacetNormalB);
FacetNormal = FacetNormal.Normalize();
if (DotProduct(ViewVector, FacetNormal) >= 0) {
for (int nPoint = 0; nPoint < 4; nPoint++)
{
ScreenPoint = projection.ObliqueProjection(P[F[nFacet].Index[nPoint]]);
if (0 == nPoint)
{
pDC->MoveTo(ROUND(ScreenPoint.x), ROUND(ScreenPoint.y));
temp = ScreenPoint;
}
else
{
pDC->LineTo(ROUND(ScreenPoint.x), ROUND(ScreenPoint.y));
}
}
pDC->LineTo(ROUND(temp.x), ROUND(temp.y));
}
}
}
void CCube::Draw3(CDC* pDC)
{
CP2 ScreenPoint, temp;
CP3 ViewPoint = projection.EyePoint;
for (int nFacet = 0; nFacet < 6; nFacet++)
{
for (int i = 0; i < 4; i++) {
quardrP[i] = P[F[nFacet].Index[i]];
}
CVector ViewVector(quardrP[0], ViewPoint);
ViewVector = ViewVector.Normalize();
CVector Vector01(quardrP[0], quardrP[1]);
CVector Vector02(quardrP[0], quardrP[2]);
CVector Vector03(quardrP[0], quardrP[3]);
CVector FacetNormalA = CrossProduct(Vector01, Vector02);
CVector FacetNormalB = CrossProduct(Vector02, Vector03);
CVector FacetNormal = (FacetNormalA + FacetNormalB);
FacetNormal = FacetNormal.Normalize();
if (DotProduct(ViewVector, FacetNormal) >= 0) {
for (int nPoint = 0; nPoint < 4; nPoint++)
{
ScreenPoint = projection.PerspectiveProjection(P[F[nFacet].Index[nPoint]]);
if (0 == nPoint)
{
pDC->MoveTo(ROUND(ScreenPoint.x), ROUND(ScreenPoint.y));
temp = ScreenPoint;
}
else
{
pDC->LineTo(ROUND(ScreenPoint.x), ROUND(ScreenPoint.y));
}
}
pDC->LineTo(ROUND(temp.x), ROUND(temp.y));
}
}
}
效果展示
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a3bf86a46f069463e668cbd152169c96.png)