持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情
一、实验目的及要求
实验要求: 1.掌握对三维物体进行平移、旋转、放缩、错切等变换的方法; 2.掌握利用透视变换算法生成立方体的一点、两点和三点透视的方法; 3.掌握旋转立方体的透视投影图的方法。 4.良好的交互设计。
二、实验仪器设备与软件环境
Windows 7以上操作系统 Microsoft Visual Studio 2010
三、实验过程及实验结果分析
(包括实验原理、步骤、数据、图表、结果及分析。软件类实验应写出程序代码;硬件类实验画出电路原理图(或逻辑框图)、列出实验数据,并对实验结果进行分析)
主要实验步骤:
创建新项目Test; 同时添加点类,选择“添加”,添加类CP2,虚析构函数 P2.h:
class CP2
{
public:
CP2();
virtual ~CP2();
public:
double x;
double y;
UINT rc;
};
CP3同理: P3.h :
#pragma once
#include "p2.h"
class CP3 :
public CP2
{
public:
CP3(void);
virtual ~CP3();
CP3(double,double,double);
public:
double z;
};
P3.cpp :
#include "StdAfx.h"
#include "P3.h"
CP3::CP3()
{
z=0.0;
}
CP3::~CP3()
{
this->z=z;
}
颜色类: RGB.h:
#pragma once
class CRGB
{
public:
CRGB();
CRGB(double,double,double);
virtual ~CRGB();
void Normalize();
public:
double red;
double green;
double blue;
};
RGB.cpp:
#include "StdAfx.h"
#include "RGB.h"
CRGB::CRGB()
{
red=1.0;
green=1.0;
blue=1.0;
}
CRGB::CRGB(double r,double g,double b)
{
red=r;
green=g;
blue=b;
}
CRGB::~CRGB()
{
}
Line.h:
class CLine
{
public:
CLine();
virtual ~CLine();
void MoveTo(CDC *,CP2);
void MoveTo(CDC *,double,double);
void LineTo(CDC *,CP2);
void LineTo(CDC *,double,double);
public:
CP2 P0;
CP2 P1;
};
CFace.h:
#pragma once
class CFace
{
public:
CFace();
virtual ~CFace();
void SetNum(int);
public:
int vN;
int *vI;
};
CFace.cpp:
CFace::CFace()
{
vI=NULL;
}
CFace::~CFace()
{
if(vI!=NULL)
{
delete []vI;
vI=NULL;
}
}
void CFace::SetNum(int en)
{
vN=en;
vI=new int[vN];
}
CTestView.h:
#include"Line.h"
#include"Face.h"
#include"P3.h"
CTestview.cpp:
void CTestView::DoubleBuffer(CDC *pDC)
{
CRect rect;
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);
CDC memDC;
CBitmap NewBitmap,*pOldBitmap;
memDC.CreateCompatibleDC(pDC);
NewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
pOldBitmap=memDC.SelectObject(&NewBitmap);
memDC.FillSolidRect(rect,pDC->GetBkColor());
memDC.SetMapMode(MM_ANISOTROPIC);
memDC.SetWindowExt(rect.Width(),rect.Height());
memDC.SetViewportExt(rect.Width(),-rect.Height());
memDC.SetViewportOrg(rect.Width()/2,rect.Height()/2);
rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);
DrawObject(&memDC);
pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,-rect.Width()/2,-rect.Height()/2,SRCCOPY);
memDC.SelectObject(pOldBitmap);
NewBitmap.DeleteObject();
}
void CTestView::DrawObject(CDC* pDC)
{
CP2 t;
CLine *line=new CLine;
for(int nFace=0;nFace<6;nFace++)
{
for(int nPoint=0;nPoint<F[nFace].vN;nPoint++)
{
PerProject(P[F[nFace].vI[nPoint]]);
if(0==nPoint)
{
line->MoveTo(pDC,ScreenP);
t=ScreenP;
}
else
line->LineTo(pDC,ScreenP);
}
line->LineTo(pDC,t);
}
delete line;
}
等6个成员函数。 类视图, CTestView,类向导,虚函数, 双击OnInitialUpdate
void CTestView::OnInitialUpdate()
{
CView::OnInitialUpdate();
ReadPoint();
ReadFace();
InitParameter();
}
工具栏,资源视图Test/Icon,添加资源,Icon/导入,打开picture7文件夹,文件类型选图标文件
结果如下:
打开资源视图,找工具栏,Test/Toolbar/IDR_MAINFRAME,双击IDR_MAINFRAME
将尺寸改为32 32
导入图标:
同样方法将
图标加入到工具栏中,他们的ID 分别为ID_TWOPOINT, ID_THREEPOINT, IDM_PLAY.
类视图,右击CTestView, “类向导“,命令下找到ID ID_ONTPOINT,并双击 默认使用系统分配的函数名,确认
函数OnOnepoint代码 void CTestView::OnOnepoint() { AfxGetMainWnd()->SetWindowText(CString("一点透视")); KillTimer(1); bPlay=FALSE; Phi=90; Theta=0; InitParameter(); Invalidate(FALSE); } void CTestView::OnTwopoitnt() {
AfxGetMainWnd()->SetWindowText(CString(",二点透视"));
KillTimer(1);
bPlay=FALSE;
Phi=90;
Theta=30;
InitParameter();
Invalidate(FALSE);
}
void CTestView::OnThreepoint() { AfxGetMainWnd()->SetWindowText(CString("三点透视")); KillTimer(1); bPlay=FALSE; Phi=45; Theta=45; InitParameter(); Invalidate(FALSE); }
void CTestView::OnPlay() { AfxGetMainWnd()->SetWindowText(CString(“透视")); bPlay=bPlay?FALSE:TRUE; if(bPlay) SetTimer(1,150,NULL); else KillTimer(1); }
类视图,右击TestView,选择类向导,消息/WM_TIMER
代码: void CTestView::OnTimer(UINT_PTR nIDEvent) { // TODO: 在此添加消息处理程序代码和/或调用默认值 Phi-=5; Theta-=5; InitParameter(); Invalidate(FALSE); CView::OnTimer(nIDEvent); }
编辑函数 void CTestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { if(!bPlay) { switch(nChar) { case VK_UP: Phi+=5; break; case VK_DOWN: Theta+=5; break; case VK_RIGHT: Theta-=5; break; default: break; } } CView::OnKeyDown(nChar, nRepCnt, nFlags); }
实验结果及分析:
按1:
按2:
按3:
按动画: