欢迎来到冰豆网! | 帮助中心 分享价值,成长自我!
冰豆网
全部分类
  • IT计算机>
  • 经管营销>
  • 医药卫生>
  • 自然科学>
  • 农林牧渔>
  • 人文社科>
  • 工程科技>
  • PPT模板>
  • 求职职场>
  • 解决方案>
  • 总结汇报>
  • 党团工作>
  • ImageVerifierCode 换一换
    首页 冰豆网 > 资源分类 > DOCX文档下载
    分享到微信 分享到微博 分享到QQ空间

    实验三 图形裁剪算法实现.docx

    • 资源ID:10625745       资源大小:108.10KB        全文页数:24页
    • 资源格式: DOCX        下载积分:10金币
    快捷下载 游客一键下载
    账号登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录
    二维码
    微信扫一扫登录
    下载资源需要10金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP,免费下载
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    实验三 图形裁剪算法实现.docx

    1、实验三 图形裁剪算法实现实验三 图形裁剪算法实现实验学时:2学时实验类型:验证型 实验要求:必修在使用计算机处理图形信息时,计算机内部存储的图形往往比较大,而屏幕显示的只是图的一部分。因此需要确定图形中哪些部分落在显示区之内,哪些落在显示区之外,以便只显示落在显示区内的那部分图形。这个选择过程称为裁剪。最简单的裁剪方法是把各种图形扫描转换为点之后,再判断各点是否在窗内。但那样太费时,一般不可取。这是因为有些图形组成部分全部在窗口外,可以完全排除,不必进行扫描转换。所以一般采用先裁剪再扫描转换的方法,多边形裁剪示意图,如图1-1所示。(a)裁剪前 (b)裁剪后图1-1 多边形裁剪示意图直线裁剪

    2、1直线和窗口的关系直线和窗口的关系如图1-2所示,可以分为如下3类:图1-2 直线与窗口的关系(1)整条直线在窗口内。此时,不需剪裁,显示整条直线。(2)整条直线在窗口外,此时,不需剪裁,不显示整条直线。(3)部分直线在窗口内,部分直线在窗口外。此时,需要求出直线与窗框的交点,并将窗口外的直线部分剪裁掉,显示窗口内的直线部分。直线剪裁算法有两个主要步骤。首先将不需剪裁的直线挑出,即删去在窗外的直线。然后,对其余直线,逐条与窗框求交点,并将窗口外的部分删去。2Cohen-Sutherland直线剪裁算法以区域编码为基础,将窗口及其周围的8个方向以4 bit的二进制数进行编码。如图1-3所示的编码

    3、方法将窗口及其邻域分为5个区域。(1)内域:区域(0000)。(2)上域:区域(1001,1000,1010)。(3)下域:区域(0101, 0100, 0110)。(4)左域:区域(1001, 0001, 0101)。图1-3 窗口及其邻域的5个区域及与直线的关系(5)右域:区域(1010, 0010, 0110)。当线段的两个端点的编码的逻辑“与”非零时,线段显然为不可见的。对某线段的两各端点的区号进行位与运算,可知这两个端点是否同在视区的上、下、左、右。算法的主要思想是,对每条直线,如P1P2利用以下步骤进行判断: 对直线两端点P1、P2编码分别记为C1(P1)=a1, b1, c1,

    4、d1,C2(P2)=a2, b2, c2, d2其中,ai、bi、ci、di取值范围为1, 0,i1, 2。 如果ai=bi=ci=di=0,则显示整条直线,取出下一条直线,返回步骤;否则,进入步骤。 如果|a1a2|=1,则求直线与窗上边(y=ywmax)的交点,并删去交点以上部分。如果|b1b2|=1,|c1c2|1,|d1d2|=1,进行类似处理。 返回步骤判断下一条直线。多边形裁剪多边形裁剪算法的关键在于,通过剪裁,要保持窗口内多边形的边界部分,而且要将窗框的有关部分按一定次序插入多边形的保留边界之间,从而使剪裁后的多边形的边仍然保持封闭状态,以便填色算法得以正确实现,多边形裁剪原理示

    5、意图,如 图1-4所示。(a)剪裁的多边形 (b)按直线剪裁的多边形 (c)按多边形剪裁后的多边形图1-4 多边形裁剪原理示意图1(1)Sutherland-Hodgman算法思路:将多边形的各边先相对于窗口的某一条边界进行裁剪,然后将裁剪结果再与另一条边界进行裁剪,如此重复多次,便可得到最终结果。(2)实现方法: 设置两个表。输入顶点表(向量)用于存放被裁剪多边形的顶点p1pm。输出顶点表(线性链表)用于存放裁剪过程中间结果的顶点q1qn。 输入顶点表中各顶点要求按一定顺序排列,一般可采用顺时针或逆时针方向。 相对于裁剪窗口的各条边界,按顶点表中的顺序,逐边进行裁剪。(3)具体操作步骤如下:

    6、 Pi若位于边界线的可见一侧,则Pi送给输出顶点表。 Pi若位于边界线的不可见一侧,则将其舍弃。 除第一个顶点外,还要检查每一个Pi和前一顶点Pi1是否位于窗口边界的同一侧,若不在同一侧,则需计算出交点送给输出顶点表。 最后一个顶点Pn则还要与P1一起进行同样的检查。如下图1-6所示,是上述多边形裁剪的原理示意图。图1-6 多边形裁剪原理示意图2图形裁剪编程1程序设计功能说明如图1-7所示为图形裁剪的实用程序运行时的主界面,首先根据界面提示,在用户区双击,出现所需要裁剪的各种线段,再单击菜单中“图形裁剪”,可选择其下拉菜单的各图形裁剪选项完成各种图形裁剪(在窗口中红矩形框外的线段或多边形被裁减

    7、掉)。 图1-7 “图形裁剪”程序主界面2程序设计步骤程序“图形裁剪”的设计步骤如下:(1)创建工程名称为“图形裁剪”单文档应用程序框架(参看上面单文档应用程序框架的建立)。(2)编辑菜单资源。图1-8 图形裁剪切界面设计如图1-8所示的菜单项。在工作区的ResourceView标签中,单击Menu项左边“+”,然后双击其子项IDR_MAINFRAME,并根据表1-9中的定义编辑菜单资源。表1-9 菜单资源表菜单标题菜单项标题标示符ID图形裁剪线段裁剪ID_CLIPLINE多边形裁剪ID_CLIPPOLYGON(3)添加消息处理函数。利用ClassWizard(建立类向导)为应用程序添加与菜单

    8、项相关的消息处理函数,ClassName栏中选择CMyView,根据表1-10建立如下的消息映射函数,ClassWizard会自动完成有关的函数声明。表1-10 菜单项的消息处理函数菜单项ID消 息消息处理函数ID_CLIPLINECONMMANOnIDTRANSLATIONID_CLIPPOLYGONCONMMANOnIDROTATION(4)添加代码,在图形裁剪应用程序的相应文件中添加如下黑体字部分代码。 在“图形裁剪View.h”文档中的适当位置添加定义存储线段端点的数组。class CMyView : public CViewprotected: / create from seria

    9、lization only Mpublic: CPoint ptsetN; M; 在“图形裁剪View.cpp”文档中的适当位置手工添加以下黑体部分代码。 #include stdafx.h #include 图形裁剪.h M #endif #define LEFT 1 #define RIGHT 2 #define BOTTOM 4 #define TOP 8 #define XL 100 #define XR 300 #define YT 100 #define YB 250/void CMyView:OnDraw(CDC* pDC)/功能为程序开始呈现下面的界面 CMyDoc* pDoc

    10、 = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here CPen newpen(PS_SOLID,1,RGB(255,0,0); CPen *old=pDC-SelectObject(&newpen); pDC-Rectangle(CRect(XL,YT,XR,YB); /剪切窗口,可通过修改上面的对应数据修改裁剪矩形框 /需要剪切的各种线段,可通过修改数据修改线段(见图1-9)ptset0=CPoint(120,150);ptset1=CPoint(170,110);ptset2=CPo

    11、int(0,190); ptset3=CPoint(350,150); ptset4=CPoint(0,250);ptset5=CPoint(150,230);ptset6=CPoint(200,50);ptset7=CPoint(120,150); 图1-9 线段剪切ptset10=CPoint(20,150); ptset11=CPoint(170,110);ptset12=CPoint(250,150);ptset13=CPoint(200,230);ptset14=CPoint(20,150); pDC-TextOut(0,0,双击, 出现要剪切的线段);pDC-TextOut(0,0

    12、,双击鼠标右键, 出现要剪切的多边形); pDC-SelectObject(old);/处理双击左键消息函数,得到要进行裁剪的直线段void CMyView:OnLButtonDblClk(UINT nFlags, CPoint point) CDC* pDC=GetDC(); CPen newpen(PS_SOLID,1,RGB(255,0,0); CPen *old=pDC-SelectObject(&newpen); flag=1; for(int i=0;iMoveTo(ptseti); pDC-LineTo(ptseti+1); i+; CView:OnLButtonDblClk(n

    13、Flags, point);void CMyView:OnClipline() /线段裁剪消息处理函数图1-10 警告图示窗 CDC* pDC=GetDC(); CPen newpen(PS_SOLID,1,RGB(0,255,0); CPen *old=pDC-SelectObject(&newpen); if(flag!=1) MessageBox(请先双击,警告!);(如图1-10所示) else float x,y,x1,x2,y1,y2; int i; int code1,code2; RedrawWindow(); / 求两端点所在区号code for(i=0;iN;i+,i+)

    14、int c=0;图1-11 线段剪切结果 if(ptseti.xXR)c=c|RIGHT; if(ptseti.yYB) c=c|BOTTOM; else if(ptseti.yYT) c=c|TOP; code1=c; c=0; if(ptseti+1.xXR) c=c|RIGHT; if(ptseti+1.yYB) c=c|BOTTOM; else if(ptseti+1.yMoveTo(ptseti.x,ptseti.y); pDC-LineTo(ptseti+1.x,ptseti+1.y); if(code1=0&code2=0) pDC-MoveTo(ptseti.x,ptseti.

    15、y); pDC-LineTo(ptseti+1.x,ptseti+1.y); if(code1=0&code2!=0) pDC-MoveTo(ptset0.x,ptset0.y); if(LEFT&code2)!=0) /线段与左边界相交 x=XL; y=ptseti.y+(ptseti+1.y-ptseti.y)*(XL-ptseti.x)/(ptseti+1.x-ptseti.x); else if(RIGHT&code2)!=0) /线段与右边界相交 x=XR; y=ptseti.y+(ptseti+1.y-ptseti.y)*(XR-ptseti.x)/(ptseti+1.x-ptse

    16、ti.x); else if(BOTTOM&code2)!=0) /线段与下边界相交 y=YB; x=ptseti.x+(ptseti+1.x-ptseti.x)*(YB-ptseti.y)/(ptseti+1.y-ptseti+1.y); else if(TOP&code2)!=0) /线段与上边界相交 y=YT; x=ptseti.x+(ptseti+1.x-ptseti.x)*(YT-ptseti.y)/(ptseti+1.y-ptseti.y); ptseti+1.x=x; ptseti+1.y=y; pDC-LineTo(ptseti+1.x,ptseti+1.y); if(code

    17、1!=0&code2=0) pDC-MoveTo(ptseti+1.x,ptseti+1.y); if(LEFT&code1)!=0) /线段与左边界相交 x=XL; y=ptseti.y+(ptseti+1.y-ptseti.y)*(XL-ptseti.x)/(ptseti+1.x-ptseti.x); else if(RIGHT&code1)!=0) /线段与右边界相交 x=XR; y=ptseti.y+(ptseti+1.y-ptseti.y)*(XR-ptseti.x)/(ptseti+1.x-ptseti.x); else if(BOTTOM&code1)!=0) /线段与下边界相交

    18、 y=YB; x=ptseti.x+(ptseti+1.x-ptseti.x)*(YB-ptseti.y)/(ptseti+1.y-ptseti+1.y); else if(TOP&code1)!=0) /线段与上边界相交 y=YT; x=ptseti.x+(ptseti+1.x-ptseti.x)*(YT-ptseti.y)/(ptseti+1.y-ptseti.y); ptseti.x=x; ptseti.y=y; pDC-LineTo(ptseti.x,ptseti.y); 图1-12 多边形剪切/处理双击右键出现要裁剪的多边形(见图1-12)void CMyView:OnRButton

    19、DblClk(UINT nFlags, CPoint point) CDC* pDC=GetDC(); CPen newpen(PS_SOLID,1,RGB(255,0,0); CPen *old=pDC-SelectObject(&newpen); flag=2; pDC-MoveTo(ptset10); for(int i=1;iLineTo(ptset1i); CView:OnRButtonDblClk(nFlags, point);void CMyView:OnClippolygon() 多边形裁剪(见图1-13)图1-15 警告提示窗 CDC* pDC=GetDC(); CPen n

    20、ewpen(PS_SOLID,1,RGB(0,255,0); CPen *old=pDC-SelectObject(&newpen);if(flag!=1) MessageBox(请先双击鼠标右键,警告!);(见图1-14) else int i,k; int code1,code2; int M=5;图1-13 多边形剪切结果 RedrawWindow(); / 求两端点所在区号code k=0; for(i=0;iM;i+) int c=0; if(ptset1i.xXL)c=0; code1=c; c=0; if(ptset1i+1.xXL) c=0; code2=c; if(code1

    21、!=0&code2=0) ptk.x=XL; ptk.y=ptset1i.y+(ptset1i+1.y-ptset1i.y)*(XL-ptset1i.x)/(ptset1i+1.x-ptset1i.x); ptk+1.x=ptset1i+1.x; ptk+1.y=ptset1i+1.y; k=k+2; if(code1=0&code2=0) if(k=0) ptk.x=ptset1i.x; ptk.y=ptset1i.y; ptk+1.x=ptset1i+1.x; ptk+1.y=ptset1i+1.y; k=k+2; if(k!=0) ptk.x=ptset1i+1.x; ptk.y=pts

    22、et1i+1.y; k=k+1; if(code1=0&code2!=0) ptk.x=XL; ptk.y=ptset1i.y+(ptset1i+1.y-ptset1i.y)*(XL-ptset1i.x)/(ptset1i+1.x-ptset1i.x); k+; ptk.x=pt0.x; ptk.y=pt0.y; M=k+1; k=0; for(i=0;iM;i+) int c=0; if(pti.xXR) c=2; code1=c; c=0; if(pti+1.xXR) c=2; code2=c; if(code1=0&code2=0) if(k=0) ptsk.x=pti.x; ptsk.y=pti.y; ptsk+1.x=pti+1.x; ptsk+1.y=pti+1.y; k=k+2; if(k!=0) ptsk.x=pti+1.x; ptsk.y=pti+1.y; k+; if(code1!=0&code2=0) ptsk.x=XR; ptsk.y=pti.y+(


    注意事项

    本文(实验三 图形裁剪算法实现.docx)为本站会员主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

    copyright@ 2008-2022 冰点文档网站版权所有

    经营许可证编号:鄂ICP备2022015515号-1

    收起
    展开