计算机图形学立方体三维变换


// 02View.h: CMy02View 类的接口
//

#pragma once
#include"CFace.h"
#include"cp3.h"
#include"CTransform.h"
class CMy02View : public CView
{
protected: // 仅从序列化创建
	CMy02View() noexcept;
	DECLARE_DYNCREATE(CMy02View)

// 特性
public:
	CMy02Doc* GetDocument() const;

// 操作
public:
	CRect rect;
	cp3 V[8];
	CFace F[6];
	CTransform T;
	void SetPoint();
	void SetFace();
	void DrawObject(CDC* pDC);
	cp2 Project(cp3);
// 重写
public:
	virtual void OnDraw(CDC* pDC);  // 重写以绘制该视图
	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);

// 实现
public:
	virtual ~CMy02View();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

protected:

// 生成的消息映射函数
protected:
	afx_msg void OnFilePrintPreview();
	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
};

#ifndef _DEBUG  // 02View.cpp 中的调试版本
inline CMy02Doc* CMy02View::GetDocument() const
   { return reinterpret_cast<CMy02Doc*>(m_pDocument); }
#endif


// 02View.cpp: CMy02View 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义,并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "02.h"
#endif

#include "02Doc.h"
#include "02View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CMy02View

IMPLEMENT_DYNCREATE(CMy02View, CView)

BEGIN_MESSAGE_MAP(CMy02View, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CMy02View::OnFilePrintPreview)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_WM_KEYDOWN()
END_MESSAGE_MAP()

// CMy02View 构造/析构

CMy02View::CMy02View() noexcept
{
	// TODO: 在此处添加构造代码
	SetPoint();
	SetFace();
    T.SetMat(V, 8);
}

CMy02View::~CMy02View()
{
}

BOOL CMy02View::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CMy02View 绘图

void CMy02View::OnDraw(CDC* pDC)
{
	CMy02Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	
	GetClientRect(&rect);//获得客户区矩形
	pDC->SetMapMode(MM_ANISOTROPIC);//设置映射模式
	pDC->SetWindowExt(rect.Width(), rect.Height());//设置窗口
	pDC->SetViewportExt(rect.Width(), -rect.Height());//设置视区;
	pDC->SetViewportOrg(rect.Width() / 2, rect.Height() / 2);//
	rect.OffsetRect(-rect.Width() / 2, -rect.Height() / 2);//客户区矩形矫正
	DrawObject(pDC);
	// TODO: 在此处为本机数据添加绘制代码
}


// CMy02View 打印


void CMy02View::OnFilePrintPreview()
{
#ifndef SHARED_HANDLERS
	AFXPrintPreview(this);
#endif
}

BOOL CMy02View::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CMy02View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CMy02View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}

void CMy02View::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CMy02View::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CMy02View 诊断

#ifdef _DEBUG
void CMy02View::AssertValid() const
{
	CView::AssertValid();
}

void CMy02View::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMy02Doc* CMy02View::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMy02Doc)));
	return (CMy02Doc*)m_pDocument;
}
#endif //_DEBUG


// CMy02View 消息处理程序
void CMy02View::SetPoint()
{
	int a = 100;
	V[0].x = 0, V[0].y = 0, V[0].z = 0;
	V[1].x = a, V[1].y = 0, V[1].z = 0;
	V[2].x = a, V[2].y = a, V[2].z = 0;
	V[3].x = 0, V[3].y = a, V[3].z = 0;
	V[4].x = 0, V[4].y = 0, V[4].z = a;
	V[5].x = a, V[5].y = 0, V[5].z = a;
	V[6].x = a, V[6].y = a, V[6].z = a;
	V[7].x = 0, V[7].y = a, V[7].z = a;
}
void CMy02View::SetFace()
{
	F[0].SetNum(4); F[0].VI[0] = 4; F[0].VI[1] = 5; F[0].VI[2] = 6; F[0].VI[3] = 7;//前面点的序号
	F[1].SetNum(4); F[1].VI[0] = 0; F[1].VI[1] = 3; F[1].VI[2] = 2; F[1].VI[3] = 1;//后
	F[2].SetNum(4); F[2].VI[0] = 0; F[2].VI[1] = 4; F[2].VI[2] = 7; F[2].VI[3] = 3;//左
	F[3].SetNum(4); F[3].VI[0] = 1; F[3].VI[1] = 2; F[3].VI[2] = 6; F[3].VI[3] = 5;//右
	F[4].SetNum(4); F[4].VI[0] = 0; F[4].VI[1] = 1; F[4].VI[2] = 5; F[4].VI[3] = 4;//下
	F[5].SetNum(4); F[5].VI[0] = 2; F[5].VI[1] = 3; F[5].VI[2] = 7; F[5].VI[3] = 6;//上
}
void CMy02View::DrawObject(CDC* pDC)
{
	pDC->MoveTo(0, 0);
	pDC->LineTo(rect.Width() / 2, 0);
	pDC->MoveTo(0, 0);
	pDC->LineTo(0, rect.Height() / 2);
	cp3 Z;
	cp2 X;
	Z.x = 0;
	Z.y = 0;
	Z.z = rect.Width() / 2;
	X = Project(Z);
	pDC->MoveTo(0, 0);
	pDC->LineTo(X.x, X.y);
	int i, j;
	cp2 SP,pt;
	for(i=0;i<6;i++)//面循环
		for (j = 0;j < 4;j++)
		{
			SP=Project(V[F[i].VI[j]]);
			if (j == 0)
			{	//移动到起到
				pDC->MoveTo(SP.x, SP.y);//当前点
				pt = SP;
			}
			else
				//画到下一个点
				pDC->LineTo(SP.x, SP.y);
		}
	pDC->LineTo(pt.x, pt.y);
}
cp2 CMy02View::Project(cp3 P)
{
	//正交投影
	cp2 ScreenP;
	/*ScreenP.x = P.x;
	ScreenP.y = P.y;*/
	//斜投影
	/*ScreenP.x = P.x-P.z*0.707;
	ScreenP.y = P.y - P.z * 0.707;*/
	//斜二测投影
	//ScreenP.x = P.x - P.z * 0.3536;
	//ScreenP.y = P.y - P.z * 0.3536;
	ScreenP.x = P.x - P.z * sqrt(2);
	ScreenP.y = P.y - P.z * sqrt(2);
	//透视投影
	return ScreenP;
}


void CMy02View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch (nChar)
	{
	case'W'://向上平移
	case VK_UP:
		T.Translate(0,10,0);break;
	case'S'://向下平移
	case VK_DOWN:

		T.Translate(0, -10,0);break;
	case'N'://向左平移
	case VK_LEFT:
		T.Translate(-10, 0,0);break;
	case'D'://向右平移
	case VK_RIGHT:

		T.Translate(10, 0,0);break;
	case'H'://向前平移
		T.Translate(0, 0, 10);break;
	case'V'://向后平移
		T.Translate(0, 0, -10);break;
	case'A'://等比例放大
	case VK_F1:
		T.Scale(1.5, 1.5,1.5);break;
	case'B'://等比例缩小
	case VK_F2:
		T.Scale(0.5, 0.5,0.5);break;
	case'E'://X复合旋转
	case VK_F3:

		T.RotateX(30);break;
	case'F'://Y复合旋转
	case VK_F4:

		T.RotateY(-30);break;
	case'1':
		T.RotateZ(30);break;
	case'G'://关于xoy轴反射变换
	case VK_F5:

		T.ReflectXOY();break;
	case'T'://关于yoz轴反射变换
	case VK_F6:

		T.ReflectYOZ();break;
	case'I'://关于zox反射变换
	case VK_F7:

		T.ReflectZOX();break;
	case'J'://X轴正向错切变换
	case VK_F8:

		T.ShearX(1, 1);break;
	case'K'://Y轴正向错切变换
	case VK_F9:

		T.ShearY(1, 1);break;
	case'M'://Z轴正向错切变换
	case VK_F10:

		T.ShearZ(1, 1);break;
	case'Q'://Y轴负向错切变换
	case VK_F11:

		SetPoint();
	}
	Invalidate();
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
#pragma once
class CFace
{
public:
    CFace(void);
    ~CFace(void);
    void SetNum(int vn);
public:
    //顶点数量
    int VNum;
    //保存若干个整形序号,动态数组
    int *VI;
 
};

#include "pch.h"
#include "CFace.h"
CFace::CFace()
{
	//VI = new int(VNum);//定义整型变量,变量的值
	VI = NULL;
}
CFace::~CFace()
{
	
}
void CFace::SetNum(int vn)
{
	VI = new int[vn];//定义整形数组,括号里数组的元素个数
	VNum = vn;
}
#pragma once
class cp2
{
public:
	cp2(void);
	~cp2(void);
	cp2(double x, double y);//带参构造
public:
	double x;
	double y;
	double w;

};

#include "pch.h"
#include "cp2.h"
cp2::cp2()
{
	w = 1;
}
cp2::~cp2()
{

}
cp2::cp2(double x, double y)
{
	this->x = x;
	this->y=y;
	w = 1;
}

#pragma once
#include"cp2.h"
class cp3:
	public cp2
{
public:
	cp3(void);
	~cp3(void);
	cp3(double x, double y,double z);//带参构造
public:
	/*double x;
	double y;*/
	double z;
};

#include "pch.h"
#include "cp3.h"
cp3::cp3()
{

}
cp3::~cp3()
{

}
cp3::cp3(double x, double y, double z) :cp2(x, y)
{
	this->z = z;
}
#pragma once
#include"cp3.h"
class CTransform
{
public:
	CTransform();
	~CTransform();
	void SetMat(cp3*, int n);
	void Identity();//初始化二维数组
	void Translate(double dx, double dy, double dz);//平移变换矩阵
	void Scale(double, double, double);//比例变换矩阵
	void RotateX(double);//x轴旋转变换
	void RotateY(double);//y轴旋转变换
	void RotateZ(double);
	void ReflectX();//x轴反射变换矩阵
	void ReflectY();
	void ReflectZ();
	void ReflectXOY();//XOY面反射变换矩阵
	void ReflectYOZ();
	void ReflectZOX();
	void ShearX(double,double);//x方向错切变换矩阵
	void ShearY(double, double);
	void ShearZ(double, double);
	void MulMat();//矩阵相乘
public:
	double T[4][4];
	cp3 * pOld;
	int PNum;
};

#include "pch.h"
#include "CTransform.h"
#include"cp3.h"
#define PI 3.1415926
CTransform::CTransform(void) {

}
CTransform::~CTransform(void) {

}
void CTransform::SetMat(cp3* p, int n)
{
	pOld = p;
	PNum = n;

}
void CTransform::Identity()
{
	/*T[0][0] = 1.0;T[0][1] = 0.0;T[0][2] = 0.0;T[0][3] = 0.0;
	T[1][0] = 0.0;T[1][1] = 1.0;T[1][2] = 0.0;T[1][3] = 0.0;
	T[2][0] = 0.0;T[2][1] = 0.0;T[2][2] = 1.0;T[2][3] = 0.0;
	T[3][0] = 0.0;T[3][1] = 0.0;T[3][2] = 0.0;T[2][3] = 1.0;*/
	T[0][0] = 1; T[0][1] = 0; T[0][2] = 0; T[0][3] = 0;
	T[1][0] = 0; T[1][1] = 1; T[1][2] = 0; T[1][3] = 0;
	T[2][0] = 0; T[2][1] = 0; T[2][2] = 1; T[2][3] = 0;
	T[3][0] = 0; T[3][1] = 0; T[3][2] = 0; T[3][3] = 1;
}
void CTransform::MulMat()
{
	int i;
	cp3* pNew = new cp3[PNum];
	for (i = 0;i < PNum;i++)
	{
		pNew[i].x = pOld[i].x;
		pNew[i].y = pOld[i].y;
		pNew[i].z = pOld[i].z;
		pNew[i].w = pOld[i].w;
	}
	for (i = 0;i < PNum;i++)
	{
		/*pOld[i].x = pNew[i].x * T[0][0]
			+ pNew[i].y * T[1][0]
			+ pNew[i].z * T[2][0]
			+ pNew[i].w * T[3][0];
		pOld[i].y = pNew[i].x * T[0][1]
			+ pNew[i].y * T[1][1]
			+ pNew[i].z * T[2][1]
			+ pNew[i].w * T[3][1];
		pOld[i].z = pNew[i].x * T[0][2]
			+ pNew[i].y * T[1][2]
			+ pNew[i].z * T[2][2]
			+ pNew[i].w * T[3][2];
		pOld[i].w = pNew[i].x * T[0][3]
			+ pNew[i].y * T[1][3]
			+ pNew[i].z * T[2][3]
			+ pNew[i].w * T[3][3];*/
		pOld[i].x = pNew[i].x * T[0][0] + pNew[i].y * T[1][0] + pNew[i].z * T[2][0] + pNew[i].w * T[3][0];
		pOld[i].y = pNew[i].x * T[0][1] + pNew[i].y * T[1][1] + pNew[i].z * T[2][1] + pNew[i].w * T[3][1];
		pOld[i].z = pNew[i].x * T[0][2] + pNew[i].y * T[1][2] + pNew[i].z * T[2][2] + pNew[i].w * T[3][2];
		pOld[i].w = pNew[i].x * T[0][3] + pNew[i].y * T[1][3] + pNew[i].z * T[2][3] + pNew[i].w * T[3][3];
	}
	delete[]pNew;
}
void CTransform::Translate(double dx, double dy, double dz)//平移
{
	Identity();
	T[3][0] = dx; T[3][1] = dy; T[3][2] = dz;
	MulMat();
}
void CTransform::Scale(double sx, double sy,double sz)
{
	Identity();
	T[0][0] = sx;T[1][1] = sy;T[2][2] = sz;
	MulMat();
}

void CTransform::RotateX(double beta)
{
	Identity();
	double rad = beta * PI / 180;

	T[1][1] = cos(rad);T[1][2] = sin(rad);
	T[2][1] = -sin(rad);T[2][2] = cos(rad);
	MulMat();

}
void CTransform::RotateY(double beta)
{
	Identity();
	double rad = beta * PI / 180;

	T[0][0] = cos(rad);T[0][2] = -sin(rad);
	T[2][0] = sin(rad);T[2][2] = cos(rad);
	MulMat();
}
void CTransform::RotateZ(double beta)
{
	Identity();
	double rad = beta * PI / 180;

	T[0][0] = cos(rad);T[0][1] = sin(rad);
	T[1][0] = -sin(rad);T[1][1] = cos(rad);
	MulMat();
}
void  CTransform::ReflectX()
{
	Identity();
	T[1][1] = -1;T[2][2] = -1;
	MulMat();
}
void CTransform::ReflectY()
{
	Identity();
	T[0][0] = -1;T[2][2] = -1;
	MulMat();
}

void CTransform::ReflectZ()
{
	Identity();
	T[0][0] = -1;T[1][1] = -1;
	MulMat();
}
void CTransform::ReflectXOY()
{
	Identity();
	T[2][2] = -1;
	MulMat();
}
void CTransform::ReflectYOZ()
{
	Identity();
	T[0][0] = -1;
	MulMat();
}
void CTransform::ReflectZOX()
{
	Identity();
	T[1][1] = -1;
	MulMat();
}
void  CTransform::ShearX(double d, double g)
{
	Identity();
	T[1][0] = d;T[2][0] = g;
	MulMat();
}
void  CTransform::ShearY(double b, double h)
{
	Identity();
	T[0][1] = b;T[2][1] = h;
	MulMat();
}
void  CTransform::ShearZ(double c, double f)
{
	Identity();
	T[0][1] = c;T[1][0] = f;
	MulMat();
}

  • 2
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值