多边形裁剪地Sutherland—Hodgman算法(计算机图形学)

合集下载

sutherland-hodgman原理

sutherland-hodgman原理

sutherland-hodgman原理
Sutherland-Hodgman算法是一种计算多边形相交的算法。

该算
法是由伊文·苏瑟兰和阿尔伯特·霍奇曼在1974年首次提出的。

该算法的目的是确定一个多边形在给定一个“裁剪多边形”内部的部分,即得到裁剪后的多边形。

Sutherland-Hodgman算法的基本思想是,通过逐边计算两个多
边形之间的相交点,然后根据相交点的位置来保留或丢弃多边形的顶点。

具体步骤如下:
1. 首先,将待裁剪的多边形的顶点按逆时针的顺序排列。

2. 针对裁剪多边形的每条边,依次进行以下步骤:
a. 计算裁剪线与多边形顶点的相对位置关系。

有三种可能的
情况:内部、外部或边上。

b. 根据相对位置关系,确定多边形顶点是否需要保留。

c. 如果裁剪线与多边形的一条边相交,计算相交点并加入裁
剪后的多边形的顶点列表。

3. 重复步骤2,直到处理完所有的裁剪多边形的边。

4. 返回裁剪后的多边形。

该算法的主要优点是简单易懂、计算量相对较小,但也存在一
些问题。

首先,该算法只能处理凸多边形,对于凹多边形需要进行额外的处理。

其次,该算法无法正确处理相互重叠的多边形,这种情况下算法的结果可能是不正确的。

因此,在实际应用中,可能需要在算法的基础上进行一些改进或增加其他算法来解决这些问题。

多边形裁剪地Sutherland—Hodgman算法(计算机图形学)

多边形裁剪地Sutherland—Hodgman算法(计算机图形学)

多形裁剪的 Sutherland —Hodgman算法1>. Sutherland—Hodgman多形裁剪算法思想算法的根本思想是每次用窗口的一条界及其延来裁剪多形的各。

多形往常由它的点序列来表示,裁剪某条界裁剪后,果形成新的点序列,又留待下条界行裁剪,⋯,直到窗口的全部界都裁剪完,算法形成最后的点序列,才是果多形〔它可能组成一个或多个多形〕。

当多形一个点 Pi 相于窗口某条界及其延行剪裁,不外乎以下四种状况〔即裁剪〕:1、点 Pi 在内,前一点 Pi-1也在内,将 Pi 入新的点序列;2、点 Pi 在内,前一点 Pi-1在外,先求交点Q,再将 Q、Pi 挨次入新的点序列;3、点 Pi 在外,前一点 Pi-1在内,先求交点Q,再将 Q入新的点序列;4、点 Pi 与前一点 Pi-1 均在外,点序列中不增添新的点。

2>. Sutherland—Hodgman多形裁剪算法步考多形相于一条界及其延行裁剪的算法:1.从主函数获得待裁剪多形的点序列 P[][2] 、点序列数 n、窗口一条界参数 xl 〔假定矩形窗口的左界〕;2.初:将点序列中的最后一个点前一点S;置初始志 flag :if(S在界内)flag=0;else flag=1;新的点序列数j=0 ;3.多形各点行裁剪理,果放入新的多形点序列Q[][2]中:for( 第一个点直到最后一个点,逐个理〕{if(Pi 在界内 ){if(flag!=0){flag=0;求交点并放入新的多形点序列Qj 中;j++ ;}将目前点放入新的多形点序列 Qj 中: Qj=Pi ; j++ ;}else{if(flag==0){flag=1;求交点并放入新的多形点序列Qj 中;j++ ;}}将目前极点赋给S: S=Pi;}4.做返回准备:将新的多边形极点序列Q又逐个放回原多边形极点序列P 中: P=Q;将新的多边形极点数j 放回原多边形极点数n 中: n=j ;////////////////////////////////////////////////////////////////////////////////////////-----多边形裁剪的Sutherland—Hodgman算法---------///////////////////////////////////////////////////////////////////////////////////////void CMyClip_AView::ClipedgeL(CPoint polypoint[], CPoint clipwindow[],UINT polynum)/* 此中参数 polypoint[] 为多边形极点 ,clipwindow[] 为裁剪窗口极点 ,polynum 为多边形极点数量 */{//找出裁剪窗口界限long xl,xr,yt,yb;UINT i;xl=clipwindow[0].x;xr=clipwindow[0].x;yt=clipwindow[0].y;yb=clipwindow[0].y;for(i=1;i<=4;i++){if(xl>clipwindow[i].x)xl=clipwindow[i].x;if(xr<clipwindow[i].x)xr=clipwindow[i].x;if(yb>clipwindow[i].y)yb=clipwindow[i].y;if(yt<clipwindow[i].y)yt=clipwindow[i].y;}//CPoint B[Polygon_Num],C[Polygon_Num];UINT m_nA,m_nB;int x,y;long tem1,tem2;m_nA=polynum;/*记录原始多边形极点极点个数*/m_nB=0;/* 记录重生成多边形极点极点个数*/for(i=0;i<m_nA;i++){if(polypoint[i].x<xl&& polypoint[i+1].x<xl)/* 判断的多边形边两个端点都在外面,不做办理*/{continue;/*假如是这类状况,那么就对持续对下一条多边形边作判断,也就是说下边的判断不用做了*/}if(polypoint[i].x>=xl&& polypoint[i+1].x>=xl)/* 边两个端点都在内部,保留*//* 由于每个保留的点在数组中只出现一次,且下一次判断时第二个端点必定会要取到,所以只保留的两个点中的第一个*/{B[m_nB].x =polypoint[i].x ;B[m_nB].y =polypoint[i].y ;m_nB=m_nB+1;continue;}if(polypoint[i].x<xl&& polypoint[i+1].x>=xl)/*边两个端点起点在外面,终点在内部,求交点,而后交点,终点都应当送入暂时数组*/{/*保留交点*/x=xl;tem1=(xl-polypoint[i].x);//tem2=(xl-x1)*dy/dx+y1;//y/x=dy/dx---->y=x*dy/dxtem2=tem1*(polypoint[i+1].y-polypoint[i].y)/(polypoint[i+1].x-polypoint[i].x)+polypoint[i].y;y=tem2;B[m_nB].x =x;B[m_nB].y =y;m_nB=m_nB+1;continue;}if(polypoint[i].x>=xl && polypoint[i+1].x<xl)/*起点在内部,终点在外,求交点,而后起点,交点送入暂时数组*/{/*保留内部点*/B[m_nB].x =polypoint[i].x ;B[m_nB].y =polypoint[i].y ;m_nB=m_nB+1;/* 保留交点 */x=xl;tem1=(xl-polypoint[i].x);tem2=tem1*(polypoint[i+1].y-polypoint[i].y)/(pol ypoint[i+1].x-polypoint[i].x)+polypoint[i].y;y=tem2;B[m_nB].x =x;B[m_nB].y =y;m_nB=m_nB+1;continue;}}//把第一个点的数据拷贝到最后//形成裁剪后的多边形if(i==m_nA){B[m_nB]=B[0];}//下 ------------------m_nA=0;for(i=0;i<m_nB;i++){if(B[i].y<yb && B[i+1].y<yb)//两个点全在下方{continue;//下一条边}if(B[i].y>=yb && B[i+1].y>=yb)//p1,p2 都在 yb 上方{C[m_nA].x =B[i].x;C[m_nA].y =B[i].y;m_nA++;continue;}if(B[i].y<yb && B[i+1].y>=yb)//p1 在下, P2 在上 , 留交点,外->内{y=yb;tem1=yb-B[i].y;//tem2=x1+(yb-y1)*dx/dytem2=tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y)+ B[i].x;x=tem2;C[m_nA].x =x;C[m_nA].y =y;m_nA++;continue;}if(B[i].y>=yb && B[i+1].y<yb)//p1在上方,P2 在下方,留P1 和交点, 内-外{//save p1C[m_nA].x=B[i].x;C[m_nA].y=B[i].y;m_nA++;//留交点y=yb;tem1=yb-B[i].y;//tem2=x1+(yb-y1)*dx/dytem2=tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y)+B[i].x;x=tem2;C[m_nA].x =x;C[m_nA].y =y;m_nA++;continue;}}//形成第二次裁剪多边形if(i==m_nB){C[m_nA]=C[0];}//右 ------------------m_nB=0;for(i=0;i<m_nA;i++){if(C[i].x>xr && C[i+1].x>xr)//P1 , P2 都在右方 --go next{continue;}if(C[i].x<=xr && C[i+1].x<=xr)//P1 , P2 都在左方,留P1{B[m_nB].x =C[i].x;B[m_nB].y =C[i].y;m_nB++;continue;}if(C[i].x>xr && C[i+1].x<=xr)//P1在右方,P2在左方,留交点{x=xr;tem1=C[i].x-xr;tem2=C[i].y-tem1*(C[i+1].y-C[i].y)/(C[i+1].x-C[i ].x);y=tem2;B[m_nB].x =x;B[m_nB].y =y;m_nB++;continue;}if(C[i].x<=xr && C[i+1].x>xr)//P1在内, P2 在外,留P1 和交点{//save p1B[m_nB].x =C[i].x;B[m_nB].y =C[i].y;m_nB++;//save交点x=xr;tem1=C[i].x-xr;tem2=C[i].y-tem1*(C[i+1].y-C[i].y)/(C[i+1].x-C[i ].x);y=tem2;B[m_nB].x =x;B[m_nB].y =y;m_nB++;continue;}}//三次裁剪后的新多边形if(i==m_nA){B[m_nB]=B[0];多边形裁剪地Sutherland—Hodgman算法(计算机图形学)适用文档}//上 -------------------m_nA=0;for(i=0;i<m_nB;i++){if(B[i].y>yt && B[i+1].y>yt)//p1,p2 都在上方 ,next{continue;}if(B[i].y<=yt && B[i+1].y<=yt)//p1,p2 都在下方 , 留 P1{C[m_nA].x =B[i].x;C[m_nA].y =B[i].y;m_nA++;continue;}if(B[i].y>yt && B[i+1].y<=yt)//P1在上方,P2在下方外->内, 留交点{y=yt;tem1=B[i].y-yt;//tem2=x1+(yb-y1)*dx/dytem2=B[i].x-tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i ].y);x=tem2;C[m_nA].x =x;C[m_nA].y =y;m_nA++;continue;}if(B[i].y<=yt && B[i+1].y>yt)//P1在下方,P2在上方,内->外,留P1 和交点{//save p1,,,C[m_nA].x =B[i].x;C[m_nA].y =B[i].y;m_nA++;//save交点y=yt;tem1=B[i].y-yt;多边形裁剪地Sutherland—Hodgman算法(计算机图形学)适用文档//tem2=x1+(yb-y1)*dx/dytem2=B[i].x-tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i ].y);x=tem2;C[m_nA].x =x;C[m_nA].y =y;m_nA++;continue;}}//形成裁剪后的多边形if(i==m_nB){C[m_nA]=C[0];}CClientDC dc(this);CPen tempen;tempen.CreatePen(PS_SOLID,1,RGB(255,0,0));dc.SelectObject(tempen);dc.MoveTo(C[0]);for(i=1;i<=m_nA;i++){dc.LineTo(C[i]);}}//.....。

计算机图形学(简单多边形裁剪算法)

计算机图形学(简单多边形裁剪算法)

简单多边形裁剪算法摘要:多边形裁剪算法与线性裁剪算法具有更广泛的实用意义,因此它是目前裁剪研究的主要课题。

本文主要介绍了一种基于多边形顶点遍历的简单多边形裁剪算法,它有效降低了任意多边形裁剪复杂度。

通过记录交点及其前驱、后继信息,生成结果多边形,该算法简化了交点的数据结构,节省了存储空间,降低了算法的时间复杂度,具有简单、易于编程实现、运行效率高的特点。

关键词:多边形裁剪;交点;前驱;后继;矢量数组一、技术主题的基本原理简单多边形裁剪算法综合考虑现有多边形裁剪算法的优缺点,它是一种基于多边形顶点遍历来实现简单多边形裁剪工作的。

其主要的原理是遍历多边形并把多边形分解为边界的线段逐段进行裁剪,输出结果多边形。

二、发展研究现状近年来,随着遥感绘图、CAD辅助设计、图象识别处理技术的发展,图形裁剪算法从最初在二维平面上线和图形的裁剪扩展到三维空间里体和场的裁剪,国内外相继提出不少行之有效的算法,但越来越复杂的图形和计算也对算法的速度和适用性提出了越来越高的要求。

因此,不断简化算法的实现过程,完善细节处理,满足大量任意多边形的裁剪也就成了当今算法研究的焦点之一。

以往多边形裁剪算法不是要求剪裁多边形是矩形,就是必须判断多边形顶点的顺时针和逆时针性,即存在不实用或者是增加了多边形裁剪算法的难度。

为了解决现在的问题,我们研究现在的新多边形算法,其中,裁剪多边形和被裁剪多边形都可以是一般多边形,且不需要规定多边形输入方向。

它采用矢量数组结构,只需遍历剪裁多边形和被裁剪多边形顶点即完成多边形的裁剪,具有算法简单、运行效率高的特点。

三、新算法设计1、算法的思想本算法是为了尽量降低任意多边形裁剪算法复杂度而提出的,其主要思想是采用矢量数组结构来遍历裁剪多边形和被裁多边形顶点,记录裁剪多边形和被裁减多边形交点及其前驱、后继信息,并通过记录相邻交点的线段,然后通过射线法选择满足条件的线段,之后进行线段连接,输出对应的裁剪结果。

了解电脑显卡的多边形剪裁和裁剪

了解电脑显卡的多边形剪裁和裁剪

了解电脑显卡的多边形剪裁和裁剪随着计算机图形学的不断发展,电脑显卡在图像处理方面的性能也逐渐提升。

而多边形剪裁和裁剪则是电脑显卡中重要的技术之一。

本文将介绍多边形剪裁和裁剪的定义、作用以及相关的算法与技术。

一、多边形剪裁和裁剪的定义多边形剪裁是指根据视口和裁剪窗口的位置,将位于裁剪窗口外的多边形剪除,只保留位于窗口内的部分。

而裁剪是指将多边形按照裁剪窗口的形状进行修剪,以适应显示设备的输出。

二、多边形剪裁的作用多边形剪裁的作用主要有以下几个方面:1. 提高渲染效率:多边形剪裁可以剔除位于屏幕外的多边形,避免不必要的计算和绘制,从而提高渲染效率。

2. 减少像素填充:在3D渲染中,所有多边形都要经过像素填充来生成最终的图像。

通过剪裁掉屏幕外的多边形,可以减少不必要的像素填充操作,提高渲染速度。

3. 实现可视化效果:多边形剪裁可以确保只显示用户所需的图像内容,可以实现视点的选择、物体的隐藏和透视等视觉效果。

三、多边形剪裁的算法与技术在实际应用中,多边形剪裁通常使用的算法包括:1. 逐边裁剪算法(Cohen-Sutherland算法):该算法通过将裁剪窗口划分为9个区域,将多边形的每条边与裁剪窗口的边界相交,并根据交点位置来确定多边形是否可见以及如何修剪多边形。

2. 多边形切割算法(Sutherland-Hodgman算法):该算法通过对多边形的每条边进行切割,生成新的多边形。

这些新的多边形通过裁剪窗口切割并连接,最终得到位于裁剪窗口内的多边形。

四、裁剪的应用和技术裁剪不仅可以应用于多边形,还可以应用于曲线、曲面和体素等图形对象的裁剪。

裁剪的技术也不仅仅局限于多边形剪裁算法,还包括对二维和三维对象的参数化、位图和文本的裁剪处理等。

在实际应用中,常用的裁剪技术包括:1. 区域编码算法:区域编码算法通过给定的区域码来标识物体所在的位置,从而对物体进行裁剪。

常见的算法有四叉树编码和八叉树编码。

2. 软件裁剪和硬件裁剪:软件裁剪是指在计算机的主机CPU上通过算法进行裁剪操作;而硬件裁剪则是指使用专门的图形处理器(GPU)来完成裁剪操作,通过并行计算提高裁剪效率。

计算机图形学第四讲

计算机图形学第四讲
第一位为1:端点处于上边界的上方 第二位为1:端点处于下边界的下方 第三位为1:端点处于右边界的右方 第四位为1:端点处于左边界的左方 否则,相应位为0
11
1001 0001
xL
A
B
C
1000 0000 E 裁剪窗口 0100
xR
第4讲 图形裁剪算法
1010 D yT 0010
7
第4讲 图形裁剪算法
直线裁减的效率策略
首先,通过方法来快速判断完全在窗口内和完全 在窗口外的直线 若是部分在窗口内的情况,则设法减少直线的求 交次数和每次的求交计算量
8
第4讲 图形裁剪算法
直线裁剪算法
Cohen-Sutherland裁剪算法 中点分割算法 梁友栋-Barsky裁剪算法
9
第4讲 图形裁剪算法
Cohen-Sutherland裁剪算法(编码裁剪法)
基本思想:对于每条待裁剪的线段P1P2分三种情 况处理
若P1P2完全在窗口内,则显示该线段 若P1P2完全在窗口外,则丢弃该线段 若线段不满足上述条件,则求线段与窗口边界的交点, 在交点处把线段分为两段,其中一段完全在窗口外, 可舍弃之,然后对另一段重复上述处理
P1
P1
P1
A
Pm
A Pm A B B P2
B Pm
18
P2
P2
第4讲 图形裁剪算法
算法特点
对分辨率为2N×2N的显示器,上述二分过程至多 进行N次 主要过程只用到加法和除法运算,适合硬件实现, 它可以用左右移位来代替乘除法,这样就大大加 快了速度
19
第4讲 图形裁剪算法
梁友栋-Barsky裁剪算法
13
第4讲 图形裁剪算法

三维sutherland-hodgman算法

三维sutherland-hodgman算法

三维sutherland-hodgman算法Sutherland-Hodgman 算法是一种裁剪多边形的算法,用于从一个多边形中裁剪出另一个多边形。

三维Sutherland-Hodgman 算法在二维的基础上进行了扩展,适用于三维空间。

以下是三维Sutherland-Hodgman 算法的基本步骤:1. 定义裁剪平面:确定一个裁剪平面,该平面可以是XYZ 轴的任意组合。

例如,裁剪平面可以是XY 平面、XZ 平面或YZ 平面。

2. 对每个多边形顶点进行处理:-对于每个多边形顶点,检查其位置相对于裁剪平面的情况(在平面的哪一侧)。

3. 裁剪:-根据顶点在平面的位置,采取相应的裁剪操作。

-如果顶点在平面的一侧,将其添加到输出多边形中。

-如果顶点在平面的两侧,进行插值计算,找到交点并添加到输出多边形中。

4. 完成裁剪:-处理完所有顶点后,输出多边形即为裁剪后的结果。

以下是一个简化的Java 伪代码示例,假设裁剪平面是XY 平面:```java// 三维Sutherland-Hodgman 算法List<Vertex> clip3D(List<Vertex> inputPolygon) {List<Vertex> outputPolygon = new ArrayList<>();// 裁剪平面方程:z = 0for (int i = 0; i < inputPolygon.size(); i++) {Vertex currentVertex = inputPolygon.get(i);Vertex nextVertex = inputPolygon.get((i + 1) % inputPolygon.size());// 如果当前顶点在平面的一侧,添加到输出多边形if (currentVertex.z >= 0) {outputPolygon.add(currentVertex);}// 如果边与平面相交,计算交点并添加到输出多边形if ((currentVertex.z >= 0 && nextVertex.z < 0) || (currentVertex.z < 0 && nextVertex.z >= 0)) {double t = currentVertex.z / (currentVertex.z - nextVertex.z);double x = currentVertex.x + t * (nextVertex.x - currentVertex.x);double y = currentVertex.y + t * (nextVertex.y - currentVertex.y);outputPolygon.add(new Vertex(x, y, 0));}}return outputPolygon;}```这个示例中,裁剪平面被设定为XY 平面(z = 0)。

计算机图形学裁剪算法

计算机图形学裁剪算法

一、实验目标1.了解Cohen-SutherLand线段裁剪算法、Liang-Barsky线段裁剪算法、SutherLand-Hodgeman多边形裁剪算法的基本思想;2.掌握Cohen-SutherLand线段裁剪算法、Liang-Barsky线段裁剪算法、SutherLand-Hodgeman多边形裁剪算法的算法实现;二、实验内容本次实验主要是实现Cohen-SutherLand线段裁剪算法、Liang-Barsky线段裁剪算法、SutherLand-Hodgeman多边形裁剪算法。

Cohen-sutherland线段裁剪算法思想:该算法也称为编码算法,首先对线段的两个端点按所在的区域进行分区编码,根据编码可以迅速地判明全部在窗口内的线段和全部在某边界外侧的线段。

只有不属于这两种情况的线段,才需要求出线段与窗口边界的交点,求出交点后,舍去窗外部分。

对剩余部分,把它作为新的线段看待,又从头开始考虑。

两遍循环之后,就能确定该线段是部分截留下来,还是全部舍弃。

Cohen-sutherland线段裁剪算法步骤:1、分区编码延长裁剪边框将二维平面分成九个区域,每个区域各用一个四位二进制代码标识。

各区代码值如图中所示。

四位二进制代码的编码规则是:(1)第一位置1:区域在左边界外侧(2)第二位置1:区域在右边界外侧(3)第三位置1:区域在下边界外侧(4)第四位置1:区域在上边界外侧裁剪窗口内(包括边界上)的区域,四位二进制代码均为0。

设线段的两个端点为P1(x1,y1)和P2(x2,y2),根据上述规则,可以求出P1和P2所在区域的分区代码C1和C2。

2、判别根据C1和C2的具体值,可以有三种情况:(1)C1=C2=0,表明两端点全在窗口内,因而整个线段也在窗内,应予保留。

(2)C1&C2≠0(两端点代码按位作逻辑乘不为0),即C1和C2至少有某一位同时为1,表明两端点必定处于某一边界的同一外侧,因而整个线段全在窗外,应予舍弃。

多边形裁剪——精选推荐

多边形裁剪——精选推荐

多边形裁剪错觉:直线段裁剪的组合?新的问题:边界不再封闭,需要⽤窗⼝边界的恰当部分来封闭它,如何确定其边界?⼀个凹多边形可能被裁剪成⼏个⼩的多边形,如何确定这些⼩多边形的边界?Sutherland-Hodgman算法Sutherland-Hodgman算法也叫逐边裁剪法,该算法是萨瑟兰德(I.E.Sutherland)和霍德曼(Hodgman)在1974年提出的。

这种算法采⽤了分割处理、逐边裁剪的⽅法。

1、算法介绍1. 分割处理策略:该算法的基本思想是将多边形边界作为⼀个整体,每次⽤窗⼝的⼀条边对要裁剪的多边形和中间结果多边形进⾏裁剪,体现⼀种分⽽治之的思想。

2. 流⽔线过程(左上右下):前边的结果是后边的输⼊2、算法思想基本思想是⼀次⽤窗⼝的⼀条边裁剪多边形。

考虑窗⼝的⼀条边以及延长线构成的裁剪线该线把平⾯分成两个部分:可见⼀侧和不可见⼀侧多边形的各条边的两端点S、P。

它们与裁剪线的位置关系只有四种情况(1):起点终点都在可见⼀侧,仅输出顶点P;如果都输出,会出现多边形的点重复情况(2):起点终点都不在可见⼀侧,输出0个顶点;情况(3):起点在可见⼀侧,终点在不可见⼀侧,输出线段SP与裁剪线的交点I;情况(4):起点在不可见⼀侧,终点在可见⼀侧,输出线段SP与裁剪线的交点I和终点P 3、算法框图上述算法仅⽤⼀条裁剪边对多边形进⾏裁剪,得到⼀个顶点序列,作为下⼀条裁剪边处理过程的输⼊。

对于每⼀条裁剪边,算法框图同上,只是判断点在窗⼝哪⼀侧以及求线段SP与裁剪边的交点算法应随之改变。

4、⼩结对凸多边形应⽤本算法可以得到正确的结果,但是对凹多边形的裁剪将如图所⽰显⽰出⼀条多余的直线。

这种情况在裁剪后的多边形有两个或者多个分离部分的时候出现。

因为只有⼀个输出顶点表,所以表中最后⼀个顶点总是连着第⼀个顶点。

解决这个问题有多种⽅法,⼀是把凹多边形分割成若⼲个凸多边形,然后分别处理各个凸多边形。

⼆是修改本算法,沿着任何⼀个裁剪窗⼝边检查顶点表,正确的连接顶点对。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

多边形裁剪的Sutherland—Hodgman算法1>. Sutherland—Hodgman多边形裁剪算法思想该算法的基本思想是每次用窗口的一条边界及其延长线来裁剪多边形的各边。

多边形通常由它的顶点序列来表示,经过裁剪规则针对某条边界裁剪后,结果形成新的顶点序列,又留待下条边界进行裁剪,…,直到窗口的所有边界都裁剪完毕,算法形成最后的顶点序列,才是结果多边形(它可能构成一个或多个多边形)。

当多边形一个顶点Pi相对于窗口某条边界及其延长线进行剪裁时,不外乎下列四种情况(即裁剪规则):1、顶点Pi在内侧,前一顶点Pi-1也在内侧,则将Pi纳入新的顶点序列;2、顶点Pi在内侧,前一顶点Pi-1在外侧,则先求交点Q,再将Q、Pi依次纳入新的顶点序列;3、顶点Pi在外侧,前一顶点Pi-1在内侧,则先求交点Q,再将Q纳入新的顶点序列;4、顶点Pi与前一顶点Pi-1均在外侧,则顶点序列中不增加新的顶点。

2>. Sutherland—Hodgman多边形裁剪算法步骤考虑多边形相对于一条边界及其延长线进行裁剪的算法:1.从主函数得到待裁剪多边形的顶点序列P[][2]、顶点序列数n、窗口一条边界参数xl(假如为矩形窗口的左边界);2.赋初值:将顶点序列中的最后一个顶点赋给前一顶点S;设置初始标志flag:if(S在边界内侧)flag=0;else flag=1;设新的顶点序列数j=0;3.对多边形各顶点进行裁剪规则处理,结果放入新的多边形顶点序列Q[][2]中:for(对第一个顶点直到最后一个顶点,逐一处理){if(Pi在边界内侧){if(flag!=0){flag=0;求交点并放入新的多边形顶点序列Qj中;j++;}将当前顶点放入新的多边形顶点序列Qj中:Qj=Pi;j++;}else{if(flag==0){flag=1;求交点并放入新的多边形顶点序列Qj中;j++;}}将当前顶点赋给S:S=Pi;}4.做返回准备:将新的多边形顶点序列Q又逐一放回原多边形顶点序列P中:P=Q;将新的多边形顶点数j放回原多边形顶点数n中:n=j;///////////////////////////////////////////////////////////////////// ///////////////////-----多边形裁剪的Sutherland—Hodgman算法---------/////////////////////////////////////////////////////////////////////// ////////////////void CMyClip_AView::ClipedgeL(CPoint polypoint[], CPoint clipwindow[], UINT polynum)/*其中参数polypoint[]为多边形顶点,clipwindow[]为裁剪窗口顶点,polynum 为多边形顶点数目*/{//找出裁剪窗口边界long xl,xr,yt,yb;UINT i;xl=clipwindow[0].x;xr=clipwindow[0].x;yt=clipwindow[0].y;yb=clipwindow[0].y;for(i=1;i<=4;i++){if(xl>clipwindow[i].x)xl=clipwindow[i].x;if(xr<clipwindow[i].x)xr=clipwindow[i].x;if(yb>clipwindow[i].y)yb=clipwindow[i].y;if(yt<clipwindow[i].y)yt=clipwindow[i].y;}//CPoint B[Polygon_Num],C[Polygon_Num];UINT m_nA,m_nB;int x,y;long tem1,tem2;m_nA=polynum;/*记载原始多边形顶点顶点个数*/m_nB=0;/*记载新生成多边形顶点顶点个数*/for(i=0;i<m_nA;i++){if(polypoint[i].x<xl && polypoint[i+1].x<xl) /*判断的多边形边两个端点都在外部,不做处理*/{continue;/*如果是这种情况,那么就对继续对下一条多边形边作判断,也就是说下面的判断不用做了*/}if(polypoint[i].x>=xl && polypoint[i+1].x>=xl) /*边两个端点都在内部,保留*//*因为每个保留的点在数组中只出现一次,且下一次判断时第二个端点一定会要取到,因此只保留的两个点中的第一个*/{B[m_nB].x =polypoint[i].x ;B[m_nB].y =polypoint[i].y ;m_nB=m_nB+1;continue;}if(polypoint[i].x<xl && polypoint[i+1].x>=xl)/*边两个端点起点在外部,终点在内部,求交点,然后交点,终点都应该送入临时数组*/{/*保留交点*/x=xl;tem1=(xl-polypoint[i].x);//tem2=(xl-x1)*dy/dx+y1;//y/x=dy/dx---->y=x*dy/dxtem2=tem1*(polypoint[i+1].y-polypoint[i].y)/(polypoint[i+1].x-polypoint[i].x)+polypoi nt[i].y;y=tem2;B[m_nB].x =x;B[m_nB].y =y;m_nB=m_nB+1;continue;}if(polypoint[i].x>=xl && polypoint[i+1].x<xl)/*起点在内部,终点在外,求交点,然后起点,交点送入临时数组*/{ /*保留内部点*/B[m_nB].x =polypoint[i].x ;B[m_nB].y =polypoint[i].y ;m_nB=m_nB+1;/*保留交点*/tem1=(xl-polypoint[i].x);tem2=tem1*(polypoint[i+1].y-polypoint[i].y)/(polypoint[i+1].x-polypoint[i].x)+polypoi nt[i].y;y=tem2;B[m_nB].x =x;B[m_nB].y =y;m_nB=m_nB+1;continue;}}//把第一个点的数据拷贝到最后//形成裁剪后的多边形if(i==m_nA){B[m_nB]=B[0];}//下------------------m_nA=0;for(i=0;i<m_nB;i++){if(B[i].y<yb && B[i+1].y<yb)//两个点全在下方{continue;//下一条边}if(B[i].y>=yb && B[i+1].y>=yb)//p1,p2都在yb上方{C[m_nA].x =B[i].x;C[m_nA].y =B[i].y;m_nA++;continue;}if(B[i].y<yb && B[i+1].y>=yb)//p1在下,P2在上,留交点,外->内{y=yb;tem1=yb-B[i].y;//tem2=x1+(yb-y1)*dx/dytem2=tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y) + B[i].x;C[m_nA].x =x;C[m_nA].y =y;m_nA++;continue;}if(B[i].y>=yb && B[i+1].y<yb)//p1在上方,P2在下方,留P1和交点,内-外{//save p1C[m_nA].x=B[i].x;C[m_nA].y=B[i].y;m_nA++;//留交点y=yb;tem1=yb-B[i].y;//tem2=x1+(yb-y1)*dx/dytem2=tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y)+B[i].x;x=tem2;C[m_nA].x =x;C[m_nA].y =y;m_nA++;continue;}}//形成第二次裁剪多边形if(i==m_nB){C[m_nA]=C[0];}//右------------------m_nB=0;for(i=0;i<m_nA;i++){if(C[i].x>xr && C[i+1].x>xr)//P1,P2都在右方--go next{continue;}if(C[i].x<=xr && C[i+1].x<=xr)//P1,P2都在左方,留P1{B[m_nB].x =C[i].x;B[m_nB].y =C[i].y;m_nB++;continue;}if(C[i].x>xr && C[i+1].x<=xr)//P1在右方,P2在左方,留交点{x=xr;tem1=C[i].x-xr;tem2=C[i].y-tem1*(C[i+1].y-C[i].y)/(C[i+1].x-C[i].x);y=tem2;B[m_nB].x =x;B[m_nB].y =y;m_nB++;continue;}if(C[i].x<=xr && C[i+1].x>xr)//P1在内,P2在外,留P1和交点{//save p1B[m_nB].x =C[i].x;B[m_nB].y =C[i].y;m_nB++;//save 交点x=xr;tem1=C[i].x-xr;tem2=C[i].y-tem1*(C[i+1].y-C[i].y)/(C[i+1].x-C[i].x);y=tem2;B[m_nB].x =x;B[m_nB].y =y;m_nB++;continue;}}//三次裁剪后的新多边形if(i==m_nA){B[m_nB]=B[0];}//上-------------------m_nA=0;for(i=0;i<m_nB;i++){if(B[i].y>yt && B[i+1].y>yt)//p1,p2都在上方,next{continue;}if(B[i].y<=yt && B[i+1].y<=yt)//p1,p2都在下方,留P1{C[m_nA].x =B[i].x;C[m_nA].y =B[i].y;m_nA++;continue;}if(B[i].y>yt && B[i+1].y<=yt)//P1在上方,P2在下方外->内,留交点{y=yt;tem1=B[i].y-yt;//tem2=x1+(yb-y1)*dx/dytem2=B[i].x-tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y);x=tem2;C[m_nA].x =x;C[m_nA].y =y;m_nA++;continue;}if(B[i].y<=yt && B[i+1].y>yt)//P1在下方,P2在上方,内->外,留P1和交点{//save p1,,,C[m_nA].x =B[i].x;C[m_nA].y =B[i].y;m_nA++;//save 交点y=yt;tem1=B[i].y-yt;//tem2=x1+(yb-y1)*dx/dytem2=B[i].x-tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y);x=tem2;C[m_nA].x =x;C[m_nA].y =y;m_nA++;continue;}}//形成裁剪后的多边形if(i==m_nB){C[m_nA]=C[0];}CClientDC dc(this);CPen tempen;tempen.CreatePen(PS_SOLID,1,RGB(255,0,0));dc.SelectObject(tempen);dc.MoveTo(C[0]);for(i=1;i<=m_nA;i++){dc.LineTo(C[i]);}}//.....。

相关文档
最新文档