计算机图形学 图形变换

时间:2024.5.4

实验五:图形变换

一、实验目的:

1、掌握图形变换的基本方法。

2、初步掌握映射菜单消息和捕获键盘消息的方法。

二、实验内容及要求:

1、

2、

3、 以三角形为例,使用Visual C++实现二维图形的平移、旋转和缩放功能。 每人单独完成实验。 按要求撰写实验报告,写出实验心得,并在实验报告中附上程序的核心算法代码。

三、实验设备:

微机,Visual C++6.0

四、实验内容和步骤:

1、 打开VC,新建一个MFC Appwizard项目,选择创建单文档工程(SDI工程)。假设工程名为Transform。如图1和图2所示。

计算机图形学图形变换

图1

计算机图形学图形变换

图2

2、 在图2的界面上点击Finish,完成工程的创建。

3、 在TransformView.h文件中,加入如下代码:

public:

CPoint Pt[3]; //存储三角形的三个顶点

float dAngle; //存储三角形旋转的角度

4、 在类CTransformView的构造函数中定义三角形的三个顶点的初始坐标和dAngle的初值,代码如

下;

CTransformView::CTransformView()

{

// TODO: add construction code here

Pt[0].x = 200; Pt[0].y = 220;

Pt[1].x = 260; Pt[1].y = 300;

Pt[2].x = 360; Pt[2].y = 180;

dAngle = 0.0;

}

5、 在类CTransformView中添加成员函数void DrawTriangle(CDC *pDC),并实现该函数。(该部分代

码请同学们自己实现,为了简便编程,可以使用MoveTo和LineTo函数,也可以调用自己在实验2中编写的DDA或者Bresenham画线函数);

6、 在类CTransformView的OnDraw()函数中添加绘制三角形的代码;

void CTransformView::OnDraw(CDC* pDC)

{

CTransformDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

// TODO: add draw code for native data here

DrawTriangle(pDC);

}

7、 映射菜单消息,方法是打开ResourceView菜单,依次展开MENU \ IDR_MAINFRAME,添加“图

形变换”主菜单项,在其下添加“平移”,如图3所示。

计算机图形学图形变换

图3

8、 在TransformView.cpp文件中(类CTransformView中)映射平移的菜单消息,触发平移函数。代

码如下:

void CTransformView::OnMenuTransformTranslate()

{

// TODO: Add your command handler code here

int nX = 50;

int nY = 80; //平移的X坐标和Y坐标

for(int i=0; i<3; i++)

{

Pt[i].x += nX;

Pt[i].y += nY;

}

RedrawWindow(); //该行代码必不可少,用于触发OnDraw()函数

}

9、 与平移类似,请同学们自己依次添加“缩放”和“旋转”菜单,并实现相应的“缩放”菜单和“旋

转”菜单的消息映射函数。

10、 添加捕获键盘的消息,实现用键盘控制三角形的平移、缩放和旋转。在TransformView.cpp

文件中单击鼠标右键,选择ClassWizard,如图4所示,为键盘消息WM_KEYDOWN添加消息映射函数,代码如下:

void CTransformView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

{

// TODO: Add your message handler code here and/or call default

int i=0;

CPoint TmpPt = Pt[0];

switch (nChar){

case VK_UP: //用上箭头控制三角形向上移动

for(i=0; i<3; i++)

{

Pt[i].y -= 5;

}

break;

case VK_DOWN: //用下箭头控制三角形向下移动

for(i=0; i<3; i++)

{

Pt[i].y += 5;

} } break; 。。。。。。 // } RedrawWindow(); CView::OnKeyDown(nChar, nRepCnt, nFlags);

计算机图形学图形变换

图4

11、 请同学们在WM_KEYDOWN的消息映射函数中,再自己实现用左、右箭头控制三角形移动

的代码。左右箭头的虚键分别为VK_LEFT, VK_RIGHT。

12、 请同学们在WM_KEYDOWN的消息映射函数中,再自己实现用Z和X键控制三角形放大1

倍和缩小1倍的代码。在消息映射函数中,按下Z键,说明nChar=Z的ASCII码;其他字母相同。

13、 请同学们在WM_KEYDOWN的消息映射函数中,再自己实现用R键控制三角形旋转的代

码。多按几下R键,看看会发生什么情况?为什么会这样?如何解决?

五、核心代码:

这里将自己编写的上机程序中的主要代码拷贝粘贴过来;

Ondraw:

void CShiyqan5View::OnDraw(CDC* pDC)

{

CShiyqan5Doc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

DrawTriangle(pDC);

}

用DDA画出三角形

void CShiyqan5View::DrawTriangle(CDC *pDC)

{

DDALine(Pt[0].x,Pt[0].y,Pt[1].x,Pt[1].y,RGB(0,147,145));

DDALine(Pt[1].x,Pt[1].y,Pt[2].x,Pt[2].y,RGB(0,147,145));

DDALine(Pt[2].x,Pt[2].y,Pt[0].x,Pt[0].y,RGB(0,147,145));

}

void CShiyqan5View::DDALine(int x0, int y0, int x1, int y1, COLORREF color) {

CDC *pDC = this->GetDC();

int i;

float dx, dy, length,x,y;

if (fabs(x1-x0)>=fabs(y1-y0))

length=fabs(x1-x0);

else

length=fabs(y1-y0);

dx= (x1-x0)/length;

dy=(y1-y0)/length;

i=1;x= x0;y= y0;

while(i<=length)

{

pDC->SetPixel(int (x + 0.5), int (y + 0.5), color);

x=x+dx;

y=y+dy;

i++;

}

实现图形平移

void CShiyqan5View::OnMenuTransformTranslate()

{

// TODO: Add your command handler code here

int nX = 50;

int nY = 80; //平移的X坐标和Y坐标

for(int i=0; i<3; i++)

{

Pt[i].x += nX;

Pt[i].y += nY;

}

RedrawWindow();

}

缩放

void CShiyqan5View::Onsuofang()

{

int nX=200;

int nY=200;

for(int i=0 ;i<3;i++)

{

Pt[i].x=Pt[i].x*0.5;

Pt[i].y=Pt[i].y*0.5;

Pt[i].x+=nX;

Pt[i].y+=nY;

}

RedrawWindow();

}

旋转

void CShiyqan5View::Onxuanzhuan()

{

double dAngle=0.1;

for(int i=0;i<3;i++)

{

Pt[i].x=Pt[i].x*cos(dAngle)-Pt[i].y*sin(dAngle);

Pt[i].y=Pt[i].x*sin(dAngle)+Pt[i].y*cos(dAngle);

}// TODO: Add your command handler code here

RedrawWindow();

}

键盘

void CShiyqan5View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {

// TODO: Add your message handler code here and/or call default int i=0;

int nX=200;

int nY=200;

CPoint TmpPt = Pt[0];

switch (nChar){

case VK_UP: //用上箭头控制三角形向上移动 for(i=0; i<3; i++)

{

Pt[i].y -= 5;

}

break;

case VK_DOWN: //用下箭头控制三角形向下移动 for(i=0; i<3; i++)

{

Pt[i].y += 5;

}

break;

case VK_LEFT: //用上箭头控制三角形向左移动 for(i=0; i<3; i++)

{

Pt[i].x -= 5;

}

break;

case VK_RIGHT: //用下箭头控制三角形向右移动 for(i=0; i<3; i++)

{

Pt[i].x += 5;

}

break;

case 90: //Z缩小

for(i=0 ;i<3;i++)

{

Pt[i].x=Pt[i].x*0.5;

Pt[i].y=Pt[i].y*0.5;

Pt[i].x+=nX;

Pt[i].y+=nY;

}

break;

case 88://x放大

for(i=0 ;i<3;i++)

{

Pt[i].x=Pt[i].x*2.0;

Pt[i].y=Pt[i].y*2.0;

Pt[i].x+=nX;

Pt[i].y+=nY;

}

break;

case 82://R的旋转

double circular=15*3.1415/180;

double x1=(Pt[0].x)*cos(circular)-(Pt[0].y)*sin(circular);

double y1=(Pt[0].x)*sin(circular)+(Pt[0].y)*cos(circular);

double x2=(Pt[1].x)*cos(circular)-(Pt[1].y)*sin(circular);

double y2=(Pt[1].x)*sin(circular)+(Pt[1].y)*cos(circular);

double x3=(Pt[2].x)*cos(circular)-(Pt[2].y)*sin(circular);

double y3=(Pt[2].x)*sin(circular)+(Pt[2].y)*cos(circular);//进行逆时针旋转变化 double sX=Pt[0].x-x1;

double sY=Pt[0].y-y1;

x1+=sX;

y1+=sY;

x2+=sX;

y2+=sY;

x3+=sX;

y3+=sY;

Pt[0].x=x1;

Pt[0].y=y1;

Pt[1].x=x2;

Pt[1].y=y2;

Pt[2].x=x3;

Pt[2].y=y3; }

break;

}

RedrawWindow();

CView::OnKeyDown(nChar, nRepCnt, nFlags);

});

六、屏幕显示结果:

这里将绘出的图形界面拷贝下来;

画出三角形:

计算机图形学图形变换

缩小一半:

计算机图形学图形变换

旋转

计算机图形学图形变换

实现向上移动:

计算机图形学图形变换

实现向下移动:

计算机图形学图形变换

向左

计算机图形学图形变换

键盘向右

计算机图形学图形变换

实现Z的缩放

计算机图形学图形变换

实现X的放大

计算机图形学图形变换

实现R的旋转

计算机图形学图形变换

计算机图形学图形变换

七、思考题(尽量做,计入成绩):

1、将三角形A(250,200),B(100,100),C(300,200)绕P(200,100)点旋转45°,求旋转后的三角形的坐标。 要求画出原三角形、坐标系、点P,旋转后得到的新三角形。――要求上机完成

2、如何较好地绘出一个平面直角坐标系?

(1)Scale法

通过自定义左上角和右下角坐标来设置新的坐标系统。用户通过自定义坐标时,一般先选定ScaleMode=0,然后设定用户自定义坐标ScaleMode=3,最后用Scale方法定义坐标系。

(2)通过对象属性ScaleLeft和ScaleTop直接赋值自定义坐标系

3、在Turbo C中如果要编写菜单的实现程序,是什么步骤?

首先建立类向导,然后在Project的Cshiyan5View下的,Message是command下建立一个新的成员函数。然后设好ID,并且名字可以改成想要的。建好后就可以在函数体中添加代码,来实现菜单。 例如:

void CShiyqan5View::OnMenuTransformTranslate()

{

// TODO: Add your command handler code here

int nX = 50;

int nY = 80; //平移的X坐标和Y坐标

for(int i=0; i<3; i++)

{

Pt[i].x += nX;

Pt[i].y += nY;

}

RedrawWindow();

4、如果OnKeyDown函数中不加RedrawWindow()语句,会出现什么结果?为什么?

RedrawWindow()是用来触发Ondraw函数的,如果不用则无法进行调用。

5、为什么旋转程序的结果和预计的不一样?

因为P点是左上角的一个点,随着三角形的旋转,围绕着的中心点不断向外延伸出去。这样就和预想的结果有些不同了。

八、实验体会

通过这次试验,我学到了图形变换的基本方法,同时初步掌握映射菜单消息和捕获键盘消息的方法。根据实验指导书的要求,以三角形为例,使用Visual C++实现二维图形的平移、旋转和缩放功能。

在映射平移的菜单消息中,触发平移函数。使用RedrawWindow();这条语句,该行代码必不可少,用于触发OnDraw()函数。然后在实现缩放和平移的内容。

在做实验时我一直编译不通过,经过老师的提点之后,发现我一开始是在Frame下建立类向导,而实际是应该在View下建立,但是我只是把相应的代码从程序中删除了,而没有实际把他们删掉,使得程序总是编译不通过。经过老师的提点后,发现其实错误根本还没有完全删除,再改正之后,程序才得以编译成功。

添加捕获键盘的消息,在实现键盘上下左右的位移,通过上面的实验指导书中的内容加以改编,可以完成,还需加上case 和要用的按钮。在添加ZXR的虚键时,算了下他们相对应的ASCII码,之后进行编写代码,把之前做的缩放、旋转加进去,这样即可实现。

按照实验内容,共做了13步实验,并加以实现。

九、注意及特别说明

1、 实验内容及步骤中的前9步为必须完成的实验内容,第10步至第13步,请同学们根据自己的兴趣选

做;

2、 如对Visual C++的编译环境不熟悉,请课下提前参考Visual C++的相关书籍和MSDN。


第二篇:计算机图形学投影变换


计算机图形学实验报告

实验三 三维图形的投影变换

生业导、姓班教名 级 师 绩

电子与信息工程系

2010 年 11月 6日

一、实验目的:

绘制三维物体的轴测投影图和一点透视图 ,在程序中给定控制多面体的顶点坐标及点线信息。视点固定在z轴某点上,输入物体的旋转角度及平移量。正轴测投影图和一点透视图。

二、题目:

三维图象的基本变换

三、设计思想:

因为电脑显示的是2维持坐标图象,所以在设计时要将三维的图象坐标转换成电脑能显示的二维持坐标图,然后根据图象的基本变换矩阵计算出变换后的坐标点,最后绘制出图象变换效果。

四、原程序:

CPoint dian22[8];//六面体的8个2维坐标点

CPoint dian[8]; float coordinate2[8][3];

float coordinate3[8][3] 六面体的8个3维坐标点

Void draw6angle()//绘制一个六面方体。

dc.MoveTo(0,0);//yuan dian zuo biao dian(400,400)

dc.LineTo(400,0);//x //绘制一x轴,Y,Z轴

dc.MoveTo(0,0); dc.LineTo(0,400);//y dc.MoveTo(50,50);//z dc.LineTo(-200,-200); dc.MoveTo(dian[0]);//0-1 dc.LineTo(dian[1]); dc.MoveTo(dian[0]);//0-3 dc.LineTo(dian[3]); dc.MoveTo(dian[0]);//0-7 dc.LineTo(dian[7]);

} dc.MoveTo(dian[4]);//4-3 dc.LineTo(dian[3]); dc.MoveTo(dian[4]);//4-5 dc.LineTo(dian[5]); dc.MoveTo(dian[4]);//4-7 dc.LineTo(dian[7]); dc.MoveTo(dian[6]);//6-5 dc.LineTo(dian[5]); dc.MoveTo(dian[6]);//6-7 dc.LineTo(dian[7]); dc.MoveTo(dian[6]);//6-1 dc.LineTo(dian[1]); dc.MoveTo(dian[2]);//2-1 dc.LineTo(dian[1]); dc.MoveTo(dian[2]);//2-3 dc.LineTo(dian[3]); dc.MoveTo(dian[2]);//2-5 dc.LineTo(dian[5])}

void CCBod_3DView::switch_point()//将三维坐标点转换成电脑上能表示的二维坐标点

{ float canshu=0.7071;

for(int i=0;i<8;i++)

{ dian[i].x=float (coordinate3[i][0]+float((-coordinate3[i][2]*canshu))); dian[i].y=float (coordinate3[i][1]+float((-coordinate3[i][2]*canshu))); } }

void CCBod_3DView::OnMoveOnz() //图象在Z轴上的移动。

{

// TODO: Add your command handler code here for(int i=0;i<8;i++)

{

coordinate3[i][2]=coordinate3[i][2]+50; }

this->Invalidate();

}

void CCBod_3DView::OnSpinz() //Z轴上旋转

{ // TODO: Add your command handler code here

{ coordinate3[i][0]=float(coordinate3[i][0]*b)+float(coordinate3[i][1]*(-a)); coordinate3[i][1]=float(coordinate3[i][0]*a)+coordinate3[i][1]*b; } float b=cos(0.23); float a=sin(0.23); for(int i=0;i<8;i++)

OnLarge();

this->Invalidate(); }

void CCBod_3DView::OnDUICHeng() //关于X对称 {// TODO: Add your command handler code here

for(int i=0;i<8;i++) {coordinate3[i][2]= -coordinate3[i][2]; } this->Invalidate(); }

void CCBod_3DView::OnZhengzhouce() //轴测投影图 {// TODO: Add your command handler code here

if(flage==false) { flage=true; }

else

{ flage=false;

}

float dian3[8][3];

for(int i=0;i<8;i++)

{

dian3[i][0]=coordinate3[i][0];

dian3[i][1]=coordinate3[i][1];

dian3[i][2]=coordinate3[i][2];

}

float a,b,c;

float angle_a=3.1415/4;

float angle_b=3.1415/6;

for(int j=0;j<8;j++)

{

a=dian3[j][0];

b=dian3[j][1];

c=dian3[j][2];

dian3[j][0]=float ( a*cos(angle_a) -b*sin(angle_a) );

dian3[j][1]=0;

dian3[j][2]= float( -sin(angle_b)*( a*sin(angle_a)+b*cos(angle_a) + c*cos(angle_b) ); }

float canshu=0.7071;

for(int i2=0;i2<8;i2++)

{ dian22[i2].x=float (dian3[i2][0]+float((-dian3[i2][2]*canshu))); dian22[i2].y=float (dian3[i2][1]+float((-dian3[i2][2]*canshu))); }

this->Invalidate();

} )

void CCBod_3DView::OnONEView() //一点透视图象 {

}

五、运行结果:

1.初始化界面。

计算机图形学投影变换

// TODO: Add your command handler code her this->Invalidate(); if(m_toushi==false) { m_toushi=true; }else { m_toushi=false;}

2.沿Z轴旋转的效果

计算机图形学投影变换

3放大效果

计算机图形学投影变换

4 旋转效果

计算机图形学投影变换

5对称

计算机图形学投影变换

6.轴侧投影图

计算机图形学投影变换

7.一点透视

计算机图形学投影变换

更多相关推荐:
计算机图形学学习心得体会

计算机图形学学习心得体会计算机科学与技术与技术班学号1计算机图形学计算机图形学ComputerGraphics简称CG狭义上是一种研究基于物理定律经验方法以及认知原理使用各种数学算法处理二维或三维图形数据生成可...

计算机图形学学习体会

让设计成为现实我对计算机图形学的认识10049410级景观一班苏莞琴计算机图形学包含的主要内容计算机图形学ComputerGraphic是人类设计手法不断演进的产物这门学科主要研究通过计算机处理用几何数据和数学...

计算机图形学感想

计算机图形学感想小学期的导论课里老师们从偏微分方程代数学组合概率论非线性方程组解法计算数学简介几何学最优化运筹学和计算机图形学八个方面为切入点给我们讲解了数学的一些分支上的知识老师的讲解拓宽了我们的知识面增加了...

计算机图形学学习的心得体会

对计算机图形学课程学习的心得体会通过一个学期的学习,了解了什么是计算机图形学、什么是图形API、为什么需要计算机图形学以及计算机图形学在各个领域的应用。计算机图形学是一种使用数学算法将二维或三维图形转化为计算机…

计算机图形学学习体会

计算题图形学课程学习体会计算机图形学是研究用计算机生成处理和显示图形的一门学科他的重要性体现在人们越来越强烈的需要和谐的人机交互环境UI已经成为软件的重要组成部分以图形的方式表示抽象的概念和数据已经成为信息领域...

计算机图形学心得体会

计算机图形学心得体会姓名:学号:20xx03284班级:计科11202序号:31院系:计算机科学学院通过一个学期的学习,经过老师细心的讲解,我对图形学这门课有了基础的认识,从您的课上我学到了不少知识,基本上对图…

计算机图形学 总结

第一章绪论计算机图形学的基本概念计算机图形学是研究怎样用数字计算机生成处理和显示图形的一门学科图形计算机图形学的研究对象构成图形的要素几何要素几何属性点线面体非几何要素视觉属性明暗灰度色彩纹理透明性线型线宽表示...

计算机图形学实验报告

武汉工业学院数学与计算机学院计算机图形学专业班级学号姓名指导老师实验报告20xx年5月25日第二章直线生成算法21实验原理211中点Bresenham算法22实验内容请使用中点Bresenham算法来生成直线实...

计算机图形学实验报告

实验报告课程名称计算机图形学学院信息科学与工程学院专业数字媒体技术班级20xx级姓名李义学号20xx010520xx20xx年12月19日山东科技大学教务处制目录实验一环境设置3实验二直线的生成算法4实验三圆的...

计算机图形学大作业

大连民族学院计算机图形学期末论文学院计算机科学与工程专业计算机科学与技术班级学号姓名成绩一问题描述11基本要求了解计算机图形学中的基本原理和方法并能利用程序设计语言实现12实验内容1利用程序设计语言进行二维及三...

计算机图形学第五次实验报告

计算机图形学实验报告实验十一真实感图形一实验教学目标与基本要求初步实现真实感图形并实践图形的造型与变换等二理论基础运用几何造型几何投影及透视变换真实感图形效果消隐纹理光照等有关知识实现1用给定地形高程数据绘制出...

计算机图形学

一试验动机编出一个程序能够实现贪吃蛇的游戏二实验环境VisuaiC60三核心算法描述贪吃蛇的要求为一条蛇在封密的围墙内在围墙内随机出现一个食物通过按键盘上的四个光标控键控制蛇向上下左右四个方向移动蛇头撞到食物则...

计算机图形学学习心得(45篇)