计算机图形学课程设计实验报告_第1页
计算机图形学课程设计实验报告_第2页
计算机图形学课程设计实验报告_第3页
计算机图形学课程设计实验报告_第4页
计算机图形学课程设计实验报告_第5页
已阅读5页,还剩34页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、精选优质文档-倾情为你奉上计算机图形学课程设计实验报告专心-专注-专业计算机图形学实验报告班级 计算机科学与技术 姓名 学号 年 6 月 2 日实验一 基本图形生成算法一、实验目的: 1、掌握中点Bresenham绘制直线的原理; 2、设计中点Bresenham算法; 3、掌握八分法中点Bresenham算法绘制圆的原理; 4、设计八分法绘制圆的中点Bresenham算法; 5、掌握绘制1/4椭圆弧的上半部分和下半部分的中点Bresenham算法原理; 6、掌握下半部分椭圆偏差判别式的初始值计算方法; 7、设计顺时针四分法绘制椭圆的中点Bresenham算法。二、实验过程:1、 实验描述 实验

2、1:使用中点Bresenham算法绘制斜率为0<=k<=1的直线。 实验2:使用中点Bresenham算法绘制圆心位于屏幕客户区中心的圆。 实验3:使用中点Bresenham算法绘制圆心位于屏幕客户区中心的椭圆。2、实验过程 1)用MFC(exe)建立一个单文档工程; 2)编写对话框,生成相应对象,设置相应变量; 3)在类CLineView中声明相应函数,并在相关的cpp文件中实现; 4)在OnDraw()函数里调用函数实现绘制直线、圆、椭圆; 5)运行程序,输入相应值,绘制出图形。3、 源代码实验1:直线中点Bresenham算法1./ cline.cpp : implement

3、ation file/ cline dialogcline:cline(CWnd* pParent /*=NULL*/): CDialog(cline:IDD, pParent)/AFX_DATA_INIT(cline)m_x0 = 0;m_y0 = 0;m_x1 = 0;m_y1 = 0;/AFX_DATA_INITvoid cline:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(cline)DDX_Text(pDX, IDC_x0, m_x0);DDX_Text(pDX, IDC_y

4、0, m_y0);DDX_Text(pDX, IDC_x1, m_x1);DDX_Text(pDX, IDC_y1, m_y1);/AFX_DATA_MAPBEGIN_MESSAGE_MAP(cline, CDialog)/AFX_MSG_MAP(cline)/AFX_MSG_MAPEND_MESSAGE_MAP()2、 / LineView.hclass CLineView : public CViewpublic:CLineDoc* GetDocument();.void Mbline(double,double,double,double); /直线中点Bresenham函数.3、/ L

5、ine.cpp /*直线中点Bresenham函数*/void CLineView:Mbline(double x0, double y0, double x1, double y1) CClientDC dc(this); COLORREF rgb=RGB(0,0,255); /定义直线颜色为蓝色double x,y,d,k;x=x0; y=y0; k=(y1-y0)/(x1-x0); d=0.5-k;for(x=x0;x<=x1;x+)dc.SetPixel(int)x,(int)y,rgb);if(d<0)y+;d+=1-k;elsed-=k;4、/LineView.cppv

6、oid CLineView:OnDraw(CDC* pDC)CLineDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data herecline a;a.DoModal();/初始化CLineView:Mbline(a.m_x0,a.m_y0,a.m_x1,a.m_y1);实验2:圆中点Bresenham算法 1、/cricle.cpp/ Ccricle dialogCcricle:Ccricle(CWnd* pParent /*=NULL*/): CDialog(Ccricle:ID

7、D, pParent)/AFX_DATA_INIT(Ccricle)m_r = 0;/AFX_DATA_INITvoid Ccricle:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(Ccricle)DDX_Text(pDX, r_EDIT, m_r);/AFX_DATA_MAP 2、/CcircleView.hclass CCcircleView : public CView.public:CCcircleDoc* GetDocument();void CirclePoint(doubl

8、e,double); /八分法画圆函数void Mbcircle(double); /圆中点Bresenham函数. 3、/CcircleView.cppvoid CCcircleView:OnDraw(CDC* pDC)CCcircleDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data hereCcricle r;r.DoModal();CCcircleView:Mbcircle(r.m_r);/画圆4、/CcircleView.cpp/*八分法画圆*/void CCcircle

9、View:CirclePoint(double x,double y)CClientDC dc(this);COLORREF rgb=RGB(0,0,255);dc.SetPixel(int)(300+x),(int)(300+y),rgb);dc.SetPixel(int)(300-x),(int)(300+y),rgb);dc.SetPixel(int)(300+x),(int)(300-y),rgb);dc.SetPixel(int)(300-x),(int)(300-y),rgb);dc.SetPixel(int)(300+y),(int)(300+x),rgb);dc.SetPixe

10、l(int)(300-y),(int)(300+x),rgb);dc.SetPixel(int)(300+y),(int)(300-x),rgb);dc.SetPixel(int)(300-y),(int)(300-x),rgb);/*圆中点Bresenham函数*/void CCcircleView:Mbcircle(double r)double x,y,d;COLORREF rgb=RGB(0,0,255);d=1.25-r;x=0; y=r;for(x=0;x<y;x+)CirclePoint(x,y); /调用八分法画圆子函数if(d<0)d+=2*x+3;elsed+=

11、2*(x-y)+5;y-;实验3:椭圆中点Bresenham算法1、/ellipse1.cpp/ Cellipse dialogCellipse:Cellipse(CWnd* pParent /*=NULL*/): CDialog(Cellipse:IDD, pParent)/AFX_DATA_INIT(Cellipse)m_a = 0;m_b = 0;/AFX_DATA_INITvoid Cellipse:DoDataExchange(CDataExchange* pDX)CDialog:DoDataExchange(pDX);/AFX_DATA_MAP(Cellipse)DDX_Text(

12、pDX, IDC_EDIT1, m_a);DDX_Text(pDX, IDC_EDIT2, m_b);/AFX_DATA_MAP2、/EllipseView.hclass CEllipseView : public CView.public:CEllipseDoc* GetDocument();void EllipsePoint(double,double); /四分法画椭圆void Mbellipse(double a, double b); /椭圆中点Bresenham函数.3、/Ellipse.cpp/*四分法画椭圆*/void CEllipseView:EllipsePoint(dou

13、ble x,double y)CClientDC dc(this);COLORREF rgb=RGB(0,0,255); dc.SetPixel(int)(300+x),(int)(300+y),rgb);dc.SetPixel(int)(300-x),(int)(300+y),rgb);dc.SetPixel(int)(300+x),(int)(300-y),rgb);dc.SetPixel(int)(300-x),(int)(300-y),rgb);/*椭圆中点Bresenham函数*/void CEllipseView:Mbellipse(double a, double b)doubl

14、e x,y,d1,d2;x=0;y=b;d1=b*b+a*a*(-b+0.25);EllipsePoint(x,y);while(b*b*(x+1)<a*a*(y-0.5)/椭圆AC弧段if(d1<0)d1+=b*b*(2*x+3);elsed1+=b*b*(2*x+3)+a*a*(-2*y+2);y-;x+;EllipsePoint(x,y);d2=b*b*(x+0.5)*(x+0.5)+a*a*(y-1)*(y-1)-a*a*b*b;/椭圆CB弧段while(y>0)if(d2<0)d2+=b*b*(2*x+2)+a*a*(-2*y+3);x+;elsed2+=a*

15、a*(-2*y+3);y-;EllipsePoint(x,y);4、/EllipseView.cppvoid CEllipseView:OnDraw(CDC* pDC)CEllipseDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data hereCellipse el;el.DoModal();/初始化CEllipseView:Mbellipse(el.m_a, el.m_b);/画椭圆4、 实结果验实验1:直线中点Bresenham算法实验2:圆中点Bresenham算法实验3:椭

16、圆中点Bresenham算法实验二 有效边表填充算法一、实验目的:1、设计有效边表结点和边表结点数据结构;2、设计有效边表填充算法;3、编程实现有效边表填充算法。2、 实验过程:1、实验描述 下图1 所示多边形覆盖了 12 条扫描线,共有 7 个顶点和 7 条边。7 个顶点分别为:P0(7,8) ,P1(3,12) ,P2(1,7) ,P3(3,1), P4(6,5), P5(8,1), P6(12,9)。在 1024×768 的显示分辩率下,将多边形顶点放大为 P0(500,400) ,P1(350,600) ,P2(250,350),P3(350,50), P4(500,250)

17、, P5(600,50), P6(800,450)。请使用有效边表算法填充该多边形。2、 实验过程 (1)建立AET类和Bucket类; (2)初始化桶,并在建立桶结点时为其表示的扫描线初始化为带头结点的链表; (3)对每个桶结点进行循环,将桶内每个结点的边表合并为有效边表,并进行有效边表循环; (4)按照扫描线从小到大的移动顺序,计算当前扫描线与多边形各边的交点,然后把这些交点按X值递增的顺序进行排序,配对,以确定填充区间; (5)用指定颜色点亮填充区间内的所有像素,即完成填充工作。3、 源代码1、/AET.hclass AET public:AET();virtual AET();doub

18、le x;int yMax;double k;/代替1/kAET *next;/AET.cppAET:AET()AET:AET()2、 /Bucket.h#include "AET.h"class Bucket public:Bucket();virtual Bucket();int ScanLine;AET *p;/桶上的边表指针Bucket *next;/ Bucket.cppBucket:Bucket()Bucket:Bucket()3、/test2.cppvoid CTest2View:Et()/构造边表函数for(int i=0;i<Number;i+)/访

19、问每个顶点CurrentB=HeadB;/从桶链表的头节点开始循环int j=i+1;/边表第二个顶点,Pointi和Pointj构成边if(j=Number)j=0;/保证多边形的闭合if(Pointj.y>Pointi.y)/终点比起点高while(CurrentB->Scanline!=Pointi.y)/在桶内寻找该边的yMinCurrentB=CurrentB->next;/移到下一个桶结点Ei.x=Pointi.x;/计算AET表的值Ei.yMax=Pointj.y;Ei.k=double(Pointj.x-Pointi.x)/(Pointj.y-Pointi.y

20、);/代表1/kEi.next=NULL;CurrentE=CurrentB->p;/获得桶上连接边表的地址if(CurrentB->p=NULL)CurrentE=&Ei;/边表的起始地址CurrentB->p=CurrentE;/第一个边表直接连接到对应的桶中elsewhile(CurrentE->next!=NULL)/如果当前边已连有边结点CurrentE=CurrentE->next;/移动指针到当前边的最后一个结点CurrentE->next=&Ei;/把当前边接上去if(Pointj.y<Pointi.y)/终比起点低wh

21、ile(CurrentB->Scanline!=Pointj.y)/在桶内寻找该边的yMinCurrentB=CurrentB->next;/移到下一个桶结点Ei.x=Pointj.x;/计算AET表的值Ei.yMax=Pointi.y;Ei.k=double(Pointi.x-Pointj.x)/(Pointi.y-Pointj.y);/代表1/kEi.next=NULL;CurrentE=CurrentB->p;/获得桶上连接边表的地址if(CurrentE=NULL)CurrentE=&Ei;/边表的起始地址CurrentB->p=CurrentE;/第一

22、个边表直接连接到对应的桶中elsewhile(CurrentE->next!=NULL)/如果当前边已连有边结点CurrentE=CurrentE->next;/移动指针到当前边的最后一个结点CurrentE->next=&Ei;/把当前边接上去CurrentB=NULL;CurrentE=NULL;void CTest2View:AddEdge(AET *NewEdge)/插入临时边表函数T1=HeadE;if(T1=NULL)/边表为空,将边表置为TempEdgeT1=NewEdge;HeadE=T1;elsewhile(T1->next!=NULL)/边表

23、不为空,将TempEdge连在该边之后T1=T1->next;T1->next=NewEdge;void CTest2View:EdegeOrder()/对边表进行排序函数T1=HeadE;if(T1=NULL)return;if(T1->next=NULL)/如果该边表没有再连边表return;/桶结点只有一条边,不需要排序elseif(T1->next->x<T1->x)/边表按x值排序T2=T1->next;T1->next=T2->next;T2->next=T1;HeadE=T2; T2=HeadE; T1=HeadE

24、->next; while(T1->next!=NULL)/继续两两比较相连的边表的x值,进行排序 if(T1->next->x<T1->x) T2->next=T1->next; T1->next=T1->next->next; T2->next->next=T1;T2=T2->next; else T2=T1; T1=T1->next; void CTest2View:PolygonFill()/多边形填充函数CClientDC dc(this);COLORREF rgb=RGB(0,0,255);

25、HeadE=NULL;for(CurrentB=HeadB;CurrentB!=NULL;CurrentB=CurrentB->next)/访问所有桶结点for(CurrentE=CurrentB->p;CurrentE!=NULL;CurrentE=CurrentE->next)/桶中所有结点AET *TempEdge= new AET;TempEdge->x=CurrentE->x;TempEdge->yMax=CurrentE->yMax; TempEdge->k=CurrentE->k; TempEdge->next=NULL

26、; AddEdge(TempEdge);/将该边插入临时Aet表EdegeOrder();/边表按照x递增的顺序存放 T1=HeadE;/根据ymax抛弃扫描完的边结点if(T1=NULL)return;while(CurrentB->Scanline>=T1->yMax)/放弃该结点,Aet表指针后移,下闭上开T1=T1->next;HeadE=T1;if(HeadE=NULL)return;if(T1->next!=NULL)T2=T1;T1=T2->next;while(T1!=NULL)if(CurrentB->Scanline>=T1-

27、>yMax)/跳过一个结点 T2->next=T1->next; T1->next=NULL; T1=T2->next;elseT2=T1;T1=T2->next;BOOL In=false;/设置一个BOOL变量In,初始值为假double xb,xe;/扫描线的起点和终点for(T1=HeadE;T1!=NULL;T1=T1->next)/填充扫描线和多边形相交的区间if(In=false)xb=T1->x;In=true;/,每访问一个结点,把In值取反一次else/如果In值为真,则填充从当前结点的x值开始到下一个结点的x值结束的区间xe

28、=T1->x-1;/左闭右开CClientDC dc(this);for(double x=xb;x<=xe;x+)dc.SetPixel(int(x),CurrentB->Scanline,rgb);/填充 Sleep(1);/延时1ms,提高填充过程的可视性 In=FALSE;for(T1=HeadE;T1!=NULL;T1=T1->next)/边连贯性 T1->x=T1->x+T1->k;/x=x+1/kdelete HeadB;delete CurrentB;delete CurrentE;delete HeadE;/*初始化桶*void CT

29、est2View:CreatBucket() int ScanMax,ScanMin;ScanMax = ScanMin = Point0.y;for(int i=1;i<Number;i+)if(Pointi.y<ScanMin)ScanMin = Pointi.y; /扫描线的最小值if(Pointi.y>ScanMax)ScanMax = Pointi.y; /扫描线的最大值for( i=ScanMin;i<=ScanMax;i+) /建立桶节点if(ScanMin = i) /桶头结点HeadB = new Bucket; /建立桶的头结点CurrentB = HeadB; /CurrentB为Bucket当前节点指针CurrentB->Scanline = ScanMin;CurrentB->p = NULL; /没有连接边链表CurrentB->next = NULL;else /建立桶的其它节点CurrentB->nex

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论