当前位置:文档之家› 梁友栋-Barsky直线裁剪算法计算机图形学课程设计

梁友栋-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算法画圆 (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)

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

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

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

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

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

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

第4章功能实现 (14)

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

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

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

4.4 Sutherland-Hodgman算法进行多边形裁剪测试结果 (16)

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

第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、窗口一条边界参数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.做返回准备:

5.将新的多边形顶点序列Q又逐一放回原多边形顶点序列P中:P=Q;

6.将新的多边形顶点数j放回原多边形顶点数n中:n=j;

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

在显示函数中将各个算法添加到一个程序中,使用右键菜单的特殊功能实现画线、画圆、线段裁剪和多边形裁剪,主要是processMenuEvents函数和createGLUTMenus函数的编写。这两个函数的程序代码如下:

void processMenuEvents(int option)

{ switch (option) {

case 1:select = 1;

glutPostRedisplay();

break;

case 2: select = 2;

glutPostRedisplay();

break;

case 3:select = 3;

glutPostRedisplay();

break;

case 4:select =4;

glutPostRedisplay();

break;

default: break;}

}

void createGLUTMenus()

{ int menu;

menu = glutCreateMenu(processMenuEvents);

glutAddMenuEntry("Bresenham Line",1);

glutAddMenuEntry("Bresenham Circle",2);

glutAddMenuEntry("Liang-Barsky Cut",3);

glutAddMenuEntry("Sutherland-Hodgman Cut",4);

glutAttachMenu(GLUT_RIGHT_BUTTON);

}

void Display()

{glClear(GL_COLOR_BUFFER_BIT);

Wangge();

glColor3f (0.0f, 0.0f, 0.0f);

glRectf(rect.xmin,rect.ymin,rect.xmax,rect.ymax);

if(select == 1) myDisplay_Line();

else if(select==2) myDisplay_Circle();

else if(select==3) myDisplay_cut();

else if(select==4) myDisplay_cutGraphics();

glutSwapBuffers();

glFlush();

}

第4章功能实现4.1用Bresenham算法画线测试结果

打开vc++6.0,加载画线代码并运行,点击画线并输入数据:

然后点击Bresenham算法,就得到结果:

4.2用Bresenham算法画圆测试结果

打开vc++6.0,加载画圆代码并运行,然后测试结果如下:

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

打开vc++6.0,加载画圆代码并运行,先点击画线:

然后点击裁剪得到如下结果:

4.4 Sutherland-Hodgman算法进行多边形裁剪测试结果

Sutherland-Hodgman算法中来实现多边形的裁剪,不同图形裁剪的结果如图所示。

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

运行该程序后,出现主界面,然后单击鼠标右键,出现4个菜单项,分别是Bresenham Line、Bresenham Circle、Liang-Barsky Cut、Sutherland-Hodgman Cut。单击Bresenham Line 项可以画线,单击Bresenham Circle项可以画圆,单击Liang-Barsky Cut项可以进行线段裁剪,单击Sutherland-Hodgman Cut项可以进行多边形裁剪。

第5章总结

通过本次课程设计,使我进一步深入了解了计算机图形学和对vc的使用,也提高了我对程序的理解和调试能力。程序的编写也经历了问题的提出及分析,简化,再简化,最终编程实现的过程。该设计过程中遇到了很多的问题,有些问题任然还没有解决,程序也存在着很大不足,但通过自己动手,真正提高了我的动手能力。同时也得到了同学的帮助使我学到了很多东西。

计算机图形学输出直线实验报告

六盘水师范学院计科系本科班计算机图形学实验报告 系别:计科系 课程名称:计算机图形学 班级:本科 学号:114077031057 学生姓名:郑月儒 一、实验目的 1、了解和使用开发环境; 2、熟悉MFC上机操作步骤; 3、熟悉基本图形函数的使用。 二、实验环境 1、操作系统Windows7旗舰版 2、Microsoft Visual C++6.0 3、PC 三、实验人数 5人 四、实验内容 在屏幕上绘制一条直线。 五、实验步骤 (1)进入Microsoft Visual C++6.0集成开发环境后,选择“文件-新建”菜单,弹出“新建”对话框。单击“工程”标签,打开其选项卡,在其左边的列表框中选择MFC AppWizard(EXE)工程类型,在

“工程名称”文本框输入工程名,在“位置”中选择工程路径。如果是第一个工程文件,则必须创建一个新的工作区,选择“创建新的工作空间”,在“平台”编辑框中选择“Win32”。 (2)单击“确定”按钮,现实“MFC应用程序向导-步骤1”对话框,选择“单文档”选项。 (3)单击“完成”按钮,系统弹出“新建工程信息”对话框。(4)单击“确定”按钮,就完成了应用程序的自动生成,在指定的目录下生成了应用程序框架所必需的全部文件,并且可以以直接运行。 (5)选择“组建-执行”。因为是第一次执行,没有生成可执行文件.EXE,提示是否生成,选择“是”,则系统进行编译及连接,生成可执行文件,并运行。、 (6)在窗口左边工作区“FileView”标签中,选择graphicView.cpp 文件,在voidCGraphicView::OnDraw(CDC*pDC)函数中添加如下代码:pDC->SetPixel(100,100,RGB(0,0,0)); pDC->MoveTo(0,0); pDC->LineTo(1000,415); (7)运行程序,得到实验结果。 六、实验效果(含程序运行主要截图)

直线段的裁剪

实验:直线段的裁剪 姓名:龙泽学号: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

计算机图形学实验一_画直线

大学实验报告 学院:计算机科学与技术专业:计算机科学与技术班级:计科131

如果 d<0,则M在理想直线下方,选右上方P1点; 如果 d=0,则M在理想直线上,选P1/ P2点。 由于d是xi和yi的线性函数,可采用增量计算提高运算效率。 1.如由pi点确定在是正右方P2点(d>0).,则新的中点M仅在x方向加1,新的d值为: d new=F(xi+2,yi+0.5)=a(xi+2)+b(yi+0.5)+c 而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c d new=d old+a= d old-dy 2.如由pi点确定是右上方P1点(d<0),则新的中点M在x和y方向都增加1,新的d值为 d new=F(xi+2,yi+1.5)=a(xi+2)+b(yi+1.5)+c 而 d old=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c d new=d old+a+b= d old-dy+dx 在每一步中,根据前一次第二迭中计算出的d值的符号,在正右方和右上方的两个点中进行选择。d的初始值: d0=F(x0+1,y0+0.5)=F(x0,y0)+a+b/2=a+b/2=-dy+dx/2 F(x0,y0)=0,(x0,y0)在直线上。 为了消除d的分数,重新定义 F(x,y)=2(ax+by+c) 则每一步需要计算的d new 是简单的整数加法 dy=y1-y0,dx=x1-x0 d0=-2dy+dx d new=d old-2*dy,当 d old>=0 d new=d old-2(dy-dx),当d old<0 Bresenham画线算法 算法原理: 与DDA算法 相似,Bresenham 画线算法也要在 每列象素中找到 与理想直线最逼 近的象素点。 根据直线的 斜率来确定变量 在x或y方向递 增一个单位。另 一个方向y或x

计算机图形学裁剪

《计算机图形学》实验报告 学院:理学院专业:信息与计算科学班级:姓名学号指导教师实验时间 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

计算机图形学实验—中点算法画直线

计算机图形学实验报告 班级:软件1102 姓名:夏明轩 学号:201109020221

中点算法的线段光栅化 一、设计思想和算法流程 1.假定直线斜率0 P 2离直线更近更近->取P 2 。 M 在Q 的上方-> P 1离直线更近更近->取P 1 M 与Q 重合, P 1、P 2任取一点。 问题:如何判断M 与Q 点的关系? 由常识知:若y=kx+b; F(x,y)=y-kx-b;则有 ()()()?????<>=点在直线下方 0,点在直线上方0,点在直线上面0,y x F y x F y x F 假设直线方程为:ax +by +c=0 (y=(-a/b)x-c/b) 通过两点不能唯一确定a,b,c, 取 a=y 0-y 1, b=x 1-x 0, c=x 0y 1-x 1y 0 F(x,y)=ax +by +c=b(y-(-a/b)x-c/b); ()()()?????<>=点在直线下方0,点在直线上方0 ,点在直线上面0,y x F y x F y x F 则有 ∴欲判断M 点是在Q 点上方还是在Q 点下方,只需把M 代入F (x ,y ),并检查它的符号。构造判别式:d=F(M)=F(x p +1,y p +0.5)=a(x p +1)+b(y p +0.5)+c 当d<0,M 在直线(Q 点)下方,取右上方P 2; 当d>0,M 在直线(Q 点)上方,取右方P 1; 当d=0,选P 1或P 2均可,约定取P 1; 能否采用增量算法呢?若d ≥0 ---->M 在直线上方->取P1;此时再下一个象素的判别式为 d 1=F(x p +2, y p +0.5) =a(x p +2)+b(y p +0.5)+c = a(x p +1)+b(y p +0.5)+c +a =d+a ; 增量为a 若d<0 ------>M 在直线下方->取P2;此时再下一个象素的判别式为 d 2= F(x p +2, y p +1.5) =a(x p +2)+b(y p +1.5)+c = a(x p +1)+b(y p +0.5)+c +a +b =d+a+b ;

计算机图形学用VC++画直线

实验一基本图形生成算法 实验目的: 掌握中点Bresenham绘制直线的原理 设计中点Bresenham算法 编程实现中点Bresenham算法 实验描述: 使用中点Bresenham算法绘制斜率为0≤k≤1的直线。 算法设计: 直线中点Bresenham算法 1. 输入直线的起点坐标P0(x0,y0)和终点坐标P1(x1,y1)。 2. 定义直线当前点坐标x,y、定义中点偏差判别式d、定义直线斜率k、定义像素点颜色 rgb。 3. x=x0,y=y0,计算d=0.5-k,k=(y1-y0)/(x1-x0),rgb=RGB(0,0,255)。 4. 绘制点(x,y),判断d的符号。若d<0,则(x,y)更新为(x+1,y+1),d 更新为 d+1-k;否则(x,y)更新为(x+1,y),d更新为d-k。 5. 如果当前点x 小于x1,重复步骤4,否则结束。 源程序: 1)// TestView.h #include "InputDlg.h"//对话框头文件 class CTestView : public CView { ….. } 2)//TestView.cpp #define ROUND(a) int(a+0.5) //四舍五入 ….. void CTestView::OnMbline()//菜单响应函数 { InputDlg dlg; if(dlg.DoModal()==IDOK) { AfxGetMainWnd()->SetWindowText(":直线中点Bresenham算法"); RedrawWindow(); Mbline(dlg.m_x0, dlg.m_y0, dlg.m_x1, dlg.m_y1); } } void CTestView::Mbline(double x0, double y0,double x1,double y1) //直线中点Bresenham函数{ CClientDC dc(this); COLORREF rgb=RGB(0,0,255); //定义直线颜色为蓝色 double x,y,d,k; x=x0;y=y0;k=(y1-y0)/(x1-x0);d=0.5-k;

线段裁剪算法

计算机图形学 实验报告 实验(四) 实验题目:线段裁剪算法 指导老师:吴颖斌 专业:数字媒体技术 班级: 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) {

计算机图形学 直线的生成算法的实现

实验二 直线的生成算法的实现 班级 08信计2班 学号 59 姓名 分数 一、实验目的和要求 1.理解直线生成的基本原理。 2.掌握几种常用的直线生成算法。 3.利用Visual C++实现直线生成的DDA 算法。 二、实验内容 1.了解直线的生成原理,尤其是Bresenham 画线法原理。 2.掌握几种基本的直线生成算法:DDA 画线法、Bresenham 画线法、中点画线法。 3.利用Visual C++实现直线生成的DDA 算法,在屏幕上任意生成一条直线。 三、实验步骤 1.直线的生成原理: (1)DDA 画线法也称数值微分法,是一种增量算法。是一种基于直线的微分方程来生成直线的方法。 (2)中点画线法原理 以下均假定所画直线的斜率[0,1]k ∈,如果在x 方向上的增量为1,则y 方向上的增量只能在01 之间。中点画线法的基本原理是:假设在x 坐标为p x 的各像素点中,与直线最近者已经确定为(,)p p P x y ,用小实心圆表示。那么,下一个与直线最近的像素只能是正右方的1(1,)p p P x y +,或右上方的2(1,1)p p P x y ++,用小空心圆表示。以M 为1P 和2P 的中点,则M 的坐标为(1,0.5)p p x y ++。又假设Q 是理想直线与垂直线1p x x =+的交点。显然,若M 在Q 的下方,则2P 离直线近,应取2P 为下一像素点;若M 在Q 的上方,则1P 离直线近,应取1P 为下一像素点。 (3)B resenham 画线法原理 直线的中点Bresenham 算法的原理:每次在主位移方向上走一步,另一个方向上走不走步取决于中点偏差判别式的值。 给定理想直线的起点坐标为P0(x0,y0),终点坐标为P1(x1,y1),则直线的隐函数方程为: 0b kx y y)F(x,=--= (3-1) 构造中点偏差判别式d 。 b x k y y x F y x F d i i i i M M -+-+=++==)1(5.0)5.0,1(),(

直线裁剪算法研究(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任意多边形裁剪算法思想:

计算机图形学简答题.和名词解释

1、简述图像处理、模式识别与计算机图形学的关系。 图像处理、模式识别与计算机图形学是计算机应用领域发展的三个分支学科,它们之间有一定的关系和区别,它们的共同之处就是计算机所处理的信息都是与图有关的信息。它们本质上是不同的:图像处理是利用计算机对原存在物体的映象进行分析处理,然后再现图像;模式识别是指计算机对图形信息进行识别和分析描述,是从图形到描述的表达过程;计算机图形学是研究根据给定的描述用计算机生成相应的图形、图像。 计算机图形系统主要具有哪些功能? 答案:1. 计算功能 2. 存储功能 3. 输入功能 4. 输出功能 5. 交互功能多边形的顶点和点阵表示各有什么优缺点? 答案:顶点表示是用多边形的顶点序列来描述多边形。该表示几何意义强、占内存少、几何变换方便;但它不能直观地说明哪些像素在多边形内,故不能直接用于面着色。 点阵表示用位于多边形内的像素的集合来描述多边形。该方法虽然没有多边形的几何信息,但便于用帧缓存表示图形,可直接用于面着色。 为什么需要隐藏面消隐算法? 答: 因为我们在用计算机生成三维物体的真实感图形,必须要做的是确定物体的可见部分,只有 确定了物体的可见部分,我们才能在计算机中真实地再现三维物体。因此,我们就需要一个隐藏面消隐算法来去掉物体的不可见部分,从而避免错误地将不可见部分显示出来,这样就可以在计算机中生成一个三维物体的真实感图形了。 z缓冲器算法是怎么判断哪个面应消隐的? 答: z缓冲器算法设置了一个二维数组,类似于帧缓冲器。但是z缓冲器存放的是每个象素点的深 度值,而不是帧缓冲器中的颜色值。z缓冲器的初始值为某个大的数值,通常是后裁剪平面的距离。 在判断像素),(yx上的哪个平面更靠近观察者时,就可以简单地比较z缓冲器中的深度值和当前平面的深度值。如果当前平面的值比z缓冲器中的值小(即距视点更近),则用新值替换原z缓冲器中的值,像素的颜色值也变成新平面的颜色值。 颜色的基本特征是什么? 答:颜色的基本特征是:波长、亮度和饱和度。 波长是依赖于物质的,可见光的波长范围大约是350nm~780nm。

计算机图形学-设计算法绘制直线与圆

信息与计算科学专业基础课 Computer Report Of course 计算机图形学课程实验 报告 实验题目设计算法绘制直线与圆 班级 姓名 学号 指导教师 日期

实验说明 试验目的: 掌握直线和圆的基本生成算法思想,并上机编程实现相应的算法。 试验地点: 教九楼401 数学系机房 实验要求(Direction): 1. 每个学生单独完成;2.开发语言为TurboC 或C++,也可使用其它语言;3.请在自己的实验报告上写明姓名、学号、班级;4.每次交的实验报告内容包括:题目、试验目的和意义、程序制作步骤、主程序、运行结果图以及参考文件;5. 自己保留一份可执行程序,考试前统一检查和上交。 实验内容 实验题一 实验题目 1).用DDA 法在屏幕上画一条具有三个像素宽的直线段L1。要求:(1)直线段L1的两个端点坐标和画线颜色都要求可以随机输入;(2)要求输出直线段L1上的各点坐标;(3)画出直线的同时要求标明两端点坐标。 2).将课堂所讲的斜率01、-1

梁友栋-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.实验描述: 设置裁剪窗口坐标为: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)求解窗口与直线的交点。

计算机图形学--绘制直线

计算机图形学 实验报告 专业:信息与计算科学 班级: 1002班 学号: 10080602** 姓名: *****

1.实验目的 熟悉CDC类的MoveTo()和LineTo()直线段绘制函数。 熟悉斜率-1

m_p1=CPoint(x,y); } void CLine::LineTo(CDC* pDC,double x,double y,double k) { m_p2=CPoint(x,y); CPoint p,t; pDC->SetMapMode(MM_LOMETRIC); pDC->SetViewportOrg(200,200); double d; if(k>=-1.0&&k<0.0) { if(m_p1.x >m_p2.x ) { t=m_p1; m_p1=m_p2; m_p2=t; } d=-0.5-k; for(p=m_p1;p.x SetPixel (p.x ,p.y ,RGB(0,0,255)); if(d>0) { p.y--; d-=1+k; } else { d-=k; } } } } void CTEXTView::OnDraw(CDC* pDC) { CTEXTDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CLine cline; cline.MoveTo (-200,300); cline.LineTo (pDC,200,-300,-0.3); }

直线段剪裁实验报告

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

一、实验目的 熟练掌握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。 裁剪步骤: 对所有直线的端点都建立了区域码之后,就可按区域码判断直线在窗口之内或窗口之外。这可分为如下几种情况: ①若一直线的两个端点的区域码均为0000则此直线在窗口边界之内,应 子保留。 ②若一直线的两个端点的区域码的同一位同时为1,则此直线全部在窗 口边界之外,应子裁剪。例如,若一直线的一个端点的区域码为1001,另一个端点的区域码为0101,则此两端点的区域码的第一位均为1,说明此两端点均在窗口边界之左,因此,直线在窗口边界之外,应予裁剪。可用将直线两个端点的区域码进行与操作的方法,判断直线是否在窗口之外,若与操作的结果为0000则两端点的区域码任何位均不同时为1此直线不一定被裁剪。 ③以上两种情况之外的直线,有可能穿过窗口,也有可能不穿过窗口, 下图中所示的两条直线都不符合情况②的要求,但一条直线(P1P2)穿过窗口,另一直线(P3P4)不穿过窗口。对这类直线可以进行如下处理:取窗口外的一个端点与窗口边界比较以确定可排除直线的哪一部分,然后,把直线剩下的部分与其他边界比较,这样一直到直线全部被排除或确定直线的哪一部分在窗口之内为止。可按“左、右、下、上”的次序建立检查直线端点与窗口边界关系的算法。 图③ 三、实验结果 画线效果一:

(计算机图形学)关于任意直线的对称变换

实验3:关于任意直线的对称变换 实验类型:验证、设计 所需时间:3学时 主要实验内容及要求: 对于任意直线的二维图形对称变化的实验,要求输入的直线是任意直线,直线的端点只能由键盘输入或者鼠标拾取,要做对称变换的图形也是一个任意图形(至少应是一个任意多边形)。 对称变换,先分析如何使用一系列简单变换来构造题目要求的复合变换。本体要实现的变换可以用如下一组变换组合来实现: ①将直线任一点移至与坐标原点重合 ②将平移后的直线绕原点旋转至与某一坐标轴重合 ③将题目要求的对称变换转为实现已知图形关于上述坐标轴的对称变换 ④按逆序求上述①、②变换的逆变换 ⑤将上述矩阵依次相乘得到最终的复合变换矩阵 则某一多边形关于任意直线的对称变换就转变为将该多边形的各顶点与上述求得的复合变换进行矩阵乘法,求得变换后的新多边形的各个顶点坐标。 根据上述流程,编程实现,并测试程序功能。 源代码: #include #include using namespace std; void Initial(void) { glClearColor(1.0f,1.0f,1.0f,1.0f); glMatrixMode(GL_PROJECTION); gluOrtho2D(0.0,200.0,0.0,150.0); } class CPoint { public: int x; int y; CPoint(){} CPoint(int x1,int y1) { x=x1; y=y1; } static CPoint ZeroMoveToXY(CPoint p, CPoint XY);//原始坐标向屏幕坐标XY的平移

计算机图形学 VC下画一条直线

用ddc作图: 步骤:文件/新建/工程(mfc appwizard(exe))/工程名称ddaline() (与函数名一样)/确定/单文档/确定/在dline class添加成员函数,双击打开dline class/右击CDlineView然后选第二个选项,添加函数,函数名:void函数类型:d dline(CDC *pDC, int x0, int y0, int x1, int y1, int color) /在CDlineView下的Ondraw下调用该函数,调用命令:ddline(pDC,100,100,400,100,RGB(255,0,0));。 void CDlineView::ddline(CDC *pDC, int x0, int y0, int x1, int y1, int color) { int length,i; int x,y,dx,dy; length=abs(x1-x0); if(abs(y1-y0)>length) length=abs(y1-y0); dx=(x1-x0)/length; dy=(y1-y0)/length; x=int(x0+0.5); y=int(y0+0.5); for(i=1;i<=length;i++) { pDC->SetPixel((int)x,(int)y,color); x=x+dx; y=y+dy; } } 编写OnDraw()函数: void CMy1View::OnDraw(CDC* pDC) { CMy1Doc* pDoc = GetDocument(); ASSERT_V ALID(pDoc); // TODO: add draw code for native data here ddline(pDC,100,100,400,100,RGB(255,0,0));

相关主题
文本预览
相关文档 最新文档