⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2.6.2 多边形的剪裁.htm

📁 计算机图形学教程计算机图形学教程
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0058)http://www.ekany.com/wdg98/cg/contents/chapter2/les262.htm -->
<HTML><HEAD><TITLE>2</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2800.1106" name=GENERATOR></HEAD>
<BODY><B>
<H3 align=justify><A name=262><FONT face=楷体_GB2312 size=4>2.6.2 
多边形的剪裁</FONT></A></B></H3>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>&nbsp;&nbsp;&nbsp; 
多边形的剪裁比直线剪裁复杂。如果套用直线剪裁算法对多边形的边作剪裁的话,剪裁后的多边形之边就会成为一组彼此不连贯的折线,从而给填色带来困难(图2.6.3(b))。多边形剪裁算法的关键在于:通过剪裁,不仅要保持窗口内多边形的边界部分,而且要将窗框的有关部分按一定次序插入多边形之保留边界之间,从而使剪裁后的多边形之边仍旧保持封闭状态,填色算法得以正确实现(图2.6.3(c))。</FONT></FONT></P>
<P align=center><IMG height=193 src="2.6.2 多边形的剪裁.files/2_6_3.gif" width=421 
border=0></P>
<P align=center><FONT face=楷体_GB2312><FONT size=4>图</FONT>2.6.3 <FONT 
size=4>多边形剪裁</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>下面介绍的多边形剪裁算法是Sutherland和Hodgman提出的<SUP>[9]</SUP>,它的基本思想是:</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>1)令多边形的顶点按边线逆时针走向排序:p<SUB>1</SUB>, p<SUB>2</SUB>, …, 
p<SUB>n</SUB>。如图2.6.4(a)。各边先与上窗边求交。求交后删去多边形在窗之上的部分,并插入上窗边及其延长线的交点之间的部分(图2.6.4(b)中的(3,4)),从而形成一个新的多边形。然后,新的多边形按相同方法与右窗边相剪裁。如此重复,直至与各窗边都相剪裁完毕。图2.6.4(c)、(d)、(e)示出上述操作后所生成的新多边形的情况。</FONT></FONT></P>
<P align=center><FONT face=楷体_GB2312 size=4><IMG height=417 
src="2.6.2 多边形的剪裁.files/2_6_4.gif" width=471 border=0></FONT></P>
<P align=center><FONT face=楷体_GB2312 size=4>图2.6.4 多边形剪裁的步骤</FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>2)多边形与每一条窗边相交,生成新的多边形顶点序列的过程,是一个对多边形各顶点依次处理的过程。设当前处理的顶点为p,先前顶点为s,多边形各顶点的处理规则如下:</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>如果s, 
p均在窗边之内侧,那么,将p保存。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>如果s在窗边内侧,p在外侧,那么,求出sp边与窗边的交点I,保存I,舍去p。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>如果s, 
p均在窗边之外侧,那么,舍去p。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>如果s在窗边之外侧,p在内侧,那么,求出sp边与窗边的交点I,依次保存I和p。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>上述四种情况在图2.6.5(a)、(b)、(c)、(d)中分别示出。基于这四种情况,可以归纳对当前点p的处理方法为:1、p在窗边内侧,则保存p;否则不保存。2、p和s在窗边非同侧,则求交点I,并将I保存,并插入p之前,或s之后。</FONT></FONT></P>
<P align=center><IMG height=290 src="2.6.2 多边形的剪裁.files/2_6_5.gif" width=460 
border=0></P>
<P align=center><FONT face=楷体_GB2312><FONT size=4>图</FONT>2.6.5 <FONT 
size=4>多边形的新顶点序列的生成规则</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>程序2.6.6执行上述算法思想。它的主程序clip_polygon含有输入参数:</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>x, 
y是两个长n的数组,存放多边形顶点坐标;X<SUB>w-max</SUB>,X<SUB>w-min</SUB>,Y<SUB>w-max</SUB>,Y<SUB>w-min</SUB>是窗口的边界。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>输出参数:一个剪裁后的多边形,顶点仍放在x, 
y数组之中,长度为修改了的n。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>clip-polygon</FONT>调用二个子程序:</FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>1)clip_single_edge(edge, 
type, n_in, y_in, n_out, x_out, 
y_out);功能为将多边形与一条窗边edge相剪裁。其中输入参数为:</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>edge:窗边的值,可以是X<SUB>w-max</SUB>,Y<SUB>w-max</SUB>,X<SUB>w-min</SUB>,Y<SUB>w-min</SUB>四种值之一种;</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>type:窗边的类型,可以是right, left, 
top, bottom四种值之一种;</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>x_in, y_in, 
n_in:输入多边形顶点坐标及个数。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>输出参数为:x_out, y_out, 
n_out,是输出多边形的新顶点序列坐标及个数。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>2)test_intersection(edge, 
type, x<SUB>1</SUB>, y<SUB>1</SUB>, x<SUB>2</SUB>, x_out, y_out, yes, 
is_in);功能与参数含义为:</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>(1)判断当前点(x<SUB>2</SUB>, 
y<SUB>2</SUB>)是否在所剪裁的窗边edge之内侧,如是,is_in为True;否则,is_in为False。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>(2)判断(x<SUB>2</SUB>, 
y<SUB>2</SUB>)与先前点(x<SUB>1</SUB>, 
y<SUB>1</SUB>)是否分在edge之异侧,如是,yes为True;否则,yes为False。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT 
size=4>(3)如果yes=True,求出边(x<SUB>1</SUB>y<SUB>2</SUB>)(x<SUB>2</SUB>y<SUB>2</SUB>)与edge之交点坐标,存入x_out, 
y_out。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>该程序的输出参数为is_in, yes,和x_out, 
y_out。</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312 size=4>clip_polygon (Xwmax, Xwmin, Ywmax, 
Ywmin, n, x, y)</FONT></P>
<P align=justify><FONT face=楷体_GB2312 size=4>int Xwmax, Xwmin, Ywmax, Ywmin, n, 
*x, *y;</FONT></P>
<P align=justify><FONT face=楷体_GB2312 size=4>{</FONT></P>
<P align=justify><FONT face=楷体_GB2312 size=4>int * x1, *y1, n1;</FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>/* </FONT>定义<FONT 
size=4>right=1, bottom=2, left=3, top=4. */</FONT></FONT></P>
<P align=justify><FONT face=楷体_GB2312 size=4>clip_single_edge(Xwmax, right, n, 
x, y, &amp;n1, &amp;x1, &amp;y1);</FONT></P>
<P align=justify><FONT face=楷体_GB2312 size=4>clip_single_edge(Ywmin, bottom, n1, 
x1, y1, &amp;n, &amp;x, &amp;y);</FONT></P>
<P align=justify><FONT face=楷体_GB2312 size=4>clip_single_edge(Xwmin, left, n, x, 
y, &amp;n1, &amp;x1, &amp;y1);</FONT></P>
<P align=justify><FONT face=楷体_GB2312 size=4>clip_single_edge(Ywmax, top, n1, 
x1, y1, &amp;n, &amp;x, &amp;y);</FONT></P>
<P align=justify><FONT face=楷体_GB2312 size=4>}</FONT></P>
<P align=justify><FONT face=楷体_GB2312><FONT size=4>程序2.6.6 
多边形剪裁主程序</FONT></FONT></P>
<BLOCKQUOTE>
  <BLOCKQUOTE>
    <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
    face=Arial>clip_single_edge(edge, type, nin, xin, yin, nout, xout, 
    yout)</FONT></P>
    <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
    face=Arial>int edge, type, nin, *xin, *yin, *nout, *xout, *yout;</FONT></P>
    <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
    face=Arial>{</FONT></P>
    <BLOCKQUOTE>
      <BLOCKQUOTE>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>int i, k, yes, is_in;</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>int x, y, x_intersect, y_intersect;</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>{</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp; x=xin[nin]; y=yin[nin];</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp; k=0;</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp; for(i=0; i&lt;nin; i++){</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        test_intersect(edge, type, x, y, xin[i], yin[i],</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        &amp;x_intersect, &amp;y-intersect, &amp;yes, &amp;is_in);</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>/* yes</FONT>表示两点是否在<FONT face=Arial>edge</FONT>之异侧;<FONT 
        face=Arial>is_in</FONT>表示<FONT face=Arial>xin[i], yin[i]</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp; </FONT>是否在<FONT face=Arial>edge</FONT>之内侧<FONT 
        face=Arial>. */</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp; if (yes) {</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        xout[k]=x_intersect;</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        yout[k]=y_intersect;</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        k++;</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        }</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp; if(is_in) {</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        xout[k]=xin[i];</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        yout[k]=yin[i];</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 
        face=Arial>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
        k++;</FONT></P>
        <P style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px" align=justify><FONT 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -