计算机图形学课程设计报告.docx

上传人:b****1 文档编号:2029271 上传时间:2023-05-02 格式:DOCX 页数:15 大小:65.95KB
下载 相关 举报
计算机图形学课程设计报告.docx_第1页
第1页 / 共15页
计算机图形学课程设计报告.docx_第2页
第2页 / 共15页
计算机图形学课程设计报告.docx_第3页
第3页 / 共15页
计算机图形学课程设计报告.docx_第4页
第4页 / 共15页
计算机图形学课程设计报告.docx_第5页
第5页 / 共15页
计算机图形学课程设计报告.docx_第6页
第6页 / 共15页
计算机图形学课程设计报告.docx_第7页
第7页 / 共15页
计算机图形学课程设计报告.docx_第8页
第8页 / 共15页
计算机图形学课程设计报告.docx_第9页
第9页 / 共15页
计算机图形学课程设计报告.docx_第10页
第10页 / 共15页
计算机图形学课程设计报告.docx_第11页
第11页 / 共15页
计算机图形学课程设计报告.docx_第12页
第12页 / 共15页
计算机图形学课程设计报告.docx_第13页
第13页 / 共15页
计算机图形学课程设计报告.docx_第14页
第14页 / 共15页
计算机图形学课程设计报告.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

计算机图形学课程设计报告.docx

《计算机图形学课程设计报告.docx》由会员分享,可在线阅读,更多相关《计算机图形学课程设计报告.docx(15页珍藏版)》请在冰点文库上搜索。

计算机图形学课程设计报告.docx

计算机图形学课程设计报告

一、设计内容与要求

1.1、设计题目

算法实现时钟运动

1.2、总体目标和要求

(1)目标:

以图形学算法为目标,深入研究。

继而策划、设计并实现一个能够表现计算机图形学算法原理的或完整过程的演示系统,并能从某些方面作出评价和改进意见。

通过完成一个完整程序,经历策划、设计、开发、测试、总结和验收各阶段,达到巩固和实践计算机图形学课程中的理论和算法;学习表现计算机图形学算法的技巧;培养认真学习、积极探索的精神。

(2)总体要求:

策划、设计并实现一个能够充分表现图形学算法的演示系统,界面要求美观大方,能清楚地演示算法执行的每一个步骤。

(3)开发环境:

ViusalC++6.0

1.3、设计要求

内容:

(1)掌握动画基本原理;

(2)实现平面几何变换;

功能要求:

(1)显示时钟三个时针,实现三根时针间的相互关系;

(2)通过右键菜单切换时钟背景与时针颜色;

1.4设计方案

通过使用OpenGL提供的标准库函数,综合图形学Bresenham画线和画圆的算法,OpenGL颜色模型中颜色表示模式等实现指针式时钟运动,并通过点击右键菜单实习时钟背景与时针颜色的转换。

根据Bresenham画线和画圆的算法,画出时钟的指针和表盘。

再根据OpenGL颜色模型定义当前颜色。

设置当时钟运行时交换的菜单,运行程序时可变换时钟背景与时针的颜色。

最后再设置一个恢复菜单恢复开始时表盘与指针的颜色。

二、总体设计

2.1、过程流程图

 

2.2、椭圆的中点生成算法

1、椭圆对称性质原理:

(1)圆是满足x轴对称的,这样只需要计算原来的1/2点的位置;

(2)圆是满足y轴对称的,这样只需要计算原来的1/2点的位置;

通过上面分析可以得到实际上我们计算椭圆生成时候,只需要计算1/4个椭圆就可以实现对于所有点的生成了。

2、中点椭圆算法内容:

(1)输入椭圆的两个半径r1和r2,并且输入椭圆的圆心。

设置初始点(x0,y0)的位置为(0,r2);

(2)计算区域1中央决策参数的初始值

p=ry*ry-rx*rx*ry+1/4*(rx*rx);

(3)在区域1中的每个Xn为止,从n=0开始,直到|K|(斜率)小于-1时后结束;

<1>如果p<0,绘制下一个点(x+1,y),并且计算

p=p+r2*r2*(3+2*x);

<2>如果P>=0,绘制下一个点(x+1,y-1),并且计算

p=p+r2*r2*(3+2*point.x)-2*r1*r1*(y-1)

(4)设置新的参数初始值;

p=ry*ry(X0+1/2)*(X0+1/2)+rx*rx*(Y0-1)-rx*rx*ry*ry;

(5)在区域2中的每个Yn为止,从n=0开始,直到y=0时结束。

<1>如果P>0的情况下,下一个目标点为(x,y-1),并且计算

p=p-2rx*rx*(Yn+1)+rx*rx;

<2>如果p<=0的情况下,下一个目标点为(x+1,y-1),并且计算

p=p-2rx*rx*Y(n+1)+2ry*ry*(Xn+1)+rx*rx;

(6)更具对称性原理计算其他3个象限的坐标。

(7)急速拿出中心位置在(x1,y1)的位置x=x+x1;y=y+y1;

2.3、直线的Bresenham算法原理

这种生成直线的算法与数值微分法类似,每次迭代在增量最大方向上均走一步,其方向由增量的正负而定;另一方向上是否也走,取决于计算出来的误差项,误差项所记录的方向同最大增量方向垂直。

下面讨论误差项

,如图1所示。

图1误差项计算示意图

设图1中直线满足:

0

,即:

0

,所以X为最大增量方向,有

-

=1,故有每点的坐标计算:

(4)

因此直线上点的显示坐标为[

round(

)],round(

)表示最靠近y的整数。

从图1可以看出,对于计算出来的(

)点,

的取之为

;计算出来的(

)点,

的取值为

其根据就是因为

更靠近

更靠近

图1中A点为

的中心点,计算BC长度,若值大于0.5,说明在A点之上,应取

,否则取

值。

设误差:

(5)当

,B点在A点上方,有

;当

<0,B点在A点下方,有

由公式(4)(5)得:

(6)

2.4、图形变换基本原理

1、平移变换

平移变换函数如下:

voidglTranslate{fd}(TYPEx,TYPEy,TYPEz);

三个函数参数就是目标分别沿三个轴向平移的偏移量。

这个函数表示用于这三个偏移量生成的矩阵乘以当前矩阵。

当参数是(0.0,0.0,0.0)时,表示对函数glTranslate*()的操作是单位矩阵,也就是对物体没有影响。

2、旋转变换

旋转变换函数如下:

VoidglRota{fd}TYPEangle,TYPEx,TYPEy,TYPEz);

函数中第一个参数是表示目标沿从点(x,y,z)到原点方向逆时针旋转的角度,后三个参数是旋转的方向点坐标。

这个函数表示用这四个参数生成的矩阵乘以当前矩阵。

当角度参数是0.0时,表示对物体没有影响。

3、比例变换

比例变换函数如下:

VoidglScale{fd}(TYPEx,TYPEy,TYPEz);

单个函数参数值就是目标分别沿三个轴方向缩放的比例因子。

这个函数表示用这三个比例因子生成的矩阵乘以当前矩阵。

这个函数能完成沿相应的轴对目标进行拉伸、压缩和反射三项功能。

以参数x为例,若当x大于1.0时,表示沿x方向拉伸目标;若x小于1.0,表示沿x轴方向收缩目标;若x=-1.0表示沿x轴反射目标。

其中参数为负值时表示对目标进行相应轴的反射变换。

三、详细设计

3.1、主程序代码及解释

#include"stdafx.h"

#include"Clock.h"

#include"math.h"

#include"ClockDoc.h"

#include"ClockView.h"

#ifdef_DEBUG

#definenewDEBUG_NEW

#undefTHIS_FILE

staticcharTHIS_FILE[]=__FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

//CClockView

IMPLEMENT_DYNCREATE(CClockView,CView)

BEGIN_MESSAGE_MAP(CClockView,CView)

//{{AFX_MSG_MAP(CClockView)

ON_WM_TIMER()

ON_WM_CREATE()

ON_WM_CONTEXTMENU()

//}}AFX_MSG_MAP

//Standardprintingcommands

ON_COMMAND(ID_FILE_PRINT,CView:

:

OnFilePrint)

ON_COMMAND(ID_FILE_PRINT_DIRECT,CView:

:

OnFilePrint)

ON_COMMAND(ID_FILE_PRINT_PREVIEW,CView:

:

OnFilePrintPreview)

ON_COMMAND(ID_CONTEXT_BK,OnContextBK)

ON_COMMAND(ID_CONTEXT_HOUR,OnContextHour)

ON_COMMAND(ID_CONTEXT_MINUTE,OnContextMinute)

ON_COMMAND(ID_CONTEXT_SECOND,OnContextSecond)

ON_COMMAND(ID_CONTEXT_RESTORE,OnContextRestore)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

//CClockViewconstruction/destruction

CClockView:

:

CClockView()

{//TODO:

addconstructioncodehere

brushColor=RGB(240,255,255);

HourColor=RGB(0,255,0);

MinuteColor=RGB(0,0,255);

SecondColor=RGB(255,0,255);

}

CClockView:

:

~CClockView(){}

BOOLCClockView:

:

PreCreateWindow(CREATESTRUCT&cs)

{//TODO:

ModifytheWindowclassorstylesherebymodifying

//theCREATESTRUCTcs

returnCView:

:

PreCreateWindow(cs);

}

/////////////////////////////////////////////////////////////////////////////

//CClockViewdrawing

voidCClockView:

:

OnDraw(CDC*pDC)

{CClockDoc*pDoc=GetDocument();

ASSERT_VALID(pDoc);

//TODO:

adddrawcodefornativedatahere

//获取客户区

RECTRect;

GetClientRect(&Rect);

//计算椭圆中心位置

intCenterX=Rect.right/2;

intCenterY=Rect.bottom/2;

//取当前时间

CTimeTime=CTime:

:

GetCurrentTime();

CStringstr;

inti,x,y;

CSizesize;

//创建一支黄色的笔,用来画椭圆

CPenPen(PS_SOLID,5,RGB(0,0,0));

//设置当前画笔,并记下以前的画笔

CPen*OldPen=pDC->SelectObject(&Pen);

CBrushbrush(brushColor);

pDC->SelectObject(&brush);

//绘制钟面椭圆

pDC->Ellipse(5,5,Rect.right-5,Rect.bottom-5);

doubleRadians;

//设置字体颜色为红色

pDC->SetTextColor(RGB(255,0,0));

for(i=1;i<=12;i++){

//格式化钟点值

str.Format("%d",i);

size=pDC->GetTextExtent(str,str.GetLength());

Radians=(double)i*6.28/12.0;

//计算钟点放置的位置

x=CenterX-(size.cx/2)+(int)((double)(CenterX-20)*

sin(Radians));

y=CenterY-(size.cy/2)-(int)((double)(CenterY-20)*

cos(Radians));

//绘制钟点

pDC->TextOut(x,y,str);

}

//计算时钟指针的夹角

Radians=(double)Time.GetHour()+(double)Time.GetMinute()/60.0+

(double)Time.GetSecond()/3600.0;

Radians*=6.28/12.0;

//创建时钟指针画笔

CPenHourPen(PS_SOLID,5,HourColor);

pDC->SelectObject(&HourPen);

//绘制时钟指针

pDC->MoveTo(CenterX,CenterY);

pDC->LineTo(CenterX+(int)((double)(CenterX/3)*sin(Radians)),

CenterY-(int)((double)(CenterY/3)*cos(Radians)));

Radians=(double)Time.GetMinute()+(double)Time.GetSecond()/60.0;

Radians*=6.28/60.0;

//创建分钟指针画笔

CPenMinutePen(PS_SOLID,3,MinuteColor);

pDC->SelectObject(&MinutePen);

//绘制分钟指针

pDC->MoveTo(CenterX,CenterY);

pDC->LineTo(CenterX+(int)((double)(CenterX*2)/3)*sin(Radians),

CenterY-(int)((double)(CenterY*2/3)*cos(Radians)));

Radians=(double)Time.GetSecond();

Radians*=6.28/60.0;

//创建秒钟指针画笔

CPenSecondPen(PS_SOLID,1,SecondColor);

pDC->SelectObject(&SecondPen);

//绘制秒钟指针

pDC->MoveTo(CenterX,CenterY);

pDC->LineTo(CenterX+(int)((double)(CenterX*4)/5)*sin(Radians),

CenterY-(int)((double)(CenterY*4)/5*cos(Radians)));

pDC->SelectObject(OldPen);

}

/////////////////////////////////////////////////////////////////////////////

//CClockViewprinting

BOOLCClockView:

:

OnPreparePrinting(CPrintInfo*pInfo)

{//defaultpreparation

returnDoPreparePrinting(pInfo);

}

voidCClockView:

:

OnBeginPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)

{//TODO:

addextrainitializationbeforeprinting

}

voidCClockView:

:

OnEndPrinting(CDC*/*pDC*/,CPrintInfo*/*pInfo*/)

{//TODO:

addcleanupafterprinting

}

////////////////////////////////////////////////////////////////////////////

//CClockViewdiagnostics

#ifdef_DEBUG

voidCClockView:

:

AssertValid()const

{CView:

:

AssertValid();

}

voidCClockView:

:

Dump(CDumpContext&dc)const

{CView:

:

Dump(dc);

}

CClockDoc*CClockView:

:

GetDocument()//non-debugversionisinline

{ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CClockDoc)));

return(CClockDoc*)m_pDocument;

}

#endif//_DEBUG

///////////////////////////////////////////////////////////////////////////

//CClockViewmessagehandlers

voidCClockView:

:

OnTimer(UINTnIDEvent)

{//TODO:

Addyourmessagehandlercodehereand/orcalldefault

InvalidateRect(NULL,true);

UpdateWindow();

CView:

:

OnTimer(nIDEvent);

}

intCClockView:

:

OnCreate(LPCREATESTRUCTlpCreateStruct)

{if(CView:

:

OnCreate(lpCreateStruct)==-1)

return-1;

//TODO:

Addyourspecializedcreationcodehere

SetTimer(1,1000,NULL);

return0;

}

voidCClockView:

:

OnContextMenu(CWnd*pWnd,CPointpoint)

{//TODO:

Addyourmessagehandlercodehere

CMenumenu;

menu.LoadMenu(IDR_CONTEXTMENU);

CMenu*pContextMenu=menu.GetSubMenu(0);

pContextMenu->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,point.x,point.y,AfxGetMainWnd());

}

voidCClockView:

:

OnContextBK()

{brushColor=RGB(255,228,181);

}

voidCClockView:

:

OnContextHour()

{HourColor=RGB(255,0,0);

}

voidCClockView:

:

OnContextMinute()

{MinuteColor=RGB(128,128,0);

}

voidCClockView:

:

OnContextSecond()

{SecondColor=RGB(0,192,255);

}

voidCClockView:

:

OnContextRestore()

{brushColor=RGB(240,255,255);

HourColor=RGB(0,255,0);

MinuteColor=RGB(0,0,255);

SecondColor=RGB(255,0,255);

四、程序运行说明

4.1程序运行结果分析

单击运行,生成一个椭圆表盘时钟,其表盘与各指针颜色各不相同,用右键五个菜单修改表盘与指针颜色,菜单“设置背景色”来改变表盘颜色、菜单“设置时针颜色”来改变时针指针颜色、菜单“设置分针颜色”来改变分针指针颜色、菜单“设置秒针颜色”来改变秒针指针颜色、用“恢复”菜单来还原成表盘与指针原来的颜色。

改变后的颜色与原来颜色也不各不相同,改变后只能是指定的颜色,不足就是没有对话框多种颜色用来选择,颜色有点单一,用恢复菜单可以恢复原来颜色。

因为程序里调用了windows的时间函数,所以显示的时间永远跟电脑时间同步。

此结果的实现是通过MFC方法实现的。

基本上达到了要求,但不足之处仍有很多,因为个人能力有限。

4.2程序运行结果截图

4.2.1开始时运行时效果

4.2.2右键单步修改颜色效果

4.2.3右键修改颜色后效果

五、总结

5.1系统不足

在本次课程设计中,设计方案存在着很多的死板化的实现方法,也是很不人性化的一点,就是生成结果后通过右键改变表盘与指针的颜色的实现方法,只有一种颜色改变的方案,没有设置对话框来设置多种颜色供选择的,所以改编后的颜色比较单一,此为本次设计方案的不足之一;然后就是表盘的形状是椭圆形的,有点不符合常理,因为现实里的时钟都是圆形的,不过个人认为椭圆可以设计出来,圆形的肯定更容易设计,因为圆是椭圆的特殊情况,只要通过修改个别参数就可以改变此效果,此为设计方案不足之二。

再者就是表盘中没有设置分钟小刻度,此为设计方案不足之三。

鉴于个人能力真的有限,所以只能设计出此种级别的效果了。

因为实验重要的只是思想过程,效果的不美观只能是因为学习的知识还远远不够,所以不能设计出像现实里的时钟一样的效果。

5.2改进方案

通过修改我的程序中的右键更改颜色的函数,更改成生成效果是用对话框提示替换颜色的函数就可以达到可以选择改变的颜色了,查找程序中的此函数进行修改,可以达到选择颜色修改的效果。

至于把表盘修改成圆形的,通过修改生成表盘的函数参数就可以达到预期修改效果。

5.3心得体会

在本次课程设计过程中,基本掌握了OpenGL提供的标准库函数,Bresenham画线和画椭圆的方法,了解的很多有关于图形学的知识。

不过都只是皮毛而已,从中锻炼了自己的动手做实验的能力,但同时也让自己看清了自己的水平,以便在以后的生活里多加强有关这方面的学习,从而提升自己在图形学方面的知识水平。

参考文献

1.杨旭等.VisualC++编程篇[M].北京:

电子工业出版社,2004.

2.朱亚平等.OpenGL编程实例[M].北京:

人民邮电出版社,1999.

3.倪明田,吴良芝.计算机图形学[M].北京:

北京大学出版社,2000.

4.彭达等.VisualC++多媒体编程技术[M].北京:

人民邮电出版社,1999.

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2