直线段的裁剪
计算机图形学Cohen-Sutherland直线裁剪算法源码c++
实验现象:
核心代码:
Cohen-Sutherland直线段裁减算法:
void CLineClippingView::OnSutherlandID() ////////版权所有赵才
{
// TODO: Add your command handler code here
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;
ptset[i].y=YT;
continue;
}
if(code1 & BOTTOM)
{
//
ptset[i].x=int(1.0/k*(YB-ptset[i].y)+ptset[i].x+0.5);
ptset[i].y=YB;
continue;
}
}
}
}
}
int encode(int x,int y) //确定端点编码
if(code1 & LEFT)
{
//
ptset[i].y=int(k*(XL-ptset[i].x)+ptset[i].y+0.5);
ptset[i].x=XL;
计算机科学技术:计算机图形学题库三
计算机科学技术:计算机图形学题库三1、名词解释扫描转换答案:在矢量图形中,多边形用顶点序列来表示,为了在光栅显示器或打印机等设备上显示多边形,必须把它转换为点阵表示。
这种转换称为扫描转换。
2、单选下面对光栅扫描图形显示器描述正确的是()A.荧光粉涂层均匀离散分布;B.是一种点画设备;C.电子束从顶到底扫描;D.通过控制电子束的强弱实现色彩的强弱;答案:A3、填空题计算机图形系统由()系统和软件系统组成。
答案:硬件4、填空题在处理图形时常常涉及的坐标系有模型坐标系(),世界坐标系,观察坐标系,设备坐标系。
答案:局部坐标系5、单选计算机图形学与计算机图象学的关系是()。
A.计算机图形学是基础,计算机图象学是其发展B.不同的学科,研究对象和数学基础都不同,但它们之间也有可转换部分C.同一学科在不同场合的不同称呼而已D.完全不同的学科,两者毫不相干答案:B6、问答题简述中点分割法进行裁剪的过程?答案:中点分割剪取法,主要是对线段不断地进行对分,并排除在区域外的部分,找出线段落在窗口内的部分。
其方法主要是通过求出离线段的一个端点最近并且在区域内的点的方法,来确定线段落在窗口内的端点。
7、问答题局部光照模型和全局光照模型的不同之处是什么?答案:局部光照模型主要是考虑光源发出的光对物体的直接影响。
另外,全局光照模型除了处理光源发出的光之外,还考虑其他辅助光的影响,如光线穿过透明或半透明物体,以及光线从一个物体表面反射到另一个表面等。
8、判断题彩色阴极射线管主要是由红绿蓝三个彩色电子束的亮度不同,进而组合形成各种色彩的。
答案:错9、问答题什么叫做走样?什么叫做反走样?反走样技术包括那些?答案:走样指的是用离散量表示连续量引起的失真。
为了提高图形的显示质量。
需要减少或消除因走样带来的阶梯形或闪烁效果,用于减少或消除这种效果的方法称为反走样。
其方法是①前滤波,以较高的分辨率显示对象;②后滤波,即加权区域取样,在高于显示分辨率的较高分辨率下用点取样方法计算,然后对几个像素的属性进行平均得到较低分辨率下的像素属性。
【学习课件】第5章图形变换与裁剪
裁剪过程是递归的。
2021/7/9
9
直线段裁剪(8/15)
Cohen-Sutherland 算法
特点:
对显然不可见线段的快速判别
编码方法:
由窗口四条边所在直线把二维平面分成9个区域,每个区域赋予一个四 位编码, CtCbCrCl,上下右左;
1 当yymax 1 当yymin
Ct 0 else
Cb 0 else
2021/7/9
4
直线段裁剪(3/15)
点裁剪
点(x, y)在窗口内的充分必要条件是: x m in x x m a x
ym inyym ax
问题:对于任何多边形窗口,如何判别?
2021/7/9
5
直线段裁剪(4/15)
假定条件
矩形裁剪窗口:[xmin,xmax]X[ymin,ymax] 待裁剪线段: P 0(x0,y0)P 1(x1,y1)
判断图形元素是否在裁剪窗口之内并找出其位于内部的部分
裁剪处理的基础
图元关于窗口内外关系的判别 图元与窗口的求交
裁剪、覆盖
2021/7/9
3
直线段裁剪(2/15)
裁剪窗口
矩形、圆形、一般多边形
被裁剪对象
线段、多边形、曲线、字符
裁剪的策略
先裁剪,后变换 先变换,后裁剪
裁剪算法的核心问题
效率
任何平面线段相对于凸多边形窗口进行裁剪后?
2021/7/9
6
直线段裁剪(5/15)
待裁剪线段和窗口的关系
完全落在窗口内 完全落在窗口外 部分在内,部分在外
2021/7/9
7
直线段裁剪(6/15)
为提高效率,算法设计时应考虑: 1. 快速判断情形(1)(2); 2. 设法减少情形(3)求交次数和每次求交时所需的计算量
复习题计算机图形学提纲 FIN
1、编码裁剪算法的原理、方法。
中点分割裁剪算法的特点 P168编码裁剪算法(Cohen-Sutherland算法):直线段裁剪算法原理:对直线段p1(x1,y1)p2(x2,y2)分三种情况处理:(1) p1 p2都在裁剪窗口内,则该直线可见,简取之(2 )p1 p2均在窗口外,且在同一外侧,则完全不可见,简弃之(3)若均不满足,则该直线段可能与窗口相交,此时需要对直线段按交点进行分段,分段后重复上述处理。
算法步骤:1.输入直线段的两端点坐标及窗口的四条边界坐标。
2.对p1 p2进行编码,p1编码为code1,p2为code2.3.若code1|code2=0简取之,转6;若code1&code2≠0,简弃之,转7;均不成立时,转4.4.确保p1在窗口外部。
若在窗口内,将p1 p2交换坐标值与编码。
5.根据p1编码从低位开始找编码值为1的地方,从而确定p1在窗口的哪一侧,然后求出直线段与相应窗口边界交点S,并用S的坐标值替换P1的坐标值,转26.用直线扫描算法画出当前直线段p1p27.结束Code编码:1001 1000 10100001 0000 00100101 0100 0110中点分割算法(二分逼近确定直线段与窗口边界的交点)特点:用硬件执行加法和除2运算非常快。
2、三维图形基本变换矩阵P184、复合变换P191、绕任意轴旋转矩阵的复合方法P192,齐次坐标、规范化齐次坐标的概念与计算P151。
基本变换:旋转,错切,缩放,对称;投影变换;平移;整体比例变换平移:[x y z 1]->[x+tx y+ty z+tz 1]整体比例:[x y z 1]->[x/s y/s z/s 1]旋转:Z轴 [x y z 1]->[xcosa-ysina xsina+ycosa z 1]X轴 [x y z 1]->[x ycosa-zsina ysina+zcosa 1]Y轴 [x y z 1]->[ zsina+ xcosa y zcosa-xsina 1]对称:xoy面:[x y z 1]->[x y –z 1]Xoz面:[x y z 1]->[x –y z 1]Yoz面:[x y z 1]->[-x y z 1]错切:沿x方向 [x y z 1]->[x+dy+dz y z 1]沿y轴方向 [x y z 1]->[x y+dx+dz z 1]沿z轴方向 [x y z 1]->[ x y z+dx+dy 1]复合变换:1.相对任意参考点的三维变换平移到原点-〉变换-〉回到原位置2.绕任意轴的旋转变换使任意轴的起点与原点重合(平移);使方向轴与某一坐标轴重合(多次旋转);针对该坐标轴完成变换;用逆旋转变换使方向轴回到原始方向;用逆平移变换使方向轴回到原始位置齐次坐标:用n+1维向量表示n维向量齐次坐标规范化:使h=13、中点画圆算法的原理与方法P111基本原理:每次沿x方向上走一步,在y方向上减1或减0.算法:1输入圆的半径R2计算初始值d=1-R,x=0,y=R3绘制点(x,y)及其八分圆中的另外7个对称点(circlepoint(x,y,color))4判断d的符号。
[计算机图形学]复习Cohen-Sutherland直线段裁剪算法
[计算机图形学]复习Cohen-Sutherland直线段裁剪算法
关于Cohen-Sutherland 直线段裁剪算法思想概述
直线段裁剪是⼆维图形裁剪的基础,本质是判断直线段是否与窗⼝边界相交,如相交则进⼀步确定直线段上位于窗⼝内的部分。
算法思想:直线的端点赋予⼀组4位⼆进制码,称为RC(区域编码),裁剪窗⼝的四条边所在的直线可以把平⾯分为9个区域,对各个区域的编码也是四位,C3C2C1C0,分别代表上下右左四个窗⼝边界。
裁剪窗⼝所在的区域为0000,对于直线段上的端点进⾏编码,等于该端点所在的区域的编码。
编码后就容易判断两个端点的情况:
⽐如两个端点求与不等于0,即RC0&RC1≠0;说明该线段在裁剪窗⼝之外,应简弃;
两个端点RC编码按位或为0,即RC0|RC1=0。
说明直线段两个端点都在窗⼝内,应简取。
还有第三种情况:不满⾜前两种情况的,说明直线段与边界或其延长线有交点,要进⾏求交判断:
①此时直线段与边界相交,P0P1和两个边界相交,按左右下上的顺序计算交点,设交点为P,注意:总是要让直线段的⼀个顶点处于窗⼝之外,例如P0点。
这样P0点到交点P的直线段必然不可见,故可以将交点外的线段简弃。
②直线段与边界的延长线相交,直线段在窗⼝外,也不在窗⼝同⼀侧。
依旧按照左右下上顺序计算,将延长线与线段交点定为P,有PP0,位于窗⼝某侧,被简弃。
如果求裁剪后窗⼝内直线段的端点坐标,(那⼀般是求P1,以实际题⽬为准,看剪了哪部分),两点求直线⽅程,然后带⼊相交边界的x或y值可得。
直线裁剪算法
直线裁剪算法直线裁剪算法⼀、1、裁剪:确定图形哪些部分落在显⽰区之内,哪些落在显⽰区外。
这个选择的过程就称为裁剪。
2、直线段的裁剪:Cohen-Suther land、中点分割法和Liang-Barsky裁剪算法⼆、Cohen-Suther land算法⼜称编码裁剪算法,算法的基本思想是对每条直线分三种情况处理:1>若端点完全在裁剪窗⼝内----“简取”之2>若端点完全在裁剪窗⼝外,且满⾜下列四个条件之⼀----“简弃”之3>既不满⾜简取,也不满⾜简弃:对直线段按交点进⾏分段,分段后判断直线是“简取”还是“简弃”每条线段的端点都赋以四位⼆进制码D3D2D1D0,编码规则如下:(左右下上)例如:裁剪⼀条线段时,先求出端点P1,P2的编码code,然后进⾏⼆进制“或”和“与”运算(1)若code1|code2=0,对直线段简取(2)若code1&code2不等于0,对直线段简弃(3)若上述两条件都不成⽴,则需要求出直线段与窗⼝边界的交点,并在交点处把直线段⼀分为⼆3、存在问题:⼀条完全在窗⼝外的直线,进⾏与运算=0,还需求交点,然后所得结果还是全部舍弃三、三、中点分割算法1、核⼼思想:通过⼆分逼近来确定直线段与窗⼝的交点2、注意:1>若中点不在窗⼝内,则把中点和离窗⼝边界最远点构成的线段丢掉,线段上的另⼀点和该中点再构成线段求其中点2>若中点在窗⼝内,则以中点和最远点构成线段,求其中点,直到中点与窗⼝边界的坐标值在规定的误差范围内3、问题:中点分割算法会不会⽆限循环下去?不会。
因为屏幕像素是有限的,⼀般计算次数不会太多,⽽且允许在误差范围内四、Liang-Barsky裁剪算法1、主要思想:⽤参数⽅程表⽰⼀条直线段(0<=U<=1)X=X1+U*(X2-X1)=X1+U*△XY=Y1+U*(Y2-Y1)=Y1+U*△Y2、把直线看成是⼀条有⽅向的线段,把窗⼝的四条边及其延长线分成两类:⼊边和出边⼊边:左边界和下边界出边:右边界和上边界如何求出起点和终点的坐标?(即起点和终点的参数值u)判断线段某⼀部分是否在窗⼝内,可以简化为判断直线上⼀个点是否在窗⼝内的问题,窗⼝内的P点满⾜什么条件?3、举例:3、Liang-Barsky算法⼩结1>直线⽅程参数化2>直线段是有⽅向的3>把窗⼝的四条边分成⼊边和出边五、Cohen-Suther land算法和Liang-Barsky算法⽐较1、Cohen-Suther land算法的核⼼思想是编码,窗⼝和延长线把空间分成了9个区域2、线段要么⼤部分在窗⼝外,要么⼤部分在窗⼝内,使⽤Cohen-Suther land效果好3、⼀般情况下(线段贯穿窗⼝),优先使⽤Liang-Barsky算法4、两者均只能应⽤于矩形窗⼝。
《计算机图形学》习题
一、名词解释计算机图形学、图形消隐、裁剪、走样、反走样、参数方程、曲线拟合、曲线插值、曲线的参数化、区域填充、扫描转换二、判断正误(正确写T,错误写F)1.存储颜色和亮度信息的相应存储器称为帧缓冲存储器,所存储的信息被称为位图。
2.光栅扫描显示器的屏幕分为m行扫描线,每行n个小点,整个屏幕分为m╳n个中点,其中每个小点称为一个像素。
3.点阵字符用一个位图来表示,位图中的0对应点亮的像素,用前景色绘制;位图中的1对应未点亮的像素,用背景色绘制。
4.矢量字符表示法用(曲)线段记录字形的边缘轮廓线。
5.将矢量字符旋转或放大时,显示的结果通常会变得粗糙难看,同样的变换不会改变点阵字符的显示效果。
6.在光栅图形中,区域是由相连的像素组成的集合,这些像素具有相同的属性值或者它们位于某边界线的内部。
7.多边形的扫描变换算法不需要预先定义区域内部或边界的像素值。
8.用DDA算法生成圆周或椭圆不需要用到三角运算,所以运算效率高。
9.找出并消除物体中的不可见部分,称为消隐。
10.经过消隐得到的图形称为消隐图。
11.深度缓存算法并不需要开辟一个与图像大小相等的深度缓存数组,深度缓存算法能并行实现,深度缓存算法中没有对多边形进行排序。
12.在种子填充算法中所提到的八向连通区域算法同时可填充四向连通区。
13.Bezier曲线不一定通过其特征多边形的各个顶点,Bezier曲线两端点处的切线方向必须与起特征折线集(多边形)的相应两端线段走向一致,Bezier曲线可用其特征多边形来定义。
14.由三个顶点可以决定一段二次B样条曲线,若三顶点共线时则所得到的曲线褪化为一条直线段。
15.插值得到的函数严格经过所给定的数据点。
16.参数曲线的表示有形式和几何形式两种。
17.L-B参数直线裁剪算法中的裁剪条件为uP k<=Q k,当直线平行于裁剪边界的条件Q k=0。
18.L-B参数直线裁剪算法中的裁剪条件为uP k<=Q k,当P k<0时表示线段从裁剪边界外部指向内部。
潘正风《数字测图原理与方法》笔记和课后习题(含真题)详解(计算机地图绘图基础)
第十章 计算机地图绘图基础10.1 复习笔记【知识框架】【重点难点归纳】一、基本图形显示1.坐标系(见表10-1-1)表10-1-1 坐标系坐标系 基本图形显示 点的裁剪 直线段的裁剪 二维图形裁剪 多边形的裁剪 圆弧和曲线的裁剪 独立符号的自动绘制 基本线型绘制 地形图地物符号的自动绘制 线状符号的自动绘制 平行线绘制 线状符号的绘制 多边形轮廓线内绘制晕线 面状符号的自动绘制 面状符号的绘制 网格法由距离加权平均求网格点高程 三角网法的三角网连接 在网格边上等高线点的平面位置 等高线的自动绘制 等高线点的寻找 在三角形边上等高线的平面位置 在网格上等高线点的追踪 在三角形网上等高线点的追踪 等高线的光滑 计算机地图绘图基础由下向上图10-1-1 计算机屏幕坐标系2.二维图形裁剪(1)点的裁剪在笛卡儿坐标系中,窗口左下角的坐标为,窗口右上角的坐标为若某一点的坐标为x、y,同时满足和,则该点在窗口内,否则在窗口外被裁掉。
(2)直线段的裁剪直线段的裁剪算法有多种,这里介绍编码裁剪算法。
这种方法由窗口的边界分成的9个区按一定的规则用四位二进制编码来表示。
这样,当线段的端点位于某一区时,该点的位置可以用其所在区域的四位二进制码来唯一确定,通过对线段两端点的编码进行逻辑运算,就可确定线段相对于窗口的关系。
(3)多边形的裁剪把整个多边形先相对于窗口的第一条边界裁剪,然后再把形成的新多边形相对于窗口的第二条边界裁剪,如此进行到窗口的最后一条边界,从而把多边形相对于窗口的全部边界进行了裁剪。
(4)圆弧和曲线的裁剪圆弧和曲线都可以用一组短的直线段来逼近,因此,圆弧和曲线的裁剪可采取对每一条短直线段的裁剪来实现对圆弧和曲线的裁剪。
二、地形图地物符号的自动绘制1.独立符号的自动绘制(1)首先建立表示这些符号特征点信息的符号库,独立符号特征点的数据采集是将图式上的独立符号和说明符号放大20倍绘在毫米格网纸上,进行符号特征点的坐标采集,采集坐标时均已符号的定位点作为坐标原点。
直线裁剪算法研究(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直线相对干窗口边界的栽剪直线裁剪算法应首先确定哪些直线全部保留或全部裁剪,剩下的即为部分裁剪的直线。
对于部分裁剪的直线则首先要求出这些直线与窗口边界的交点,把从交点开始在边界外的部分裁剪掉。
一个复杂的画面中可能包含有几千条直线,为了提高算法效率,加快裁剪速度,应当采用计算量较小的算法求直线与窗口边界的交点。
3 cohen-sutherland直线裁剪算法Cohen-Sutherland算法的大意是:对于每条线段P1P2,分为3种情况处理。
cohen-sutherland 直线段裁剪算法
Cohen-Sutherland 直线段裁剪算法是一种计算机图形学中的算法,用于裁剪二维图形中超出指定矩形区域的线段。
算法步骤如下:
定义四个常量,分别表示矩形区域的四个边界:TOP, BOTTOM, LEFT, RIGHT。
对于每条待裁剪的线段,计算其与矩形区域的交集情况,可以使用一个 4 位的二进制数表示,其中每一位分别表示线段与矩形上、下、左、右边界的交集情况。
例如,如果线段与矩形上边界有交集,则二进制数的第 0 位为 1,否则为 0。
根据线段的端点坐标和矩形区域的边界坐标,判断线段与矩形区域的相对位置关系,可以分为以下三种情况:
a. 线段完全在矩形区域内,不需要裁剪,直接保留。
b. 线段完全在矩形区域外,不需要裁剪,直接舍弃。
c. 线段部分在矩形区域内,部分在矩形区域外,需要进行裁剪。
4. 对于需要裁剪的线段,根据其与矩形边界的交点坐标,将线段裁剪成两部分,分别计算每部分与矩形区域的交集情况,并递归进行裁剪,直到所有线段都被处理完毕。
Cohen-Sutherland 直线段裁剪算法可以快速地裁剪二维图形中超出指定矩形区域的线段,是计算机图形学中的常用算法之一。
直线段剪裁实验报告
直线段剪裁实验报告摘要:本实验旨在通过剪裁算法对直线段进行处理,并观察其效果。
我们使用了一种常见的直线段剪裁算法——Cohen-Sutherland剪裁算法,并进行了详细的实验步骤和结果分析。
实验结果表明,Cohen-Sutherland算法能够有效地剪裁直线段,实现了准确的剪裁效果。
引言:计算机图形学中,直线段剪裁是一个重要的问题,尤其在计算机辅助设计和计算机游戏开发中具有广泛的应用。
通常情况下,直线段剪裁是指对一个直线段进行裁剪,使其仅保留在给定的裁剪窗口内。
方法:本实验使用了Cohen-Sutherland剪裁算法对直线段进行处理。
该算法是由Cohen和Sutherland于1967年提出的,是一种简单且高效的直线段剪裁算法。
它基于直线段的两端点(即P1和P2)分别与裁剪窗口的四个边界进行比较的原理,并根据他们的位置关系进行适当的处理。
算法的基本思想如下:1. 对于直线段的起点和终点,分别进行位置编码;2. 根据位置编码的结果,判断直线段是否完全在裁剪窗口内,如果是,则直接保留该直线段;3. 如果直线段完全在裁剪窗口外,那么可以直接舍弃该直线段;4. 如果直线段与裁剪窗口相交,那么可以根据交点计算出新的直线段。
实验步骤:1. 定义一个裁剪窗口(如矩形),并确定其边界;2. 输入一个需要进行剪裁的直线段,确定其起点P1和终点P2;3. 分别对P1和P2进行位置编码,得到4位二进制编码;4. 根据位置编码对两个顶点进行判断,确定直线段与裁剪窗口的位置关系;5. 根据位置关系来进行适当的处理:- 如果直线段完全在裁剪窗口内,则保留该直线段;- 如果直线段完全在裁剪窗口外,则舍弃该直线段;- 如果直线段与裁剪窗口相交,则根据交点计算出新的直线段;6. 输出剪裁后的直线段。
结果分析:经过多组实验数据的对比,我们发现Cohen-Sutherland算法能够很好地剪裁直线段,实现了准确的剪裁效果。
由于算法的采取了二进制编码的方式,可以高效地判断直线段与裁剪窗口的位置关系,并进行适当的处理。
06点、直线裁剪
B F
► 对分辩率为2N*2N的显示器,上述二分过程至 对分辩率为2
多进行N 多进行N次。 ► 主要过程只用到加法和除法运算,适合硬件 实现,它可以用左右移位来代替乘除法,这 实现,它可以用左右移位来代替乘除法,这 样就大大加快了速度。 样就大大加快了速度。
梁友栋-Barsky算法:交点计算 梁友栋-Barsky算法:交点计算
►
►
在实现本算法时,不必把线段与每条窗口边界依次求交,只 要按顺序检测到端点的编码不为0 要按顺序检测到端点的编码不为0,才把线段与对应的窗口 边界求交。 特点:对显然不可见线段的快速判别
1001
1000
1010 P1
0001
0000
0010 P3 P4
Байду номын сангаас
0101
0100
0110 P2
中点分割裁剪算法
P1P2分为三种情况处理。 分为三种情况处理。
(1)若两端点P1P2完全在窗口 若两端点P1P2完全在窗口 则完全可见该线段P1P2。 内,则完全可见该线段P1P2。否 则进入下一步; 则进入下一步; 明显在窗口外, 若线段P (2)若线段P1P2明显在窗口外, 即显然不可见,则丢弃该线段, 即显然不可见,则丢弃该线段,否 则进入下一步; 则进入下一步; 若线段既不满足( (3)若线段既不满足(1)的条 也不满足( 的条件, 件,也不满足(2)的条件,则在 交点处把线段分为两段。 交点处把线段分为两段。其中一段 完全在窗口外,可弃之。 完全在窗口外,可弃之。然后对另 一段重复上述处理。 一段重复上述处理。
P0 A Pm B P1
P0
A Pm B P1
► 从P0出发找距离P0最近可见点采用中点分割方法 出发找距离P
论述cohen-suthorland直线段裁剪算法的编码原理
论述cohen-suthorland直线段裁剪算法的编码原理1. 引言1.1 概述Cohen-Sutherland直线段裁剪算法是一种常用的计算机图形学算法,用于确定直线段是否与给定裁剪窗口相交,从而实现对直线段的裁减。
该算法以编码方式表示直线段位置关系,并根据编码结果进行裁剪判断,具有简单高效的特点,在计算机图形学领域得到广泛应用。
1.2 文章结构本文将详细论述Cohen-Sutherland直线段裁剪算法的编码原理及实现过程。
首先介绍算法的背景和相关概念,解释其在计算机图形学中的重要性。
接下来,详细说明Cohen-Sutherland算法的步骤以及编码方法,并阐述其实现过程中所需进行的初始化设置、裁剪区域判定和直线段裁剪计算等操作。
然后,通过效果评估对该算法进行评价,并分析其优点和缺点。
最后,总结论述并提出在进一步研究方向上可能存在的建议。
1.3 目的本文旨在深入探讨Cohen-Sutherland直线段裁剪算法的编码原理及其应用。
通过对该算法进行详细的解释和分析,读者将能够全面了解算法的工作原理,并具备实现及优化该算法的能力。
此外,我们也希望通过对其效果的评估和优缺点的分析,为使用该算法的工程师和学术研究人员提供参考,以便更好地选择合适的裁剪算法并应用于具体问题中。
2. Cohen-Sutherland直线段裁剪算法的编码原理2.1 算法简介Cohen-Sutherland直线段裁剪算法是一种常用的二维直线段裁剪方法,它通过将裁剪区域划分为9个小区域来判断并去除不需要显示的部分,从而实现快速而准确的线段裁剪。
2.2 算法步骤Cohen-Sutherland直线段裁剪算法主要包括以下步骤:步骤1:对于给定的两个端点P1和P2,首先利用编码方法将两个端点进行编码。
编码中使用4位二进制数表示每个点所处位置。
步骤2:根据编码结果判断两个端点是否在裁剪区域内。
如果两个端点的编码值为0000(即都在可视范围内),则可以直接输出该线段;否则,执行下一步。
直线裁剪算法研究
直线裁剪算法研究直线裁剪算法是计算机图形学中的一种技术,用于将给定的直线段裁剪为可见部分。
在计算机中,直线由起点和终点坐标表示。
直线裁剪算法主要用于将不在可见区域内的线段进行剪裁,从而提高绘制效率,减少不必要的计算。
在直线裁剪算法中,常用的有Cohen-Sutherland算法、Liang-Barsky算法、中点画线算法和Bresenham算法等。
Cohen-Sutherland算法是最早提出的直线裁剪算法之一、该算法将可视区域分为9个区域,并用二进制编码表示。
对于给定的直线段,算法通过判断线段的起点和终点在可视区域内部或外部的区域位置,进而判断直线是否与可视区域相交。
如果线段完全在可视区域外部,则直接舍弃;如果线段完全在可视区域内部,则保留;如果线段与可视区域有交点,则计算交点,然后根据裁剪后的交点来得到裁剪后的线段。
Liang-Barsky算法是对Cohen-Sutherland算法的改进。
该算法通过参数化线段,并根据线段与裁剪窗口的交点,分别对起点和终点进行参数的调整。
通过对参数的调整,可以得到裁剪后的线段。
Liang-Barsky算法相比于Cohen-Sutherland算法在性能上有所提升。
中点画线算法是一种基于点的线段绘制算法,也可用于直线裁剪。
该算法在绘制线段过程中,每一步都将当前的点与直线的斜率进行比较,根据斜率的大小来决定是向上绘制还是向右上绘制。
根据直线的方向和可视区域的位置,可以在绘制的过程中进行一些判断,从而实现直线裁剪。
Bresenham算法是一种广泛应用于计算机图形学中的线段绘制算法,也可用于直线裁剪。
该算法使用整数运算来计算像素的位置和选择绘制的像素颜色,从而实现高效的线段绘制。
同样地,通过在绘制的过程中加入一些判断,可以实现直线的裁剪。
总结来说,直线裁剪算法是计算机图形学中的重要技术,用于将给定的直线段裁剪为可见部分。
不同的算法有其优缺点,根据具体的需求选择合适的算法可以提高绘制效率,减少不必要的计算。
简述cohen-sutherland直线段的裁剪算法
简述Cohen-Sutherland直线段的裁剪算法Cohen-Sutherland算法是一种经典的直线段裁剪算法,常用于计算机图形学中。
该算法对于裁剪窗口和直线段分别进行编码,通过比较编码来确定是否需要进行裁剪。
下面是Cohen-Sutherland算法的伪代码:function CohenSutherlandLineClip(x0, y0, x1, y1, xmin, ymin, xmax, ymax)OUTCODE_INSIDE = 0 // 线段完全在裁剪窗口内部OUTCODE_LEFT = 1 // 线段位于裁剪窗口左侧OUTCODE_RIGHT = 2 // 线段位于裁剪窗口右侧OUTCODE_BOTTOM = 4 // 线段位于裁剪窗口底部OUTCODE_TOP = 8 // 线段位于裁剪窗口顶部// 初始化线段的编码code0 = computeOutCode(x0, y0, xmin, ymin, xmax, ymax) code1 = computeOutCode(x1, y1, xmin, ymin, xmax, ymax)while (true) {if (code0 == 0 and code1 == 0) {// 线段完全在裁剪窗口内部return (x0, y0, x1, y1)} else if ((code0 & code1) != 0) {// 线段完全在裁剪窗口外部,可以丢弃return null} else {// 需要裁剪的部分x = 0y = 0codeOut = code0 != 0 ? code0 : code1// 计算交点if ((codeOut & OUTCODE_TOP) != 0) {x = x0 + (x1 - x0) * (ymax - y0) / (y1 - y0) y = ymax} else if ((codeOut & OUTCODE_BOTTOM) != 0) { x = x0 + (x1 - x0) * (ymin - y0) / (y1 - y0) y = ymin} else if ((codeOut & OUTCODE_RIGHT) != 0) { y = y0 + (y1 - y0) * (xmax - x0) / (x1 - x0) x = xmax} else if ((codeOut & OUTCODE_LEFT) != 0) { y = y0 + (y1 - y0) * (xmin - x0) / (x1 - x0) x = xmin}// 更新交点和编码if (codeOut == code0) {x0 = xy0 = ycode0 = computeOutCode(x0, y0, xmin, ymin, xmax, ymax)} else {x1 = xy1 = ycode1 = computeOutCode(x1, y1, xmin, ymin, xmax, ymax)}}}}function computeOutCode(x, y, xmin, ymin, xmax, ymax) code = 0if (x < xmin) {code = code | OUTCODE_LEFT} else if (x > xmax) {code = code | OUTCODE_RIGHT}if (y < ymin) {code = code | OUTCODE_BOTTOM} else if (y > ymax) {code = code | OUTCODE_TOP}return code}以上是一个简单的Cohen-Sutherland直线段裁剪算法的实现。
计算机图形学基础教程(Visual C++版)第05章 二维图形变换与裁剪(清华大学出版社 孔令德)
y
5-19 设备坐标系
图形学中常用的坐标系
规格化设备坐标系(Normalized Device Coordinate,NDC) 将设备坐标系规格化到(0.0,0.0)到(1.0,1.0)的 范围内而定义的坐标系。 规格化设备坐标系独立于具体输出设备。 一旦图形变换到规格化设备坐标系中,只要作一个简 单的乘法运算即可映射到具体的设备坐标系中。
wyt (xw,yw) 0000 wyb
vyt (xv,yv) 0000 vyb
wxl
wxr
vxl
已知窗口内的一点P的坐标(xw,yw),求视区中 对应点P’的坐标(xv,yv) 这属于相对于任一参考点的二维几何变换
vxr
变换步骤为:
1.将窗口左下角点(wxl,wyb)平移到观察坐标系 原点
写成方程为:
xv S x xw vxl wxl S x yv S y yw vyb wyb S y
则窗视变换的展开式为:
令
xv a x w b yv c y w d
裁剪
图形变换到观察坐标系下,需要按照窗口进行 裁剪,即只保留窗口内的那部分图形,去掉窗 口外的图形 假设窗口是标准矩形,即边与坐标轴平行的矩 形,由 上(y=wyt)、 下(y=wyb)、 左(x=wxl)、 右(x=wxr) 四条边描述
30
裁剪——点的裁剪
点是构成图形的基本元素 点的裁剪:
wxl x wxr, 且wyb y wyt
把图形全部打散成点进行裁剪?
31
二维直线段的裁剪
直线的裁剪是二维图形裁剪的基础 裁剪的实质是判断直线是否与窗口相交,如相 交则进一步确定位于窗口内的部分
计算机图形学 实验四 二维图形的裁剪
西北农林科技大学实习报告学院名称:理学院专业班级:姓名:学号:课程:计算机图形学实验报告日期:第十五周实验四二维图形的裁剪一、实验目的1)加深直线段的剪裁算法的理解。
2)熟练掌握一种裁剪算法的编程方法。
二、实验步骤1)分析直线段和矩形窗口的位置关系,选定比较合理算法流程。
2)画出程序流程图。
3)编写程序的源程序。
4)编辑源程序并进行调试。
5)进行特殊模式的运行测试,并结合情况进行调整。
三、实验内容1)在编码算法、中点分割算法、Liang-Barsky算法三种中任选一种作为编程模型。
2)编写直线段裁剪的源程序。
3)建议有能力的学生编写多边形裁剪程序。
4)在计算机上编辑编译运行,实现直线段的裁剪。
原理1.直线和窗口的关系:直线和窗口的关系可以分为如下3类:(1)整条直线在窗口内。
此时,不需剪裁,显示整条直线。
(2)整条直线在窗口外,此时,不需剪裁,不显示整条直线。
(3)部分直线在窗口内,部分直线在窗口外。
此时,需要求出直线与窗框的交点,并将窗口外的直线部分剪裁掉,显示窗口内的直线部分。
直线剪裁算法有两个主要步骤。
首先将不需剪裁的直线挑出,即删去在窗外的直线。
然后,对其余直线,逐条与窗框求交点,并将窗口外的部分删去。
2.Cohen-Sutherland直线剪裁算法:(1)输入直线段的两端点坐标p1(x1,y1),p2(x2,y2),以及窗口的4条边界坐标,y wt ,y wb,y wl,y wr.(2)对p1,p2进行编码,点p1的编码为code1,点p2的编码为code2.(3)若code1| code2=0,对直线p1p2“简取”之,转(6);否则,若code1& code2≠0,对直线段“简弃”之,转(7);当上述两条均不满足时,进行步骤(4)。
(4)确保p1在窗口外部。
若p1在窗口内,则交换p1和p2的坐标值和编码。
(5)根据p1编码从低位开始寻找值为1的地方,从而确定p1在窗口外的哪一侧,然后求出直线段与相应窗口边界的交点S,并用交点S的坐标值替换p1的坐标值,即在交点S处把线段一分为二,因此可以去掉p1S。
第6章图形裁剪
下面假定裁剪是针对用户坐标系中窗口边界进行的, 裁剪完成后,再把窗口内图形映射到视区。所以裁剪的 目的是显示可见点和可见部分,删除视区外的部分。
第六章 图形裁剪(Clipping)
在用户坐标系中定义的图形往往是大而复杂的,而 输出设备如显示屏幕的尺寸及其分辨率却是有限的,为 了能够清晰地观察某一部分或对其进行某些绘图操作, 就需要将所关心的这一局部区域的图形从整个图形中区 分出来,这个区分指定区域内和区域外的图形过程称为裁 剪,所指定的区域称为裁剪窗口。
在用户坐标中设置观察坐标系,在观察坐标系中定 义一个观察窗口。观察坐标系用来任意设置矩形窗口的 方向。一旦建立了观察参考系,就可以将用户坐标系下 的描述变换到观察坐标系下。
2019/11/18
计算机图形学演示稿 纪玉波制作
2
(C)
2019/11/18
计算机图形学演示稿 纪玉波制作
3
(C)
3.规范化设备坐标系(Normalized Device Coordinates) 在规范化坐标系下(取值范围从0到1)定义视区,将
设备坐标定义,一般也定义成矩形,由其左下角和右上角两
点坐标来定义。所以,用户可以利用窗口来选择需要观察那
一部分图形,而利用视图区来指定这一部分图形在屏幕上显
示的位置。标准的窗口区和视图区一般都是矩形,其各边分
别与坐标轴平行。
2019/11/18
计算机图形学演示稿 纪玉波制作
6
(C)
用户定义的图形从窗口区到视图区的输出过程如下: 从 应 用 程 序 得 到 图 形 的 用 户 坐 标 (WC-World Coordinates)→对窗口区进行裁剪(WC)→窗口区到视图区的 规格化变换(NDC-Normalized Device Coordinate) →视图区 从 规 格 化 设 备 系 到 设 备 坐 标 系 的 变 换 (DC-Device Coordinate)→在图形设备上输出图形。
计算机图形学-实验五直线和多边形的裁剪
大学实验报告学院:计算机科学与信息学院专业:软件工程班级: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* = *L;y = y1 + (y2 - y1) * (*L - *1) / (*2 - *1);// 求直线与矩形窗口的左边界的交点} elseif ((RIGHT & code) != 0) {// 直线的端点与矩形窗口的右边编码相与!=0* = *R;y = y1 + (y2 - y1) * (*R - *1) / (*2 - *1);// 求直线与矩形窗口的右边界的交点} elseif ((BOTTOM & code) != 0) {// 直线的端点与矩形窗口的下边编码相与!=0y = YB;* = *1 + (*2 - *1) * (YB - y1) / (y2 - y1);// 求直线与矩形窗口的下边界的交点} elseif ((TOP & code) != 0) {// 直线的端点与矩形窗口的上边编码相与!=0y = YT;* = *1 + (*2 - *1) * (YT - y1) / (y2 - y1);// 直线的端点与矩形窗口的上// 边编码相与!=0}if (code == code1) {*1 = *;y1 = y;code1 = encode(*, y);} else {*2 = *;y2 = y;code2 = encode(*, y);}}g.drawLine((int) (*1 + 0.5), (int) (y1 + 0.5), (int) (*2 + 0.5),(int) (y2 +0.5));}二、多边形裁剪的核心代码为:通过点集画直线或者多边形:privatevoid draw() {//通过点集画直线或者多边形for (int i = 1; i < points.size(); i++) {Point p1 = new Point();p1 = points.get(i);int *1 = (int) p1.get*();int y1 = (int) p1.getY();Point p2 = new Point();p2 = points.get(i - 1);int *2 = (int) p2.get*();int y2 = (int) p2.getY();g.drawLine(*1, y1, *2, y2);}}多边形的裁剪函数:private Point[] cutPicture(Point[] point, Point[] edge) {// 剪裁函数,参数为〔点集,边〕Point[] intersectPoint = new Point[20];//存放交点的集合for (int j = 0; j < 20; j++) {intersectPoint[j] = new Point();}Point s = new Point();Point p = new Point();Point t = new Point();int i = 0;int length = point.length;s = point[length - 1];for (int j = 0; j < length; j++) {p = point[j];if (inside(p, edge)) {// sp在窗口,情况1if (inside(s, edge)) {intersectPoint[i] = p;i += 1;} else {// s在窗口外,情况4t = intersect(s, p, edge);intersectPoint[i] = t;i += 1;intersectPoint[i] = p;i += 1;}} elseif (inside(s, edge)) {// s在窗口,p在窗口外,情况3t = intersect(s, p, edge);intersectPoint[i] = t;i += 1;}// 情况2没有输出s = p;}List<Point> tempList = new ArrayList<Point>();for (int k = 0; k < i; k++) {if (intersectPoint[k] != null) {Point pt = intersectPoint[k];tempList.add(pt);}}Point[] temp = new Point[tempList.size()];for (int j = 0; j < tempList.size(); j++) {temp[j] = new Point();temp[j] = tempList.get(j);}intersectPoint = temp;return intersectPoint;}判断点是否在裁剪边的可见侧:privateboolean inside(Point point, Point[] edge) {//判断点是否在裁剪边的可见侧// 裁剪边为窗口下边if ((edge[0].y == edge[1].y) && (edge[0].* < edge[1].*)) {if (point.y >= edge[0].y) {returntrue;}}// 裁剪边为窗口上边if ((edge[0].y == edge[1].y) && (edge[0].* > edge[1].*)) {if (point.y <= edge[0].y) {returntrue;}}// 裁剪边为窗口右边if ((edge[0].* == edge[1].*) && (edge[0].y < edge[1].y)) {if (point.* <= edge[0].*) {returntrue;}}// 裁剪边为窗口左边if ((edge[0].* == edge[1].*) && (edge[0].y > edge[1].y)) {if (point.* >= edge[0].*) {returntrue;}}returnfalse;}直线段与窗口边界求交:private Point intersect(Point s, Point p, Point[] edge) {//直线段与窗口边界求交,并返回交点Point t = new Point();if (edge[0].y == edge[1].y) {// 水平裁剪边t.y = edge[0].y;t.* = s.* + (edge[0].y - s.y) * (p.* - s.*) / (p.y - s.y);} elseif (edge[0].* == edge[1].*) {// 垂直裁剪边t.* = edge[0].*;t.y = s.y + (edge[0].* - s.*) * (p.y - s.y) / (p.* - s.*);}return t;}鼠标的监听类〔部类〕:class MouseMonitor e*tends MouseAdapter {//通过鼠标的单击获取点,并画出直线或者多边形publicvoid mouseClicked(MouseEvent e) {points.add(e.getPoint());if (points.size() > 1) {draw();}}}键盘的监听类〔部类〕:class KeyMonitor e*tends KeyAdapter {// 键盘控制publicvoid keyPressed(KeyEvent e) {switch (e.getKeyCode()) {case KeyEvent.VK_R:// 清空画布和点集panel.repaint();points.removeAll(points);break;case KeyEvent.VK_W://对裁剪窗口的处理g.setColor(Color.RED);g.drawRect(*L, YB, *R - *L, YT - YB);//存放裁剪窗口的边top = new Point[2];// 存放裁剪窗口的上边top[0] = new Point(*L, YB);top[1] = new Point(*R, YB);right = new Point[2];//存放裁剪窗口的右边right[0] = new Point(*R, YB);right[1] = new Point(*R, YT);bottom = new Point[2];//存放裁剪窗口的下边bottom[0] = new Point(*R, YT);bottom[1] = new Point(*L, YT);left = new Point[2];//存放裁剪窗口的左边left[0] = new Point(*L, YT);left[1] = new Point(*L, YB);break;case KeyEvent.VK_A://对直线段进展裁剪g.setColor(Color.GREEN);Point p1 = points.get(0);Point p2 = points.get(1);lineCut(p1.get*(), p1.getY(), p2.get*(), p2.getY()); break;case KeyEvent.VK_B://对多边形进展裁剪source = new Point[points.size()];//得到多边形的点for (int i = 0; i < points.size(); i++) {source[i] = points.get(i);}g.setColor(Color.GREEN);wT = cutPicture(source, top);//得到多边形与裁剪窗口上边的交点wR = cutPicture(wT, right);//得到多边形与裁剪窗口右边的交点wB = cutPicture(wR, bottom);//得到多边形与裁剪窗口下边的交点wL = cutPicture(wB, left);//得到多边形与裁剪窗口左边的交点第二种情况:线段在裁剪窗口的部,线段完全可见。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
实验:直线段的裁剪
姓名:龙泽学号: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 <windows.h>
#include <GL/glut.h>
//初始化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;
{
dx=dy;
dy=temp;
interchange=1;
}
else
interchange=0;//x 方向增长快,将总步数设为x2-x1 ,每
步的x 值为:x=x+1
p=2*dy-dx; // 设置初始误差判别值
for(i=1;i<=dx;i++)
{
setPixel(x,y);
if(p>=0)
{
if(interchange==0)
y=y+s2;
else
x=x+1;
p=p-2*dx;
}
if(interchange==0)
x=x+s1;
else
y=y+s2;
p=p+2*dy;
{
//Liang-Barsky 算法
int Clip_Top(float p,float q,float &umax,float &umin) { float r=0.0;
if(p<0.0) // 线段从裁剪窗口外部延伸到内部, 取最大值 r 并更新 umax { r=q/p; if (r>umin) return 0; //umin>umax 的情况,弃之 else if (r>umax) umax=r; }
else if(p>0.0) // 线段从裁剪窗口内部延伸到外部 , 取最小值 r 并更新 umin { r=q/p;
if (r<umax) return 0; //umin>umax 的情况,弃之
else if(r<umin) umin=r;
}
else //p=0 时,线段平行于裁剪窗口 if(q<0.0) return 0; return 1;
}
x1, float y1, float x2, float y2,float Wxl,float 定义线段的坐
标和矩形的四条边界
float dx=x2-x1,dy=y2-y1,umax=0.0,umin=1.0;
// 比较左、右边界,获得最大的 umax
void Line_Clipping(float
Wxr,float Wyt,float Wyb)//
if (Clip_Top(-dx,x1-Wxl,umax,umin)) // 左边界
if (Clip_Top(dx,Wxr-x1, umax,umin))// 右边界
// 比较下、上边界,获得最小的umin
if (Clip_Top(-dy,y1-Wyb, umax,umin))// 下边界
if (Clip_Top(dy,Wyt-y1, umax,umin))// 上边界
line((int)(x1+umax*dx),(int)(y1+umax*dy),(int)(x1+umin*dx),
(int)(y1+umin*dy));
}
void display(void)// 需要点击鼠标显示,所以这里的display 函数下为空
{
}
// 鼠标响应函数,控制当鼠标接收到不同的用户操作时将要执行的后续命令。
void mouse(int button, int state, int x, int y)
{
Float x1=70,y1=480,x2=480,y2=80, Wxl=100,Wxr=400,Wyt=400,Wyb=200;// 给定直线和矩形的各项参数数值
switch (button)
{
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN如果按下鼠标左键,则显示矩形和待裁剪
的直线段
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 清除缓存glColor3f(0,0,0); // 给定矩形线条的颜色
line(Wxl,Wyt,Wxr,Wyt); // 定义矩形的上边界
line(Wxl,Wyb,Wxr,Wyb); // 定义矩形的下边界
line(Wxr,Wyb,Wxr,Wyt); // 定义矩形的右边界
line(Wxl,Wyb,Wxl,Wyt); // 定义矩形的左边界
glColor3f(0,0,255); // 给定直线的颜色
line (x1,y1,x2,y2); // 给定直线的起点坐标和终点坐标
glFlush (); // 绘图结束break;
case GLUT_MIDDLE_BUTTON:
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN如果按下鼠标右键,则显示裁剪过后的直线
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);清除缓存
glColor3f(0,0,0); // 给定剪裁后的矩形的颜色
line(Wxl,Wyt,Wxr,Wyt);
line(Wxl,Wyb,Wxr,Wyb);
line(Wxr,Wyb,Wxr,Wyt);
line(Wxl,Wyb,Wxl,Wyt); // 分别给定矩形的四条边的坐标
glColor3f(255,0,0); // 给定剪裁后的直线的颜色
Line_Clipping(x1,y1,x2,y2,Wxl,Wxr,Wyt,Wyb); // 调用上面
的Line_Clipping 函数进行裁剪
glFlush (); // 绘图结束
default: break;
}
int main(int argc, char** argv)
{
glutInit(&argc, argv); // glutInitDisplayMode 用单缓存,RGB 彩色系统 glutInitWindowSize (500, 500);
glutInitWindowPosition (100, 100); // glutCreateWindow (" 直线的裁剪 "); myinit (); // glutDisplayFunc(display); // glutMouseFunc(mouse); glutMainLoop(); // return 0;
}
实验结果:
经过大量的调试以后,运行的结果如下:
初始化 glut
(GLUT_SINGLE| GLUT_RGB); // 初始化显示模式,采
// 初始化窗口大小 初始化窗口位置
// 创建窗口 自定义初始化 注册显示函数
进入OpenG 啲主循环。
开始工作
点击鼠标左键如图:
点击鼠标右键如图:。