梁友栋-Barsky直线裁剪算法计算机图形学教学规划

梁友栋-Barsky直线裁剪算法计算机图形学教学规划
梁友栋-Barsky直线裁剪算法计算机图形学教学规划

河南理工大学

万方科技学院

课程设计报告2011 —2012学年第二学期

课程名称计算机图形学

设计题目计算机图形学基本算法

演示系统设计

学生姓名

学号

专业班级网络11升—1班

指导教师徐文鹏

2012 年5 月28 日

目录

第1章设计内容与要求 (1)

1.1 总体目标和要求 (1)

1.2内容与要求 (1)

1.2.1 直线的生成 (1)

1.2.2 圆弧的生成 (1)

1.2.3 线段裁剪 (2)

1.2.4 多边形裁剪 (2)

1.2.5 综合 (2)

第2章总体设计 (3)

2.1 Bresenham算法画直线 (3)

2.1.1 Bresenham算法画直线理论基础 (3)

2.1.2 Bresenham算法画直线原理 (3)

2.2 Bresenham算法画圆 (5)

2.2.1 Bresenham算法画圆理论基础 (5)

2.2.2 Bresenham算法画圆原理 (6)

2.3 梁友栋-Barsky算法进行线段裁剪 (7)

2.3.1梁友栋-Barsky算法进行线段裁剪基本原理 (7)

2.4.1 Sutherland—Hodgman多边形裁剪算法思想 (9)

2.4.2 点在边界内侧的判断方法 (10)

2.4.4 Sutherland-Hodgeman多边形裁剪算法特点 (10)

第3章详细设计 (9)

3.1 Bresenham算法画直线 (12)

3.1.1 Bresenham 算法画线算法具体实现过程 (12)

3.2 Bresenham算法画圆 (13)

3.2.1 Bresenham 算法画圆核心代码 (13)

3.3 梁友栋-Barsky算法进行线段裁剪 (14)

3.3.1梁友栋-Barsky算法推导过程 (14)

3.3.2梁友栋-Barsky算法进行线段裁剪的步骤 (15)

3.4 Sutherland-Hodgman算法进行多边形裁剪 (15)

3.4.1 Sutherland—Hodgman多边形裁剪算法步骤 (15)

3.5将画线、画圆、线段裁剪和多边形裁剪综合 (17)

第4章功能实现 (14)

4.1用Bresenham算法画线测试结果 (20)

4.2用Bresenham算法画圆测试结果 (21)

4.3梁友栋-Barsky算法进行线段裁剪测试结果 (21)

4.5将四种算法综合测试结果 (23)

第5章总结 (17)

参考文献 (18)

第1章设计内容与要求

1.1总体目标和要求

目标:以图形学算法为目标,深入研究。继而策划、设计并实现一个能够表现计算机图形学算法原理的或完整过程的演示系统,并能从某些方面作出评价和改进意见。

通过完成一个完整程序,经历策划、设计、开发、测试、总结和验收各阶段,达到:

1)巩固和实践计算机图形学课程中的理论和算法;

2)学习表现计算机图形学算法的技巧;

3)培养认真学习、积极探索的精神。

总体要求:策划、设计并实现一个能够充分表现图形学算法的演示系统,界面要求美观大方,能清楚地演示算法执行的每一个步骤。

开发环境:Viusal C++ 6.0,VC2005或其他你认为比较熟悉的环境。

1.2内容与要求

实验分为五项内容。

1.2.1 直线的生成

内容:用Bresenham算法画直线

要求:

1)鼠标移动时,显示鼠标当前位置

2)显示判别式的计算过程和下一点的选择策略

3)记录生成点的坐标

4)图形生成过程可以重复进行

1.2.2 圆弧的生成

内容:用Bresenham算法画圆

要求:

1)鼠标移动时,显示鼠标当前位置

2)显示判别式的计算过程和下一点的选择策略

3)记录生成点的坐标

4)图形生成过程可以重复进行

5)橡皮筋技术实现

1.2.3 线段裁剪

内容:用梁友栋-Barsky算法进行线段裁剪

要求:

1)对于线段裁剪,线段被窗口的四条边裁剪的过程要显示出来

2)用橡皮筋的形式输入剪裁线段

1.2.4 多边形裁剪

内容:用Sutherland-Hodgman算法进行多边形裁剪

要求:

1)裁剪过程需先输入一多边形,然后用窗口四边裁剪的过程中要显示顶点增删过程。

2)用橡皮筋的形式输入剪裁线段

1.2.5 综合

内容:把前四次的实验内容整合到一起

要求:

第2章总体设计

2.1 Bresenham算法画直线

2.1.1 Bresenham算法画直线理论基础

计算机是如何画直线的?简单来说,就是过各行各列像素中心构造一组虚拟的网格线,按直线从起点到终点的顺序计算各直线与歌垂直网格线的交点,然后确定各列像素中与此交点最近的像素。真实的直线是连续的,但我们的计算机显示的精度有限,不可能真正显示连续的直线,于是我们用一系列离散化后的点(像素)来近似表现这条直线。

2.1.2 Bresenham算法画直线原理

接下来的问题就是如何尽可能高效地找到这些离散的点,Bresenham直线算法就是一

个非常不错的算法。

Bresenham直线算法是用来描绘由两点所决定的直线的算法,它会算出一条线段在n 维光栅上最接近的点。这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线。是计算机图形学中最先发展出来的算法。

这个算法的流程图如下:

可以看到,算法其实只考虑了斜率在0 ~ 1 之间的直线,也就是与x 轴夹角在0 度

到45 度的直线。只要解决了这类直线的画法,其它角度的直线的绘制全部可以通过简单的坐标变换来实现。

2.2 Bresenham算法画圆

2.2.1 Bresenham算法画圆理论基础

Bresenham画圆算法与Bresenham 直线算法一样,其基本的方法是利用判别变量来判断选择最近的像素点,判别变量的数值仅仅用一些加、减和移位运算就可以计算出来。为了简便起见,考虑一个圆心在坐标原点的圆,而且只计算八分圆周上的点,其余圆周上的点利用对称性就可得到。

为什么只计算八分圆周上的点就可以了呢?和上面的直线算法类似,圆也有一个“八对称性”,如下图所示。

显然,我们只需要知道了圆上的一个点的坐标(x, y) ,利用八对称性,我们马上就能得到另外七个对称点的坐标。

2.2.2 Bresenham算法画圆原理

和直线算法类似,Bresenham画圆算法也是用一系列离散的点来近似描述一个圆,如下图。

Bresenham画圆算法的流程图如下。

可以看到,与画线算法相比,画圆的循环中用到了整数的乘法,相对复杂了一些。2.3 梁友栋-Barsky算法进行线段裁剪

2.3.1梁友栋-Barsky算法进行线段裁剪基本原理

我们知道,一条两端点为P1(x1,y1)、P2(x2,y2)的线段可以用参数方程形式表示:

x= x1+ u·(x2-x1)= x1+ u·Δx,y= y1+ u·(y2-y1)= y1+ u·Δy 式中,Δx=x2-x1,Δ

y=y2-y1,参数u在0~1之间取值,P(x,y)代表了该线段上的一个点,其值由参数u 确定,由公式可知,当u=0时,该点为P1(x1,y1),当u=1时,该点为P2(x2,y2)。如果点P(x,y)位于由坐标(xwmin,ywmin)和(xwmax,ywmax)所确定的窗口内,那么下式成立:xwmin≤x1+ u·Δx≤xwmax,ywmin≤y1+ u·Δy≤ywmax 这四个不等式可以表示为:u·pk ≤qk ,k=1,2,3,4

其中,p、q定义为p1=-Δx,q1=x1-xwmin

p2= Δx,q2=xwmax-x1

p3=-Δy,q3=y1-ywmin

p4= Δy,q4=ywmax-y1

可以知道:任何平行于窗口某边界的直线,其pk=0,k值对应于相应的边界(k=1,2,3,4对应于左、右、下、上边界)。如果还满足qk<0,则线段完全在边界外,应舍弃该线段。如果pk=0并且qk≥0,则线段平行于窗口某边界并在窗口内,见图中所示。

1、当pk<0时,线段从裁剪边界延长线的外部延伸到内部;

2、当pk>0时,线段从裁剪边界延长线的内部延伸到外部;

例如,当Δx≥0时,对于左边界p1<0(p1=-Δx),线段从左边界的外部到内部;对于右边界p2>0(p2=Δx),线段从右边界的内部到外部。

当Δy<0时,对于下边界p3>0(p3=-Δy),线段从下边界的内部到外部;对于上边界p4<0(p4=Δy),线段从上边界的外部到内部。

当pK≠0时,可以计算出参数u的值,它对应于无限延伸的直线与延伸的窗口边界k 的交点,即:

对于每条直线,可以计算出参数u1和u2,该值定义了位于窗口内的线段部分:

1、u1的值由线段从外到内遇到的矩形边界所决定(pk<0),对这些边界计算rk=qk/pk,u1取0和各个r值之中的最大值。

2、u2的值由线段从内到外遇到的矩形边界所决定(pk>0),对这些边界计算rk=qk/pk,u2取0和各个r值之中的最小值。

3、如果u1>u2,则线段完全落在裁剪窗口之外,应当被舍弃;否则,被裁剪线段的端点可以由u1和u2计算出来。

2.4 Sutherland-Hodgman算法进行多边形裁剪

2.4.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.4.2 点在边界内侧的判断方法

为了判断点是否在边界内侧可用坐标比较法和更通用的向量叉积符号判别法。

1、坐标比较法

将点的某个方向分量与边界进行比较。例如,判断某点是否在下边界内侧,用条件判别式:if(p[i][1]>=ymin) 即可。

2、向量叉积法

为简单计,测试点表示为P点。假设窗口边界方向为顺时针,如图中所示,对于其中任一边界向量,从向量起点A向终点B看过去:如果被测试点P在该边界线右边(即内侧),AB×AP的方向与X-Y平面垂直并指向屏幕里面,即右手坐标系中Z轴的负方向。反过来,如果P在该边界线的左边(即外侧),这时AB×AP的方向与X-Y平面垂直并指向屏幕外面,即右手坐标系中Z轴的正方向。设:点P(x,y)、点A(xA,yA)、点B(xB,yB),向量AB={(xB-xA),(yB-yA)},向量AP={(x-xA),(y-yA)},那么AB×AP的方向可由下式的符号来确定:V=(x[B]-x[A])*(y-y[A])- (x-x[A])*(y[B]-y[A]))

因此,当V≤0时,P在边界线内侧;而V>0时,P在边界线外侧。

2.4.4 Sutherland-Hodgeman多边形裁剪算法特点

Sutherland-Hodgeman多边形裁剪算法具有一般性,被裁剪多边形可以是任意凸多边形或凹多边形,裁剪窗口不局限于矩形,可以是任意凸多边形。

上面的算法是多边形相对窗口的一条边界进行裁剪的实现,对于窗口的每一条边界依次调用该算法程序,并将前一次裁剪的结果多边形作为下一次裁剪时的被裁剪多边形,即可得

到完整的多边形裁剪程序。

第3章详细设计

3.1 Bresenham算法画直线

3.1.1 Bresenham 算法画线算法具体实现过程

1、画点(x1, y2); dx=x2-x1; dy=y2-y1;计算误差初值P1=2dy-dx; i=1;

2、求直线的下一点位置:

xi+1=xi+1;

if Pi>0 则yi+1=yi+1;

否则yi+1=yi;

3、画点(xi+1, yi-1);

4、求下一个误差Pi+1;

if Pi>0 则Pi+1=Pi+2dy-2dx;

否则Pi+1=Pi+2dy;

5、i=i+1; if i

由上述算法思想编制算法程序。这个程序适用于所有8个方向的直线的生成。程序画出一条端点为(x1, y1)和(x2, y2)的直线。其中变量的含义是:P是误差;const1和const2,是误差的逐点变化量;inc是y的单位递变量,值为1或-1;tmp是用作象限变换时的临时变量。程序以判断|dx|>|dy|为分支,并分别将2a, 3a象限的直线和3b, 4b象限的直线变换到1a, 4a和2b, 1b方向去,以求得程序处理的简洁。

3.2 Bresenham算法画圆

3.2.1 Bresenham 算法画圆核心代码

根据Bresenham算法思想编写程序代码,在Bresenham算法画线的基础上画圆,程序代码如下:

void BresenhamCircle(int x0,int y0,int R)//,int color)

{ int x,y,d;

x=0;y=R;

d=3-2*R;

while(x

putpixel(x0+x,y0+y);

putpixel(x0+x,y0-y);

putpixel(x0-x,y0+y);

putpixel(x0-x,y0-y);

putpixel(x0+y,y0+x);

putpixel(x0+y,y0-x);

putpixel(x0-y,y0+x);

putpixel(x0-y,y0-x);

if(d<0) d=d+4*x+6;

else{d=d+4*(x-y)+10;y=y-1; }

x++;

}

}

3.3 梁友栋-Barsky算法进行线段裁剪

3.3.1梁友栋-Barsky算法推导过程

情形一pk=0

p1=p2=0

若q1<0或q2<0,则可删除直线段

若q1>=0且q2>=0,则进一步判断

u=qk/pk(k=3,4)

令 u1=max(0,u|pk<0)

u2=min(1,u|pk>0)

若u1>u2,则可删除直线段

若u1<=u2,将u1,u2代入直线方程,得到直线段的两个可见端点。

p3=p4=0

若q3<0或q4<0,则可删除直线段

若q3>=0且q4>=0,则进一步判断

u=qk/pk(k=1,2)

令 u1=max(0,u|pk<0)

u2=min(1,u|pk>0)

若u1>u2,则可删除直线段

若u1<=u2,将u1,u2代入直线方程,得到直线段的两个可见端点。

情形二pk不为0

u=qk/pk(k=1,2,3,4)

令u1=max(0,u|pk<0,u|pk<0)

u2=min(1,u|pk>0, u|pk>0)

若u1>u2,则可删除直线段

若u1<=u2,将u1,u2代入直线方程,得到直线段的两个可见端点。

3.3.2梁友栋-Barsky算法进行线段裁剪的步骤

(1)输入直线段的两端点坐标以及窗口的四条边界坐标。

(2)若Δx=0,则p1=p2=0。进一步判断是否满足q1<0或q2<0,若满足,则该直线段不在窗口内,转(7)。否则,满足q1>0且q2>0,则进一步计算u1和u2。转(5)。

(3)若Δy=0,则p3=p4=0。进一步判断是否满足q3<0或q4<0,若满足,则该直线段不在窗口内,转(7)。否则,满足q1>0且q2>0,则进一步计算u1和u2。转(5)。

(4)若上述两条均不满足,则有pk≠0(k=1,2,3,4)。此时计算u1和u2。

(5)求得u1和u2后,进行判断:若u1>u2,则直线段在窗口外,转(7)。若u1

(6)利用直线的扫描转换算法绘制在窗口内的直线段。

(7)算法结束。

3.4 Sutherland-Hodgman算法进行多边形裁剪

3.4.1 Sutherland—Hodgman多边形裁剪算法步骤

考虑多边形相对于一条边界及其延长线进行裁剪的算法:

1.从主函数得到待裁剪多边形的顶点序列P[][2]、顶点序列数n、窗口一条边界参数

直线段的裁剪

实验:直线段的裁剪 姓名:龙泽学号:20141090068 指导教师:吴昊 实验内容:采用Liang-Barsky算法对直线段进行裁剪。 实验设计:本次实验采用的是Liang-Barsky算法,根据这个算法需先定义直线段的起点坐标(x1,y1),终点坐标(x2,y2),以及裁剪框(矩形)的左边界(wxl),右边界(wxr),上边界(wyt),下边界(wyb),如void Line_Clipping(float x1, float y1, float x2, float y2,float Wxl,float Wxr,float Wyt,float Wyb),再结合鼠标mouse函数,实现点击鼠标左键显示矩形框和待裁剪的直线段,点击鼠标右键进行裁剪并显示裁剪过后的直线段,最终显示出来。 由于在Line_Clipping函数下用到了line函数,所以我在上面定义了个line 函数来绘制直线段(绘制直线段所采用的算法为Bresenham算法)。 程序代码: #include #include //初始化OpenGL场景 void myinit (void) { glClearColor (1, 1,1, 0); //将背景置成白色 glMatrixMode(GL_PROJECTION); gluOrtho2D(0,500,0,500); //设置投影变换,使用正交投影 } void setPixel(int x, int y)//在指定位置(x,y)绘制点图元 { glBegin (GL_POINTS);

glVertex2i(x,y);//绘制点的坐标 glEnd ( ); } // 绘制直线的方法 void line (int x1,int y1,int x2,int y2)//输入线段的两个端点坐标和画线颜色 { int x,y,dx,dy,s1,s2,p,temp,interchange,i; x=x1; y=y1;//设置象素坐标初值 dx=abs(x2-x1); dy=abs(y2-y1);//分别计算之间的差值 if(x2>x1) s1=1; else s1=-1; if(y2>y1) s2=1; else s2=-1; //判断起点和终点的位置,以确定是该加一个单位还是该减一个单位 if(dy>dx)//y方向增长快,将总步数设为y2-y1,每一步的y值为:y=y+1 { temp=dx;

计算机图形学裁剪算法详解

裁剪算法详解 在使用计算机处理图形信息时,计算机部存储的图形往往比较大,而屏幕显示的只是图的一部分。因此需要确定图形中哪些部分落在显示区之,哪些落在显示区之外,以便只显示落在显示区的那部分图形。这个选择过程称为裁剪。最简单的裁剪方法是把各种图形扫描转换为点之后,再判断各点是否在窗。但那样太费时,一般不可取。这是因为有些图形组成部分全部在窗口外,可以完全排除,不必进行扫描转换。所以一般采用先裁剪再扫描转换的方法。 (a)裁剪前 (b) 裁剪后 图1.1 多边形裁剪 1直线段裁剪 直线段裁剪算法比较简单,但非常重要,是复杂图元裁剪的基础。因为复杂的曲线可以通过折线段来近似,从而裁剪问题也可以化为直线段的裁剪问题。常

用的线段裁剪方法有三种:Cohen-Sutherland,中点分割算法和梁友栋-barskey 算法。 1.1 Cohen-Sutherland裁剪 该算法的思想是:对于每条线段P1P2分为三种情况处理。(1)若P1P2完全在窗口,则显示该线段P1P2简称“取”之。(2)若P1P2明显在窗口外,则丢弃该线段,简称“弃”之。(3)若线段既不满足“取”的条件,也不满足“弃”的条件,则在交点处把线段分为两段。其中一段完全在窗口外,可弃之。然后对另一段重复上述处理。 为使计算机能够快速判断一条直线段与窗口属何种关系,采用如下编码方法。延长窗口的边,将二维平面分成九个区域。每个区域赋予4位编码CtCbCrCl.其中各位编码的定义如下:

图1.2 多边形裁剪区域编码图5.3线段裁剪 裁剪一条线段时,先求出P1P2所在的区号code1,code2。若code1=0,且code2=0,则线段P1P2在窗口,应取之。若按位与运算code1&code2≠0,则说明两个端点同在窗口的上方、下方、左方或右方。可判断线段完全在窗口外,可弃之。否则,按第三种情况处理。求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段在窗口外,可弃之。在对另一段重复上述处理。在实现本算法时,不必把线段与每条窗口边界依次求交,只要按顺序检测到端点的编码不为0,才把线段与对应的窗口边界求交。 Cohen-Sutherland裁减算法 #define LEFT 1 #define RIGHT 2 #define BOTTOM 4

计算机图形学试题附答案完整版

名词解释 将图形描述转换成用像素矩阵表示的过程称为扫描转换。 1.图形 2.像素图 3.参数图 4.扫描线 5.构造实体几何表示法 6.投影 7.参数向量方程 8.自由曲线 9.曲线拟合 10.曲线插值 11.区域填充 12.扫描转换 三、填空 1.图形软件的建立方法包括提供图形程序包、和采用专用高级语言。 2.直线的属性包括线型、和颜色。 3.颜色通常用红、绿和蓝三原色的含量来表示。对于不具有彩色功能的显示系统,颜色显示为。 4.平面图形在内存中有两种表示方法,即和矢量表示法。 5.字符作为图形有和矢量字符之分。 6.区域的表示有和边界表示两种形式。 7.区域的内点表示法枚举区域内的所有像素,通过来实现内点表示。 8.区域的边界表示法枚举区域边界上的所有像素,通过给赋予同一属性值来实现边界表示。 9.区域填充有和扫描转换填充。 10.区域填充属性包括填充式样、和填充图案。 11.对于图形,通常是以点变换为基础,把图形的一系列顶点作几何变换后,

连接新的顶点序列即可产生新的变换后的图形。 12.裁剪的基本目的是判断图形元素是否部分或全部落在之内。 13.字符裁剪方法包括、单个字符裁剪和字符串裁剪。 14.图形变换是指将图形的几何信息经过产生新的图形。 15.从平面上点的齐次坐标,经齐次坐标变换,最后转换为平面上点的坐标,这一变换过程称为。 16.实体的表面具有、有界性、非自交性和闭合性。 17.集合的内点是集合中的点,在该点的内的所有点都是集合中的元素。 18.空间一点的任意邻域内既有集合中的点,又有集合外的点,则称该点为集合的。 19.内点组成的集合称为集合的。 20.边界点组成的集合称为集合的。 21.任意一个实体可以表示为的并集。 22.集合与它的边界的并集称集合的。 23.取集合的内部,再取内部的闭包,所得的集合称为原集合的。 24.如果曲面上任意一点都存在一个充分小的邻域,该邻域与平面上的(开)圆盘同构,即邻域与圆盘之间存在连续的1-1映射,则称该曲面为。 25.对于一个占据有限空间的正则(点)集,如果其表面是,则该正则集为一个实体(有效物体)。 26.通过实体的边界来表示一个实体的方法称为。 27.表面由平面多边形构成的空间三维体称为。 28.扫描表示法的两个关键要素是和扫描轨迹。 29.标量:一个标量表示。 30.向量:一个向量是由若干个标量组成的,其中每个标量称为向量的一个分量。 四、简答题 1. 什么是图像的分辨率?

计算机图形学裁剪

《计算机图形学》实验报告 学院:理学院专业:信息与计算科学班级:姓名学号指导教师实验时间 4. 实验地点计算机实验室成绩实验项目名称裁剪 实 验 环 境 VC++ 6.0 实 验内容 (1)理解直线裁剪的原理(Cohen-Surtherland算法、梁友栋算法) (2)利用VC+OpenGL实现直线的编码裁剪算法,在屏幕上用一个封闭矩形裁剪任意一条直线。 (3)调试、编译、修改程序。 实验原理编码裁剪算法的主要思想是:对于每条线段,分为三种情况处理。(1)若线段完全在窗口之内,则显示该线段,称为“取”;(2)若线段明显在窗口之外,则丢弃该线段,称为“弃”;(3)若线段既不满足“取”的条件,也不满足“舍”的条件,则把线段分割为两段。其中一段完全在窗口之外,可弃之;对另一段则重复上述处理 实验过程#include #include #include #define LEFT_EDGE 1 #define RIGHT_EDGE 2 #define BOTTOM_EDGE 4 #define TOP_EDGE 8 void LineGL(int x0,int y0,int x1, int y1) { glBegin(GL_LINES); glColor3f(1.0f,0.0f,0.0f); glVertex2f(x0,y0); glColor3f(0.0f,1.0f,0.0f); glVertex2f(x1,y1); glEnd();

} struct Rectangle { float xmin,xmax,ymin,ymax; }; Rectangle rect; int x0,y0,x1,y1; int CompCode(int x,int y,Rectangle rect) { int code=0x00; if(yrect.ymax) code=code|8; if(x>rect.xmax) code=code|2; if(x

直线段的裁剪

{ 实验:直线段的裁剪 姓名:龙泽学号:20141090068 指导教师:吴昊 实验内容:采用Liang-Barsky 算法对直线段进行裁剪。 实验设计:本次实验采用的是Liang-Barsky 算法,根据这个算法需先定义直线段的起点坐标(x1,y1 ),终点坐标(x2,y2 ),以及裁剪框(矩形)的左边界(wxl), 右边界(wxr) ,上边界(wyt) ,下边界(wyb) ,如void Line_Clipping(float x1, float y1, float x2, float y2,float Wxl,float Wxr,float Wyt,float Wyb) ,再结合鼠标mouse函数,实现点击鼠标左键显示矩形框和待裁剪的直线段,点击鼠标右键进行裁剪并显示裁剪过后的直线段,最终显示出来。 由于在Line_Clipping 函数下用到了line 函数,所以我在上面定义了个line 函数来绘制直线段(绘制直线段所采用的算法为Bresenham算法)。 程序代码: #include #include //初始化OpenGL场景 void myinit (void) { glClearColor (1, 1,1, 0); // 将背景置成白色 glMatrixMode(GL_PROJECTION); gluOrtho2D(0,500,0,500); // 设置投影变换,使用正交投影 } void setPixel(int x, int y)// 在指定位置(x,y)绘制点图元 glBegin (GL_POINTS);

线段裁剪算法

计算机图形学 实验报告 实验(四) 实验题目:线段裁剪算法 指导老师:吴颖斌 专业:数字媒体技术 班级: 1306班 姓名: xx(20131006xx) 2014年 11月19日

一、实验类型 验证性。 二、实验目的和要求 目的:编写线段裁剪算法程序,验证算法的正确性。 要求:编写Cohen-Sutherland直线剪裁算法程序,编译、调试,查看运行结果。 三、实验中用到的硬件设备及软件环境 Microsoft Visual C++ 6.0和PC机 四、实验主要程序代码 Cohen-Sutherland直线剪裁算法 (1)主要步骤和代码: 步骤1:创建Code_Clip工程文件; 步骤2:在主程序的程序头部定义符号常量(鼠标双击“CCode_ClipView”,添 加至 “class CCode_ClipView : public …………”之前) #define LEFT 1 #define RIGHT 2 #define BOTTOM 4 #define TOP 8 步骤3:定义成员变量和成员函数(鼠标双击“CCode_ClipView”,添加至“class CCode_ClipView : public …………”之内)) int WT; int WB; int WR; int WL; 步骤4:在构造函数中为窗口边界变量赋初值 CCode_ClipView::CCode_ClipView() { // TODO: add construction code here WL=100;WR=400;WB=100;WT=300; } 步骤5:编写成员函数程序(在“CCode_ClipView”单击鼠标右键-->Add member function……) void CCode_ClipView::encode(int x, int y, int *code) {

直线裁剪算法研究(Cohen-Sutherland算法和Liang-Barsky算法)

直线裁剪算法研究 摘要:直线裁剪是计算机图形学中的一个重要技术,在对常见的直经线裁剪的算法分析的基础上,针对Cohen-Sutherland算法和Liang-Barsky算法进行了分析研究。并对两种算法了计算直线与窗口边界的交点时,进行了有效有比较。 关键词:裁剪;算法;Cohen-Sutherland;Liang-Barsky; 1 引言 直线是图形系统中使用最多的一个基本元素。所以对于直线段的裁剪算法是被研究最深入的一类算法,目前在矩形窗口的直线裁剪算法中,出现了许多有效的算法。其中比较著名的有:Cohen-Sutherland算法、中点分割算法、Liang-Ba rsky算法、Sobkow-Pospisil-Yang算法,及Nicholl-Lee-Ncholl算法等。 2 直线裁剪的基本原理 图1所示的为直线与窗口边界之间可能出现的几种关系。可以通过检查直线的两个端点是否在窗口之内确定如何对此直线裁剪。如果一直线的两个端点均在窗口边界之内(如图1中P5到P6的直线),则此直线应保留。如果一条直线的一个端点在窗口外(如P9)另一个点在窗口内(如P10),则应从直线与边界的交点(P9)处裁剪掉边界之外的线段。如果直线的两个端点均在边界外,则可分为两种情况:一种情况是该直线全部在窗口之外;另一种情况是直线穿过两个窗口边界。图中从P3到P4的直线属于前一种情况,应全部裁剪掉;从P7到P8的直线属于后一种情况,应保留P7到P8的线段,其余部分均裁剪掉。 图1直线相对干窗口边界的栽剪 直线裁剪算法应首先确定哪些直线全部保留或全部裁剪,剩下的即为部分裁剪的直线。对于部分裁剪的直线则首先要求出这些直线与窗口边界的交点,把从交点开始在边界外的部分裁剪掉。一个复杂的画面中可能包含有几千条直线,为了提高算法效率,加快裁剪速度,应当采用计算量较小的算法求直线与窗口边界的交点。

Weiler-Atherton任意多边形裁剪算法

Weiler-Atherton任意多边形裁剪 Sutherland-Hodgeman算法解决了裁剪窗口为凸多边形窗口的问题,但一些应用需要涉及任意多边形窗口(含凹多边形窗口)的裁剪。Weiler-Atherton多边形裁剪算法正是满足这种要求的算法。 一、Weiler-Atherton任意多边形裁剪算法描述: 在算法中,裁剪窗口、被裁剪多边形可以是任意多边形:凸的、凹的(内角大于180o)、甚至是带有内环的(子区),见下图。 裁剪窗口和被裁剪多边形处于完全对等的地位,这里我们称: 1、被裁剪多边形为主多边形,记为A; 2、裁剪窗口为裁剪多边形,记为B。 主多边形A和裁剪多边形B的边界将整个二维平面分成了四个区域: 1、A∩B(交:属于A且属于B); 2、A-B(差:属于A不属于B); 3、B-A(差:属于B不属于A); 4、A∪B(并:属于A或属于B,取反;即:不属于A且 不属于B)。 内裁剪即通常意义上的裁剪,取图元位于窗口之内的部 分,结果为A∩B。 外裁剪取图元位于窗口之外的部分,结果为A-B。 观察右图不难发现裁剪结果区域的边界由被裁剪多边形的 部分边界和裁剪窗口的部分边界两部分构成,并且在交点处边 界发生交替,即由被裁剪多边形的边界转至裁剪窗口的边界, 或者反之。由于多边形构成一个封闭的区域,所以,如果被裁 剪多边形和裁剪窗口有交点,则交点成对出现。这些交点分成两类: 一类称“入”点,即被裁剪多边形由此点进入裁剪窗口,如图中a、c、e; 一类称“出”点,即被裁剪多边形由此点离开裁剪窗口,如图中b、d、f。 二、Weiler-Atherton任意多边形裁剪算法思想:

梁友栋-Barsky直线裁剪算法计算机图形学课程设计

河南理工大学 万方科技学院 课程设计报告 2011 — 2012学年第二学期 课程名称计算机图形学 设计题目计算机图形学基本算法 演示系统设计 学生姓名 学号 专业班级网络11升—1班 指导教师徐文鹏 2012 年5 月28 日

目录 第1章设计内容与要求 (1) 1.1 总体目标和要求 (1) 1.2内容与要求 (1) 1.2.1 直线的生成 (1) 1.2.2 圆弧的生成 (1) 1.2.3 线段裁剪 (2) 1.2.4 多边形裁剪 (2) 1.2.5 综合 (2) 第2章总体设计 (3) 2.1 Bresenham算法画直线 (3) 2.1.1 Bresenham算法画直线理论基础 (3) 2.1.2 Bresenham算法画直线原理 (3) 2.2 Bresenham算法画圆 (4) 2.2.1 Bresenham算法画圆理论基础 (4) 2.2.2 Bresenham算法画圆原理 (5) 2.3 梁友栋-Barsky算法进行线段裁剪 (6) 2.3.1梁友栋-Barsky算法进行线段裁剪基本原理 (6) 2.4 Sutherland-Hodgman算法进行多边形裁剪 (8) 2.4.1 Sutherland—Hodgman多边形裁剪算法思想 (8) 2.4.2 点在边界内侧的判断方法 (8) 2.4.4 Sutherland-Hodgeman多边形裁剪算法特点 (8) 第3章详细设计 (9) 3.1 Bresenham算法画直线 (9) 3.1.1 Bresenham 算法画线算法具体实现过程 (9) 3.2 Bresenham算法画圆 (9) 3.2.1 Bresenham 算法画圆核心代码 (9)

图形学_直线裁剪__实验报告

实验报告 实验报告 实验报告三 一、实验目的 1、理解、巩固线段裁剪的含义; 2、掌握Cohen-Sutherland线段裁剪方法。 二、算法原理介绍 对于每条线段P1P2,分为三种情况处理。 (1)若P1P2完全在窗口内,则显示该线段P1P2,简称“取”之。 (2)若P1P2明显在窗口外,则丢弃该线段,简称“弃”之。 (3)若线段既不满足“取”的条件,也不满足“弃”的条件,则把线段分为两段。 其中一段完全在窗口外,可弃之。然后对另一段重复上述处理。 三、程序源代码 #include #include #define LEFT 1 #define RIGHT 2 #define BOTTOM 4 #define TOP 8

#define XL 100 #define XR 300 #define YB 100 #define YT 300 void encode(float x,float y,int * code) { int c=0; if(xXR)c=c | RIGHT; if(yYT)c=c | TOP; *code=c; return; } /*(x1,y1)与(x2,y2)是线段端点坐标, 其它四个参数分别定义窗口的左,下,右,上边界*/ void C_S_LineCLip(float x1, float y1, float x2, float y2) { int code1,code2,code; float x,y; encode(x1,y1,&code1); encode(x2,y2,&code2); while((code1!=0) || (code2!=0)) { if((code1&code2)!=0)return; code=code1; if(code1==0)code=code2; if((LEFT&code)!=0)/*线段与左边界相交*/ { x=XL; y=y1+(y2-y1)*(XL-x1)/(x2-x1); } else if((RIGHT&code)!=0)/*线段与右边界相交*/ { x=XR;

计算机图形学_实验报告三_图形裁剪算法

图形裁剪算法 1.实验目的: 理解区域编码 设计直线裁剪算法 编程实现直线裁剪算法 2.实验描述: 设置裁剪窗口坐标为:wxl=250;wxr=850;wyb=250;wyt=450;裁剪前如下图所示: 裁剪后结果为: 3.算法设计: 直线裁剪算法: 假设裁剪窗口是标准矩形,由上(y=wyt)、下(y=wyb)、左(x=wxl)、右(x=wxr)四条边组成,如下图所示。延长窗口四条边形成9个区域。根据被裁剪直线的任一端点P(x,y)所处的窗口区域位置,可以赋予一组4位二进制区域码C4C3C2C1。

编码定义规则: 第一位C1:若端点位于窗口之左侧,即XWxr,则C2=1,否则C2=0。 第三位C3:若端点位于窗口之下侧,即YWyt,则C4=1,否则C4=0。 裁剪步骤: 1. 若直线的两个端点的区域编码都为0,即RC1|RC2=0(二者按位相或的结果为0,即RC1=0 且RC2=0),说明直线两端点都在窗口内,应“简取”。 2. 若直线的两个端点的区域编码都不为0,即RC1&RC2≠0(二者按位相与的结果不为0,即RC1≠0且RC2≠0,即直线位于窗外的同一侧,说明直线的两个端点都在窗口外,应“简弃”。 3. 若直线既不满足“简取”也不满足“简弃”的条件,直线段必然与窗口相交,需要计算直线与窗口边界的交点。交点将直线分为两段,其中一段完全位于窗口外,可“简弃”。对另一段赋予交点处的区域编码,再次测试,再次求交,直至确定完全位于窗口内的直线段为止。 4. 实现时,一般按固定顺序左(x=wxl)、右(x=wxr)、下(y=wyb)、上(y=wyt)求解窗口与直线的交点。

Cohen-Sutherland直线裁剪算法

实验三图形裁剪算法 1.实验目的: 理解区域编码(Region Code,RC) 设计Cohen-Sutherland直线裁剪算法 编程实现Cohen-Sutherland直线裁剪算法 2.实验描述: 设置裁剪窗口坐标为:wxl=250;wxr=850;wyb=250;wyt=450;裁剪前如下图所示: 裁剪后结果为: 3.算法设计: Cohen-Sutherland 直线裁剪算法: 假设裁剪窗口是标准矩形,由上(y=wyt)、下(y=wyb)、左(x=wxl)、右(x=wxr)四条边组成,如下图所示。延长窗口四条边形成9个区域。根据被裁剪直线的任一端点P(x,y)所处的窗口区域位置,可以赋予一组4位二进制区域码C4C3C2C1。

为了保证窗口内直线端点的编码为零,编码规则定义如下: 第一位:若端点位于窗口之左侧,即xwxr,则C2=1,否则C2=0。 第三位:若端点位于窗口之下侧,即ywyt,则C4=1,否则C4=0。 裁剪步骤: 1. 若直线的两个端点的区域编码都为零,即RC1|RC2=0(二者按位相或的结果为零,即RC1=0 且RC2=0),说明直线两端点都在窗口内,应“简取”之。 2. 若直线的两个端点的区域编码都不为零,即RC1&RC2≠0(二者按位相与的结果不为零,即RC1≠0且RC2≠0,即直线位于窗外的同一侧,说明直线的两个端点都在窗口外,应“简弃”之。 3. 若直线既不满足“简取”也不满足“简弃”的条件,直线必然与窗口相交,需要计算直线与窗口边界的交点。交点将直线分为两段,其中一段完全位于窗口外,可“简弃”之。对另一段赋予交点处的区域编码,再次测试,再次求交,直至确定完全位于窗口内的直线段为止。 4. 实现时,一般按固定顺序左(x=wxl)、右(x=wxr)、下(y=wyb)、上(y=wyt)求解窗口与直线的交点。

直线段剪裁实验报告

《计算机图形学》实验报告 《实验名称》 直线段裁剪 学号 专业 班级 天津大学计算机科学与技术学院

一、实验目的 熟练掌握Cohen-Sutherland直线裁剪算法,并编程实现 二、实验内容 (1) 裁剪窗口为矩形窗口,且矩形边和坐标轴平行,长宽自己定。 (2) 待裁剪线段端点坐标自己定;裁剪线段涵盖完全可见、不完全可见、 完全不可见类型。 (3) 要求显示待裁剪线段并用不同颜色标示出裁剪结果。 实现方法:一般情况下,需要判断一条直线是全部可见,全部不可见,部分裁剪(一段裁剪),全部裁剪(两端裁剪)。通过把裁剪区域分成许多部分,然后给每一段被裁剪的线段的两端分配一位代码,通过少量if语句和一个case语句就可以判断出具体情况。 伪代码如下: #define CLIP_CODE_C 0x0000 #define CLIP_CODE_N 0x0008 #define CLIP_CODE_S 0x0004

#define CLIP_CODE_E 0x0002 #define CLIP_CODE_W 0x0001 #define CLIP_CODE_NE 0x000a #define CLIP_CODE_SE 0x0006 #define CLIP_CODE_NW 0x0009 #define CLIP_CODE_SW 0x0005 实验步骤: 1)生成裁剪窗口,窗口由直线xl=250,xr=850,yb=250,yt=450 2)绘制直线段 3)编写Cohen-Sutherland直线裁剪算法,对直线段进行裁剪 编码定义规则: 第一位C1:若端点位于窗口之左侧,即Xxr,则C2=1,否则C2=0。 第三位C3:若端点位于窗口之下侧,即Yyt,则C4=1,否则C4=0。 裁剪步骤: 对所有直线的端点都建立了区域码之后,就可按区域码判断直线在窗口

计算机图形学-实验五 直线和多边形的裁剪

大学实验报告 学院:计算机科学与信息学院专业:软件工程班级:102班 学号实验组实验时间指导教师成绩实验项目名称实验五直线和多边形的裁剪 实 验 目 的 掌握直线段的裁剪算法以及多边形的裁剪算法 实 验要求熟练掌握直线段的裁剪算法以及多边形的裁剪算法的基本原理,并编写测试代码进行实验。 实验原理 Cohen-Sutherland直线剪裁算法 以区域编码为基础,将窗口及其周围的,8个方向以4 bit的二进制数进行编码。 右图所示的编码方法将窗口及其邻域 分为5个区域: ⑴域:区域(0000)。 ⑵上域:区域(1001, 1000, 1010)。 ⑶下域:区域(0101, 0100, 0110)。 ⑷左域:区域(1001, 0001, 0101)。 ⑸右域:区域(1010, 0010, 0110)。 当线段的两个端点的编码的逻辑“与”非零时,线段为显然不可见的,对某线段的两个端点的区号进行位与运算,可知这两个端点是否同在视区的上、下、左、右; Cohen-Sutherland直线剪裁算法的算法思想是: 对于每条线段P1P2分为三种情况处理。(1)若P1P2完全在窗口,则显示该线段P1P2简称“取”之。(2)若P1P2明显在窗口外,则丢弃该线段,简称“弃”之。(3)若线段既不满足“取”的条件,也不满足“弃”的条件,则在交点处把线段分为两段。其中

while (code1 != 0 || code2 != 0) { if ((code1 & code2) != 0) {// 两端点的编码相与不为0,表示直线在窗口外 return; } if (code1 != 0) { code = code1; } else { code = code2; } if ((LEFT & code) != 0) {// 直线的端点与矩形窗口的左边编码相与!=0 x = XL; y = y1 + (y2 - y1) * (XL - x1) / (x2 - x1);// 求直线与矩形窗口的左边界的交点 } else if ((RIGHT & code) != 0) {// 直线的端点与矩形窗口的右边编码相与!=0 x = XR; y = y1 + (y2 - y1) * (XR - x1) / (x2 - x1);// 求直线与矩形窗口的右边界的交点 } else if ((BOTTOM & code) != 0) {// 直线的端点与矩形窗口的下边编码相与!=0 y = YB; x = x1 + (x2 - x1) * (YB - y1) / (y2 - y1);// 求直线与矩形窗口的下边界的交点 } else if ((TOP & code) != 0) {// 直线的端点与矩形窗口的上边编码相与!=0 y = YT; x = x1 + (x2 - x1) * (YT - y1) / (y2 - y1);// 直线的端点与矩形窗口的

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

简单多边形裁剪算法 摘要:多边形裁剪算法与线性裁剪算法具有更广泛的实用意义,因此它是目前 裁剪研究的主要课题。本文主要介绍了一种基于多边形顶点遍历的简单多边形裁剪算法,它有效降低了任意多边形裁剪复杂度。通过记录交点及其前驱、后继信息,生成结果多边形,该算法简化了交点的数据结构,节省了存储空间,降低了算法的时间复杂度,具有简单、易于编程实现、运行效率高的特点。 关键词:多边形裁剪;交点;前驱;后继;矢量数组 一、技术主题的基本原理 简单多边形裁剪算法综合考虑现有多边形裁剪算法的优缺点,它是一种基于多边形顶点遍历来实现简单多边形裁剪工作的。其主要的原理是遍历多边形并把多边形分解为边界的线段逐段进行裁剪,输出结果多边形。 二、发展研究现状 近年来,随着遥感绘图、CAD辅助设计、图象识别处理技术的发展,图形裁剪算法从最初在二维平面上线和图形的裁剪扩展到三维空间里体和场的裁剪,国内外相继提出不少行之有效的算法,但越来越复杂的图形和计算也对算法的速度和适用性提出了越来越高的要求。因此,不断简化算法的实现过程,完善细节处理,满足大量任意多边形的裁剪也就成了当今算法研究的焦点之一。 以往多边形裁剪算法不是要求剪裁多边形是矩形,就是必须判断多边形顶点的顺时针和逆时针性,即存在不实用或者是增加了多边形裁剪算法的难度。为了解决现在的问题,我们研究现在的新多边形算法,其中,裁剪多边形和被裁剪多边形都可以是一般多边形,且不需要规定多边形输入方向。它采用矢量数组结构,只需遍历剪裁多边形和被裁剪多边形顶点即完成多边形的裁剪,具有算法简单、运行效率高的特点。 三、新算法设计 1、算法的思想 本算法是为了尽量降低任意多边形裁剪算法复杂度而提出的,其主要思想是采用矢量数组结构来遍历裁剪多边形和被裁多边形顶点,记录裁剪多边形和被裁减多边形交点及其前驱、后继信息,并通过记录相邻交点的线段,然后通过射线法选择满足条件的线段,之后进行线段连接,输出对应的裁剪结果。算法数据结构简单,即没有用常用的数据结构,如线性链表结构、双向链表结构和树形结构,这样就节省了存储空间,增加算法的效率。 2、主要数据结构 多边形裁剪算法的核心是数据结构,它决定了算法的复杂度和计算效率。兼顾数据结构简单和节省存储空间的目的,简单多边形裁剪算法是基于矢量数组vector的数据结构进行裁剪的,多边形矢量数组的每个元素表示多边形顶点,且按顶点输入的顺序存储。裁剪多边形和被裁剪多边以下我们分别用S和C表示,

计算机图形学Cohen-Sutherland直线裁剪算法源码c++

Cohen-Sutherland直线段裁减算法实验报告 实验现象: 核心代码: Cohen-Sutherland直线段裁减算法: void CLineClippingView::OnSutherlandID() ////////版权所有赵才{ // TODO: Add your command handler code here CDC* pDC=GetDC(); CPen newpen(PS_SOLID,1,RGB(255,255,0)); CPen *old=pDC->SelectObject(&newpen); // RedrawWindow(); //绘制N条直线段; // pDC->MoveTo(ptset[i]); // pDC->LineTo(ptset[i+1]); int i=0; while(i

int code2=encode(ptset[i+1].x,ptset[i+1].y); if((code1|code2)==0)//简取 { pDC->MoveTo(ptset[i]); pDC->LineTo(ptset[i+1]); i+=2; continue; } else { if((code1 & code2)!=0)//简弃 { i+=2; continue; } else { if(code1==0) { int tx,ty,ct; ct=code1; code1=code2; code2=ct; tx=ptset[i].x; ty=ptset[i].y; ptset[i].x= ptset[i+1].x; ptset[i].y= ptset[i+1].y; ptset[i+1].x=tx; ptset[i+1].y=ty; // pDC->MoveTo(ptset[i]); // pDC->LineTo(ptset[i+1]); } float k=float(ptset[i+1].y-ptset[i].y)/float(ptset[i+1].x-ptset[i].x); if(code1 & LEFT) { // ptset[i].y=int(k*(XL-ptset[i].x)+ptset[i].y+0.5); ptset[i].x=XL; continue; } if(code1 & RIGHT)

计算机图形学裁剪算法

一、实验目标 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,表明两端点必定处于某一边界的同一外侧,因而整个线段全在窗外,应予舍弃。 (3)不属于上面两种情况,均需要求交点。 3、求交点 假设算法按照:左、右、下、上边界的顺序进行求交处理,对每一个边界求完交点,并相关处理后,算法转向第2步,重新判断,如果需要接着进入下一边界的处理。 为了规范算法,令线段的端点P 1为外端点,如果不是这样,就需要P 1 和P 2 交换端点。 当条件(C1&0001≠0)成立时,表示端点P1位于窗口左边界外侧,按照求交公式,进行对左边界的求交运算。 依次类推,对位于右、下、上边界外侧的判别,应将条件式中的0001分别改为0010、0100、1000即可。 求出交点P后,用P1=P来舍去线段的窗外部分,并对P1重新编码得到C1,接下来算法转回第2步继续对其它边界进行判别。 Liang-Barsky线段裁剪算法思想: 我们知道,一条两端点为P1(x1,y1)、P2(x2,y2)的线段可以用参数方程形式表示: x= x1+ u·(x2-x1)= x1+ u·Δx y= y1+ u·(y2-y1)= y1+ u·Δy0≤u≤1式中,Δx=x2-x1,Δy=y2-y1,参数u在0~1之间取值,P(x,y)代表了该线段上的一个点,其值由参数u确定,由公式可知,当u=0时,该点为P1(x1,y1),当u=1时,该点为P2(x2,y2)。如果点P(x,y)位于由坐标(xw min,

计算机图形学Cohen-Sutherland直线裁剪算法实验

《计算机图形学实验》报告 任课教师:钱文华 2016年春季学期 实验:Cohen-Sutherland直线裁剪算法实验时间:2016年11月3日 实验地点:信息学院2204

实验目的:掌握Cohen-Sutherland直线裁剪算法 程序代码: #include #include #include #include #include #include #include int a,b,a1,b1,pp0,pq0,pp1,pq1; void setPixel(GLint x,GLint y){ glBegin(GL_POINTS); glVertex2i(x,y); glEnd(); } void init(void){ glClearColor(1.0,1.0,1.0,0.0); glMatrixMode(GL_PROJECTION);

gluOrtho2D(0.0,200.0,0.0,150.0); } void LineDDA(int x0,int y0,int xEnd,int yEnd){ int dx = xEnd - x0; int dy = yEnd - y0; int steps,k; float xIncrement,yIncrement,x = x0,y = y0; if(abs(dx)>abs(dy)) steps = abs(dx); else steps = abs(dy); xIncrement = float(dx)/float(steps); yIncrement = float(dy)/float(steps); for (k = 0;k

线段的裁剪

实验项目:线段的裁剪 一、实验目的与要求 1、掌握线段裁剪算法原理,并实现其算法。 2、理解多边形裁剪、字符裁剪算法思想,能编程实现其算法。 二、实验内容 1、实现直线段的标号法(Cohen-Sutherland)、矩形窗口裁剪算法。 2、参考教材中的算法,用矩形窗口实现多边形的Sutherland-Hodgman裁剪算法。 三、重要算法分析 主要思想: 以区域编码为基础,将窗口及其周围的8个方向以4 bit的二进制数进行编码。如图所示的编码方法将窗口及其邻域分为9个区域。编码为:上下右左。 当线段的两个端点的编码的逻辑“或”为零时,线段显然在窗口内,为可见的。 当线段的两个端点的编码的逻辑“与”非零时,线段显然为不可见的。 当线段的两个端点的编码的逻辑“与”为零时,线段既不能直接舍弃,也不能直接保留。 对某线段的两各端点的区号进行位与运算,可知这两个端点是否同在视区的上、下、左、右。此直线与上(下、左、右)边框求交,删去边框以上(下、左、右)的部分,重复这一过程。 对每条直线,如P1P2利用以下步骤进行判断: ①对直线两端点P1、P2编码分别记为C1(P1)={a1, b1, c1, d1},C2(P2)={a2, b2, c2, d2}其中,a i、b i、c i、 d i取值范围为{1, 0},i∈{1, 2}。 ②如果a i=b i=c i=d i=0,则显示整条直线,取出下一条直线,返回步骤①;否则,进入步骤③。 ③如果| a1–a2|=1,则求直线与窗上边(y=y w–max)的交点,并删去交点以上部分。如果| b1–b2 |=1,| c1–c2 |=1,| d1–d2|=1,进行类似处理。 ④返回步骤①判断下一条直线。

计算机图形学 二维裁剪算法Cohen_Sutherland的实现

实验六二维裁剪算法Cohen_Sutherland的实现 一、实验目的: 理解并掌握直线裁剪算法。使用Visual C++实现二维直线的裁剪的Cohen_Sutherland算法。对窗口进行编码,并实现相应的裁剪函数。 二、实验内容及要求: 1、要求用消息映射的方式,绘制出一个裁剪窗口,大小为200×150象素; 2、按照例程的步骤画出3条典型线段,分别对应于完全在裁剪窗口内、完全在裁剪窗口外、穿过 裁剪窗口三种情况,并按照本实验例程的方法用颜色分别表示出裁剪后的情况; 3、按要求撰写实验报告,写出实验心得,并在实验报告中附上程序的核心算法代码。 三、实验设备: 微机,Visual C++6.0 四、实验内容及步骤: 1、打开VC,新建一个MFC Appwizard项目,选择创建单文档工程(SDI工程)。假设工程名为Clip。 如图1和图2所示。 图1

图2 2、在图2的界面上点击Finish,完成工程的创建。 3、在视图类ClipView中定义变量CRect rect; 用于记录裁剪窗口的位置; 4、在ClipView.cpp文件中定义四个宏,记录裁剪窗口的上下左右四个位置: #define LEFT 100 #define RIGHT 300 #define TOP 150 #define BOTTOM 310 5、在视图类的构造函数中为rect赋值; CClipView::CClipView() { // TODO: add construction code here rect = CRect(LEFT, TOP, RIGHT, BOTTOM); } 6、在视图类(类CFillView中)的OnDraw()函数中绘制裁剪矩形,OnDraw函数的代码如下: void CClipView::OnDraw(CDC* pDC) { CClipDoc* pDoc = GetDocument(); ASSERT_V ALID(pDoc); // TODO: add draw code for native data here pDC->Rectangle(&rect); } 7、在视图类(类CFillView中)添加成员函数int Encode(int x, int y),该函数用于对线段的两个顶点 进行Cohen_Sutherland编码。函数体如下: int CClipView::Encode(int x, int y) { int nCode = 0; if(x < LEFT) nCode = nCode | 0x01; if(x > RIGHT) nCode = nCode | 0x02; if(y > BOTTOM)

相关文档
最新文档