二维图形裁剪的课程设计.docx
《二维图形裁剪的课程设计.docx》由会员分享,可在线阅读,更多相关《二维图形裁剪的课程设计.docx(13页珍藏版)》请在冰豆网上搜索。
二维图形裁剪的课程设计
华东交通大学
图形学课程设计
课程设计名称:
各种二维图形裁剪技术研究
姓名:
学号:
学院:
基础学院
班级:
信息与计算科学2010-1
指导老师:
小组成员:
1、摘要……………………………………………………………2
2、二维图形裁剪……………………………………………………2
2.1裁剪的原理…………………………………………………2
2.2裁剪的分类…………………………………………………3
2.2.1.线段的裁剪………………………………………………3
2.2.2多边形的裁剪……………………………………………5
2.2.3.圆和曲线的裁剪…………………………………………6
3、算法……………………………………………………………6
3.1裁剪算法………………………………………………………7
3.2裁剪圆算法…………………………………………………9
3.3裁剪窗口是圆算法……………………………………………11
4、心得体会…………………………………………………………12
5、参考文献…………………………………………………………12
6、功能实现效果的图片展示……………………………………13
1、摘要
近几十年来,计算机图形学有了引人瞩目的发展,它已广泛应用于计算机辅助设计、电视广告、动画和仿真等许多领域并发挥着重要作用。
可以说计算机图形学已经发展成为一门成熟的学科。
在各种实践应用中,计算机图形学的许多基础算法发挥着不可替代的重要作用,因此不断提高和完善图形学的基础算法至关重要。
计算机图形学是研究在计算机中如何构造图形,并把图形的描述数据(数学模型)通过指定的算法转化为图形显示的学科。
目前,计算机图形学的主要研究对象包括:
点、线、面——二维图形学:
体——三维图形学以及场等的数学构造方法与其图形显示以及它们的变化情况。
2、二维图形裁剪
在使用计算机处理图形信息时,计算机内部存储的图形往往比较大,而屏幕显示的只是图的一部分。
因此需要确定图形中哪些部分落在显示区之内,哪些落在显示区之外,以便只显示落在显示区内的那部分图形。
从数据集合中抽取所需信息即识别指定区域内或区域外的图形部分的过程称为裁剪算法,简称裁剪。
它是计算机图形学中许多重要问题的基础。
裁剪典型的用途是确定场景或画面中位于给定区域之内的部分。
这一区域称为裁剪窗口。
最简单的裁剪方法是把各种图形扫描转换为点之后,再判断各点是否在窗口内。
但那样太费时,一般不可取。
这是因为有些图形组成部分全部在窗口外,可以完全排除,不必进行扫描转换。
所以,一般采用先裁剪再扫描转换的方法。
裁剪的应用包括:
从定义的场景中抽取出用于观察的部分;在三维视图中标识出可见面:
防止线段或对象的边界混淆;使用实体造型来创建对象;显示多窗口的环境;允许选择图形一部分进行复制、移动或删除等绘图操作。
对于不同的应用,裁剪窗口可以是多边形或包含有曲线边界。
2.1裁剪的原理
裁剪的基本目的是判断图形元素是否部分或全部落在窗口区域之内,如果是,则进一步求出位于窗口内的部分。
裁剪处理包括两个方面:
判断图形元素是否在窗口内以及求图形元素与窗口的交。
一般把窗口定义为矩形,由上、下、左、右四条边围成,即:
(xL,yB),(xR,yT)。
裁剪的实质就是决定图形中哪些点、线段、文字以及多边形在窗口之内。
对于点(x,y),只要判断两对不等式:
xL≤x≤xR,yB≤y≤yT
若四个不等式均成立。
则点在矩形窗口之内;否则,点在矩形窗口之外。
2.2裁剪的分类
裁剪算法大致包括对以下图形的裁剪:
●线段的裁剪(线段)
●区域的裁剪(多边形)
●区域的裁剪(圆和曲线)
2.2.1线段的裁剪
线段与窗口的关系有如下三种:
(1)线段在窗口内,线段不需剪裁,完全可见;
(2)线段在窗口外,即线段不需剪裁,完全不可见;
(3)线段部分在窗口内,部分在窗口外,即需要求出线段与窗框的交点,并将窗口外的线段部分剪裁掉,只可见窗口内的直线部分。
线段的裁剪算法就是要找出位于窗口内部的起始点和终止点的坐标。
因矢量裁剪法对寻找起点和终点坐标的处理方法相同,下面以求始点坐标为例来说明线段矢量裁剪方法。
在右图中,窗口的四条边界把XOY平面分成九个区域,分别用1到9对这九个窗口编号,设5号区域为相应的可见窗口区,窗口的左下角点坐标(minX,minY),右上角点坐标为(maxX,maxY)。
有一条矢量线段S,其起、终点的坐标分别为(Xs,Ys)和(Xe,Ye),则对线段S按矢量裁剪的算法步骤如下:
1、若线段完全位于区域5以外的任意区域内或落在(1,2,3)(3,6,9)(7,8,9)(1,4,7)中任意一区域组内,即满足下述条件之一:
Xs Xs>minX且Xe>minX,
Ys Ys>minY且Ye>minY
则线段S不在窗口内,不必作进一步的求交点处理,否则转下一步。
2、若线段S满足minX≤Xs≤maxX且minX≤Ys≤maxY,则线段的起点在窗口内,新的起点坐标(X,Y)即为(Xs,Ys);否则,按以下各步判断S与窗口的关系以及解算其新起点坐标(X,Y)。
3、若Xs(4-2-1)
此时要作以下判断:
(1)若起点(minY≤Y≤maxY),则(X,Y)求解有效;
(2)若起点(Xs,Ys)位于4区,且Xs>minY或Y>maxY,则线段S与窗口无交点;
(3)若Y>maxY且Ys>maxY或者Y>minY且Ys (a)当起点在1区且Ye>maxY或当起点位于7区且Ye (b)若Ys(4-2-2)
若Ys>maxY,则:
(4-2-3)
用(4-2-2)和(4-2-3)式求出的X若满足minX≤X≤maxX,则(X,Y)的求解有效,否则线段与窗口仍无交点。
4、当Xs>maxX,即线段起点位于窗口右界的右边,可仿照上述过程求出线段与右边界的交点。
5、若起点(Xs,Ys)位于2或8区时,求解线段与窗口边界的交点公式为(4-2-4)和(4-2-5)式。
(4-2-4)
(4-2-5)
用式(4-2-4)和(4-2-5)求解得X在满足minX≤X≤maxX时才有效,否则线段不在窗口内。
同理,可求解出线段在窗口内新的终点坐标。
2.2.2多边形的裁剪
多边形是计算机制图中常用的图形元素,大到行政区域,小到各种地物图块,都是多边形元素。
多边形的裁剪比直线要复杂得多。
因为经过裁剪后,多边形的轮廓线仍要闭合,而裁剪后的边数可能增加,也可能减少,或者被裁剪成几个多边形,这样必须适当地插入窗口边界才能保持多边形的封闭性。
这就使得多边形的裁剪不能简单地用裁剪直线的方法来实现。
对于多边形的裁剪,人们研究出了多种算法,其中萨瑟兰德-霍奇曼(Sutherland-Hodgman)算法是根据相对于一条边界线裁剪多边形比较容易这一点,把整个多边形先相对于窗口的第一条边界裁剪,然后再把形成的新多边形相对于窗口的第二条裁剪,如此进行到窗口的最后一条边界,从而把多边形相对于窗口的全部边界进行了裁剪。
其算法描述为:
1.取多边形顶点Pi(i=1,2,…,n),将其相对于窗口的第一条边界进行判别,若点Pi位于边界的靠窗口一侧,则把Pi记录到要输出的多边形顶点中,否则不作记录。
2.检查Pi点与Pi-1点(i=1时,检查Pi与Pn点)是否位于窗口边界的同一侧。
若是,Pi点记录与否,随Pi-1点是否记录而定;否则计算出PiPi-1与窗口边界的交点,并将它记录到要输出的多边形的顶点中去。
3.如此而已判别所有的顶点P1P2…Pn后,得到一个新的多边形Q11,Q12,…,Qm,然后用新的多边形重复上述步骤1、2,依次对窗口的第二、第三和第四条边界进行判别,判别完后得到的多边形Q14,Q24,…,Qm4即为裁剪的最后结果。
如上图所示,演示了多边形的裁剪过程:
(1)首先对窗口的右边界进行判别,从多边形的顶点P1开始依次判断。
P1在右边界不可见一侧,故不记录P1点,且P1和P6在右边界同侧,则也不与右边界求交点。
P2点在右边界可见一侧,且P2和P1在右边界异侧,因此求出P2P1与右边界交点记作Q1,同时把P2点记录下来作为(Q2)。
P3点在右边界不可见一侧,但P3和P2在右边界异侧,因此求出P3P2与右边界交点记作Q3。
P4点在右边界可见一侧,且P4和P3在右边界异侧,因此求出P4P3与右边界交点记作Q4,同时把P4点记录下来作为(Q5)。
P5点在右边界不可见一侧,但P5和P4在右边界异侧,因此求出P5P4的右边界交占记作Q6。
P6点在右边界不可见一侧,且P6和P5在右边界同侧,因此不求交点也不记录P6点。
这样就得到了新多边形Q1,(Q2),Q3,Q4,(Q5),Q6
(2)把新得到的多边形Q1,(Q2),Q3,Q4,(Q5),Q6对窗口的下边界进行判断,同理可得到新的多边形Q1,(Q2),Q3,Q4,Q5,Q6
(3)新得到的多边形与窗口左边界和上边界进行判断,多边形无变化,即为多边形裁剪的最后结果。
2.2.3圆和曲线的裁剪
对圆的裁剪思路是,首先通过圆的外接矩形判断来确定圆是否全部位于窗口的外边,若全部位于窗口外边,则裁剪过程结束。
否则,将圆分解成一组短线段,然后按照直线裁剪的方法来进行。
由于曲线在实际绘制时是采用短直线来逼近曲线的方法实现,故曲线的裁剪也采用一般直线裁剪方法对每一短线段进行裁剪,从而实现对整个曲线的裁剪。
3、算法
3.1裁剪算法
procedureTComputerGrapicsMainForm.Clip1Click(Sender:
TObject);
var
i,j,Outside,Clip:
Integer;
xystring:
string;
Labeltryagain;
LabelNextLine;
begin
//Window'scoordinates
W1:
=90;W2:
=270;w3:
=40;w4:
=160;
//xcoordinatesycoordinates
XY_Lines[1,1,1]:
=110;XY_Lines[1,1,2]:
=10;
XY_Lines[1,2,1]:
=290;XY_Lines[1,2,2]:
=70;
XY_Lines[2,1,1]:
=290;XY_Lines[2,1,2]:
=70;
XY_Lines[2,2,1]:
=250;XY_Lines[2,2,2]:
=190;
XY_Lines[3,1,1]:
=250;XY_Lines[3,1,2]:
=190;
XY_Lines[3,2,1]:
=70;XY_Lines[3,2,2]:
=130;
XY_Lines[4,1,1]:
=70;XY_Lines[4,1,2]:
=130;
XY_Lines[4,2,1]:
=110;XY_Lines[4,2,2]:
=10;
XY_Lines[5,1,1]:
=160;XY_Line