计算机图形学实验二 基本图形_第1页
计算机图形学实验二 基本图形_第2页
计算机图形学实验二 基本图形_第3页
计算机图形学实验二 基本图形_第4页
计算机图形学实验二 基本图形_第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

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

文档简介

1、实验二 基本图形(元)生成技术(一) 直线生成算法一、实验目的 在一个图形系统中,基本图形(也称为图元、图素等)的生成技术是最基本的,任何复杂的图形都是由基本图形组成的,基本图形生成的质量直接影响该图形系统绘图的质量。所以,需要设计出精确的基本图形生成算法,以确保图形系统绘图的精确性。本次实验的目的就是验证直线生成的三种扫描算法,并要求对基本算法进行扩充和改进,包括:利用Visual C+实现三种直线生成算法,验证算法的正确性;二、实验任务1 理解三种直线生成算法思想,写出实现程序;2 添加鼠标功能,实现交互式画直线程序;3 将10个像素作为步距单位,编出Bresenham算法的示例。三、基本

2、知识和实验步骤任务一:实现DDA画线程序实验步骤:1 建立一个DDALine的工程文件;2 添加ddaline()成员函数方法:在工作区中选择CLASSVIEW类窗口,右击CDDAlineView类,选择“add member function”,定义如下的成员函数:void ddaline(CDC* pDC,int x0,int y0,int x1,int y1,COLORREF color);3 编写自定义的成员函数ddaline()程序 void CDDALineView:ddaline(CDC* pDC, int x0, int y0, int x1, int y1, COLORREF

3、 color) int length,i; float x,y,dx,dy; length=abs(x1-x0); if (abs(y1-y0)>length) length=abs(y1-y0); dx=(x1-x0)/length; dy=(y1-y0)/length; x=x0+0.5;y=y0+0.5; for (i=1;i<=length;i+) pDC->SetPixel(int)x,(int)y,color); x=x+dx;y=y+dy; 4编写OnDraw()函数void CDDALineView:OnDraw(CDC* pDC)CDDALineDoc* p

4、Doc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data here ddaline(pDC,100,100,400,100,RGB(255,0,0); ddaline(pDC,400,100,400,400,RGB(0,255,0); ddaline(pDC,400,400,100,400,RGB(0,0,255); ddaline(pDC,100,400,100,100,RGB(255,255,0); ddaline(pDC,100,100,400,400,RGB(255,0,255); ddal

5、ine(pDC,100,400,400,100,RGB(0,255,255);5编译、调试和运行程序,查看程序结果。任务二、放大10倍后,算法演示程序 先画出(100,100)到(600,400)大小为10的网格,然后从(100,100)以10为单位,计算出直线上各个像素位置。步骤:1 建立DDA2Line工程;2 在OnDraw()函数中画出网格,并调用DDA2Line()函数 void CDDA2LineView:OnDraw(CDC* pDC)CDDA2LineDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw co

6、de for native data here/画网格int gi,gj;/画横线pDC->TextOut(90,90,"(100,100)");pDC->MoveTo(100,100);for(gj=100;gj<=400;gj=gj+10) pDC->MoveTo(100,gj);pDC->LineTo(600,gj);/画竖线 pDC->MoveTo(100,100);for (gi=100;gi<=600;gi=gi+10) pDC->MoveTo(gi,100);pDC->LineTo(gi,400); pDC

7、->TextOut(590,410,"(600,400)");/画出像素点DDA2line(pDC,100,100,600,400,RGB(255,0,0);3添加DDA2Line()成员函数方法:在工作区中选择CLASSVIEW类窗口,右击CDDAlineView类,选择“add member function”,定义如下的成员函数:void DDA2Line(CDC* pDC,int x0,int y0,int x1,int y1,COLORREF color);4.编写DDA2Line()函数 void CDDA2LineView:DDA2line(CDC *p

8、DC, int x0, int y0, int x1, int y1, COLORREF color) int length,i,tx,ty; float x,y,dx,dy; length=abs(x1-x0); if (abs(y1-y0)>length) length=abs(y1-y0); dx=(float)(x1-x0)/length; dy=(float)(y1-y0)/length; /char tbuf20; /sprintf(tbuf,"dx,dy=%f,%f",dx,dy); /AfxMessageBox(tbuf); x=x0;y=y0; fo

9、r (i=0;i<=length;i=i+10) tx=(int)(x+5)/10)*10; ty=(int)(y+5)/10)*10; pDC->SetPixel(tx,ty,color); pDC->Ellipse(tx-5,ty-5,tx+5,ty+5); x=x+dx*10;y=y+dy*10; 5.调试、运行程序任务三、加入鼠标功能,实现交互式画直线 第一步:建立DDAMouseLine工程文件;第二步:向视图类中添加自定义的成员变量 用鼠标右键单击视图类,选择“Add Member Variable”,添加下面三个成员变量。proctected : CPoint

10、m_p1; / 起点 CPoint m_p2; /终点 int m_ist; /区别,m_ist=0,表示直线起点, /m_ist=1,表示直线终点 第三步:向视图类中添加自定义的成员函数原型: public: void DDAMouseLine(CDC *pDC, int x0, int y0, int x1, int y1, COLORREF color);第四步:在视图类CPP文件的构造函数中初始化成员变量。 视图类的构造函数名与该视图类的名字相同。在视图类中选择构造函数,如:CDDAMouseLineView(),用鼠标左键双击,输入下面程序代码:CDDAMouseLineView:C

11、DDAMouseLineView()/ TODO: add construction code here m_p1.x=0; m_p1.y=0; /起点 m_p2.x=0; m_p2.y=0; /终点 m_ist=0; /0,第1点;1,第2点;第五步:在视图类的OnDraw()函数中加入下列代码,实现视图绘图。 void CMouseSpringView:OnDraw(CDC* pDC)CMouseSpringDoc* pDoc = GetDocument();ASSERT_VALID(pDoc); / TODO: add draw code for native data herepDC-

12、>SelectStockObject(NULL_BRUSH);DDAMouseLine(pDC,m_p1.x,m_p1.y,m_p2.x,m_p2.y,RGB(255,0,0); / 调用自定义的成员函数,用鼠标画直线第六步:向视图类中添加鼠标OnLButtonDown()函数消息响应函数,并输入鼠标处理程序代码。void CMouseSpringView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCDC *pDC=GetDC

13、(); pDC->SelectStockObject(NULL_BRUSH);if (!m_ist) /是起点m_p1=m_p2=point; /纪录第一次单击鼠标位置,定起点m_ist+;elsem_p2=point; /记录第二次单击鼠标的位置,定终点的点m_ist-; / 为新绘图作准备DDAMouseLine(pDC,m_p1.x,m_p1.y,m_p2.x,m_p2.y,RGB(255,0,0); /绘制新直线ReleaseDC(pDC); /释放设备环境CView:OnLButtonDown(nFlags, point);第七步:添加成员函数的程序代码。 void CDDAM

14、ouseLineView:DDAMouseLine(CDC *pDC, int x0, int y0, int x1, int y1, COLORREF color) int length,i; float x,y,dx,dy; length=abs(x1-x0); if (abs(y1-y0)>length) length=abs(y1-y0); dx=(float)(x1-x0)/length; dy=(float)(y1-y0)/length; x=x0+0.5;y=y0+0.5; for (i=1;i<=length;i+) pDC->SetPixel(int)x,(

15、int)y,color); x=x+dx;y=y+dy; /pDC->MoveTo(x0,y0);/pDC->LineTo(x1,y1);第八步:编译运行程序,验证运行结果。程序改进,添加橡皮筋绘图技术,实现交互式画直线。 向视图类中添加鼠标OnMouseMove ()函数消息响应函数,并输入鼠标处理程序代码。void CDDAMouseLineView:OnMouseMove(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCDC *pDC=GetDC

16、(); int nDrawmode=pDC->SetROP2(R2_NOT); /设置异或绘图模式,并保存原来绘图模式pDC->SelectStockObject(NULL_BRUSH);if(m_ist=1)CPoint prePnt,curPnt; prePnt=m_p2; /获得鼠标所在的前一位置curPnt=point;/绘制橡皮筋线DDAMouseLine(pDC,m_p1.x,m_p1.y,prePnt.x,prePnt.y,RGB(255,0,0);/DrawCircle(pDC,m_bO,prePnt); /用异或模式重复画圆,擦出所画的圆DDAMouseLine(

17、pDC,m_p1.x,m_p1.y,curPnt.x,curPnt.y,RGB(255,0,0); /DrawCircle(pDC,m_bO,curPnt); /用当前位置作为圆周上的点画圆m_p2=point; pDC->SetROP2(nDrawmode); /恢复原绘图模式ReleaseDC(pDC); /释放设备环境CView:OnMouseMove(nFlags, point);四、实验结果和分析1 查看实验结果,验证算法的正确性;2 对程序进行分析和比较,你还能提出哪些改进和扩充?例如:(1)线刷子绘制直线和圆;(2)方形刷子绘制直线和圆;(3)虚线和点划线的绘制;五、实验总

18、结 总结从本次实验中学到了那些知识点或者有哪些感受?实验三 基本图形(元)生成技术(二) 圆、椭圆生成算法(4学时)一、实验目的编写圆和椭圆的扫描转换算法程序,验证算法的正确性。二、实验任务1 编写中点画圆法的扫描转换程序,考虑原点在(x0,y0)处程序的改动;2 添加鼠标程序,实现交互式画圆;3 编写中点画椭圆法的扫描转换程序;4 添加鼠标程序,实现交互式画椭圆;三、实验内容任务一:中点画圆法的扫描转换算法编写中点画圆法的扫描转换程序,考虑原点在(x0,y0)处程序的改动;分析:考虑圆心不再原点,设圆心坐标为(x0,y0)。通过平移坐标原点到圆心,则第二个8分圆上一点p(x,y),其原始坐标

19、为 x=x+x0 y=y+y0 即p1(x0 +x, y+y0)其它7个对称点分别是:p2(x0+y,y+x0), p3 (x0+y,y0-x),p4 (x0+x,y0-y),p5 (x0-x,y0-y),p6 (x0-y,y0-x),p7 (x0-y,y0+x),p8 (x0-x,y0+y)O(0,0)YX (x0,y0)R (x0+R,y0) p(x,y)XY p1(x0 +x, y+y0) p2(x0+y,y+x0) p3 (x0+y,y0-x) p4 (x0+x,y0-y)) p5 (x0-x,y0-y) p6 (x0-y,y0-x) p7 (x0-y,y0+x) p8 (x0-x,y

20、0+y)算法程序如下:MidpointCircle(int x0,int y0,int r, int color) int x,y;float d;x=0;y=r;d=1.25-r;CirPot(x0,y0,x,y,color);while (x<=y) if(d<0) d+=2*x+3; x+; else d+=2*(x-y)+5; x+; y-; CirPot(x0,y0,x,y,color); /* while*/ /* MidpointCiecle */ int CirPot(int x0,int y0,int x,int y,int color) Setpixel(x0+

21、x),(y0+y); Setpixel(x0+y),(y0+x); Setpixel(x0+y),(y0-x); Setpixel(x0+x),(y0-y); Setpixel(x0-x),(y0-y); Setpixel(x0-y),(y0-x); Setpixel(x0-y),(y0+x); Setpixel(x0-x),(y0+y);程序实现步骤:(1) 建立MidPointCircle工程文件;(2) 右击CMidPointCircleView类,建立成员函数 void MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF co

22、lor) int CirPot(CDC *pDC,int x0, int y0, int x, int y, COLORREF color) (3) 编写成员函数代码,程序如下:void CMidPointCircleView:MidpointCircle(CDC *pDC,int x0, int y0, int r, COLORREF color) /实现中点Bresenham画圆int CMidPointCircleView:CirPot(CDC *pDC,int x0, int y0, int x, int y, COLORREF color) pDC->SetPixel(x0+x

23、),(y0+y),color); pDC->SetPixel(x0+y),(y0+x),color); pDC->SetPixel(x0+y),(y0-x),color); pDC->SetPixel(x0+x),(y0-y),color); pDC->SetPixel(x0-x),(y0-y),color); pDC->SetPixel(x0-y),(y0-x),color); pDC->SetPixel(x0-y),(y0+x),color); pDC->SetPixel(x0-x),(y0+y),color);return 0;(4)编写OnDr

24、aw(CDC* pDC)函数,程序如下:void CMidPointCircleView:OnDraw(CDC* pDC)CMidPointCircleDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data hereMidpointCircle(pDC,100, 100, 10, RGB(255,0,0); MidpointCircle(pDC,500, 300, 60, RGB(255,255,0);(6) 编译、运行程序,查看结果。任务二:添加鼠标程序,实现交互式画圆 在任务1的基

25、础上,完成下列步骤: (1)向视图类中添加自定义的成员变量 用鼠标右键单击视图类,选择“Add Member Variable”,添加下面三个成员变量。proctected : int m_r; / 半径CPoint m_bO; / 圆心 CPoint m_bR; /圆上的点 int m_ist; /圆心与圆周上点的区别,m_ist=0,表示鼠标左击点为圆心, /m_ist=1,表示鼠标左击点为圆周上的点 (2)在视图类CPP文件的构造函数中初始化成员变量CMidPointCircleMouseView:CMidPointCircleMouseView()/ TODO: add constru

26、ction code here m_bO.x=0; m_bO.y=0; /圆心 m_bR.x=0; m_bR.y=0; /圆上的点 m_ist=0; /圆心与圆上的点区别 m_r=0; /圆的半径(3)向视图类中添加自定义的成员函数原型: public: int ComputeRadius(CPoint cenp,CPoint ardp);添加成员函数的程序代码:int CMouseSpringView:ComputeRadius(CPoint cenp, CPoint ardp) int dx=cenp.x-ardp.x; int dy=cenp.y-ardp.y; /sqrt()函数的调用

27、,在头文件中加入#include "math.h" return (int)sqrt(dx*dx+dy*dy);(4)向视图类中添加两个鼠标消息响应函数,并输入鼠标处理程序代码。 具体操作方法与鼠标示例1方法相同。一个是OnLButtonDown()函数,另一个是OnMouseMove()函数。程序如下:void CMidPointCircleMouseView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default CDC

28、 *pDC=GetDC(); pDC->SelectStockObject(NULL_BRUSH);if (!m_ist) /绘制圆m_bO=m_bR=point; /纪录第一次单击鼠标位置,定圆心m_ist+;elsem_bR=point; /记录第二次单击鼠标的位置,定圆周上的点m_ist-; / 为新绘图作准备m_r=ComputeRadius(m_bO,m_bR);MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0);ReleaseDC(pDC); /释放设备环境CView:OnLButtonDown(nFlags, point);v

29、oid CMidPointCircleMouseView:OnMouseMove(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call defaultCDC *pDC=GetDC(); int nDrawmode=pDC->SetROP2(R2_NOT); /设置异或绘图模式,并保存原来绘图模式pDC->SelectStockObject(NULL_BRUSH);if(m_ist=1)CPoint prePnt,curPnt; prePnt=m_bR; /获得鼠标所在的前一

30、位置curPnt=point;/绘制橡皮筋线 m_r=ComputeRadius(m_bO,prePnt); MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0);/用异或模式重复画圆,擦出所画的圆/DrawCircle(pDC,m_bO,prePnt); m_r=ComputeRadius(m_bO,curPnt); MidpointCircle(pDC,m_bO.x,m_bO.y,m_r,RGB(255,0,0); /用当前位置作为圆周上的点画圆m_bR=point; pDC->SetROP2(nDrawmode); /恢复原绘图模式Re

31、leaseDC(pDC); /释放设备环境CView:OnMouseMove(nFlags, point);任务三:编写中点画椭圆法的扫描转换程序程序实现步骤:(1) 建立MidPointEllise工程文件;(2)右击CMidPointElliseView类,建立成员函数 void MidpointEllise(CDC *pDC, int x0, int y0, int a, int b, COLORREF color) (3) 编写成员函数代码,程序如下:void CMidPointEllipseView:MidpointEllise(CDC *pDC, int x0, int y0, i

32、nt a, int b, COLORREF color) /实现中点Bresenham画椭圆 (4) 编写OnDraw()函数void CMidPointEllipseView:OnDraw(CDC* pDC)CMidPointEllipseDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);/ TODO: add draw code for native data hereMidpointEllise(pDC, 300, 200, 50, 20, RGB(255,0,0);(5)编译、运行程序。任务四:添加鼠标程序,实现交互式画椭圆程序实现步骤:(1)(

33、3)同上,建立MidPointElliseMouse工程文件。(4)添加成员变量protected:int b;int a; int m_ist;CPoint CenterPoint;CPoint RightBottom;CPoint LeftTop;(5)在构造函数中赋初值CMidPointElliseMouseView:CMidPointElliseMouseView()/ TODO: add construction code hereLeftTop.x=0;LeftTop.y=0; / 左上角坐标初值 RightBottom.x=0;RightBottom.y=0; / 右下角坐标初值

34、 CenterPoint.x=0;CenterPoint.y=0; / 中心点坐标初值a=0; b=0; /长轴和短轴长度 m_ist=0; /0:表示第一点,1:表示第二点(6) 添加OnLButtonDown()函数void CMidPointElliseMouseView:OnLButtonDown(UINT nFlags, CPoint point) / TODO: Add your message handler code here and/or call default CDC *pDC=GetDC(); pDC->SelectStockObject(NULL_BRUSH);if (!m_ist) /第一点,左上角LeftTop=RightBottom=point; /纪录第一次单击鼠标位置m_ist+;elseRightBottom=point; /记录第二次单击鼠标的位置m_ist-; / 为新绘图作准备CenterPoint.x=(LeftTop.x+RightBottom.x)/2; CenterPoint.y=(LeftTop.y+RightBottom.y)/2;a=(int)abs(RightBottom.x-LeftTop.x)/2;b=(int)abs(

温馨提示

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

评论

0/150

提交评论