直线段的裁剪
计算机科学技术:计算机图形学题库三

计算机科学技术:计算机图形学题库三1、名词解释扫描转换答案:在矢量图形中,多边形用顶点序列来表示,为了在光栅显示器或打印机等设备上显示多边形,必须把它转换为点阵表示。
这种转换称为扫描转换。
2、单选下面对光栅扫描图形显示器描述正确的是()A.荧光粉涂层均匀离散分布;B.是一种点画设备;C.电子束从顶到底扫描;D.通过控制电子束的强弱实现色彩的强弱;答案:A3、填空题计算机图形系统由()系统和软件系统组成。
答案:硬件4、填空题在处理图形时常常涉及的坐标系有模型坐标系(),世界坐标系,观察坐标系,设备坐标系。
答案:局部坐标系5、单选计算机图形学与计算机图象学的关系是()。
A.计算机图形学是基础,计算机图象学是其发展B.不同的学科,研究对象和数学基础都不同,但它们之间也有可转换部分C.同一学科在不同场合的不同称呼而已D.完全不同的学科,两者毫不相干答案:B6、问答题简述中点分割法进行裁剪的过程?答案:中点分割剪取法,主要是对线段不断地进行对分,并排除在区域外的部分,找出线段落在窗口内的部分。
其方法主要是通过求出离线段的一个端点最近并且在区域内的点的方法,来确定线段落在窗口内的端点。
7、问答题局部光照模型和全局光照模型的不同之处是什么?答案:局部光照模型主要是考虑光源发出的光对物体的直接影响。
另外,全局光照模型除了处理光源发出的光之外,还考虑其他辅助光的影响,如光线穿过透明或半透明物体,以及光线从一个物体表面反射到另一个表面等。
8、判断题彩色阴极射线管主要是由红绿蓝三个彩色电子束的亮度不同,进而组合形成各种色彩的。
答案:错9、问答题什么叫做走样?什么叫做反走样?反走样技术包括那些?答案:走样指的是用离散量表示连续量引起的失真。
为了提高图形的显示质量。
需要减少或消除因走样带来的阶梯形或闪烁效果,用于减少或消除这种效果的方法称为反走样。
其方法是①前滤波,以较高的分辨率显示对象;②后滤波,即加权区域取样,在高于显示分辨率的较高分辨率下用点取样方法计算,然后对几个像素的属性进行平均得到较低分辨率下的像素属性。
计算机图形学第6章二维图形的裁剪

• 重点:掌握二维图形点、线段、多边形和字符的裁剪算法 。
• 难点:理解二维图形的裁剪算法思想并且用C语言进行算法 的实现。
一、裁剪的意义 为了描述图形对象,我们必须存储它的全部信息,但有时为了达到分 区描述或重点描述某一部分的目的,往往将要描述的部分置于一个窗口内, 而将窗口外的部分“剪掉”,这个处理过程叫做裁剪,裁剪在计算机图形 处理中具有十分重要的意义。 裁剪实质上是从数据集合中抽取信息的过程,这个过程是通过一定的 计算方法来实现。
7.2.2 中点分割算法
二、中点分割算法实现: 1、将直线的两端点P1、P2编码得:C1、C2; 2、判别 根据C1和C2的具体值,可以有三种情况: (1)C1=C2=0,表明两端点全在窗口内,因而整个线段也在窗内, 应予保留。 (2)C1&C2≠0(两端点代码按位作逻辑乘不为0),即C1和C2至少 有某一位同时为1,表明两端点必定处于某一边界的同一外侧,因而整个线 段全在窗外,应予舍弃。 (3)不属于上面两种情况,均需要求交点。
如果上面四个不等式中任何一个不满足,则点(x,y)位于窗口之 外。 对于任意多边形窗口,需要根据多边形内点的判别准则进行判断。
7.2 线段的裁剪
直线段的裁剪比点复杂,其裁剪方法又是多边形裁剪和三维图形裁剪的 基础。 一、直线裁剪的基本思想 判断直线与窗口的位置关系: 1.确定直线是完全可见; 2.部分可见; 3.还是完全不可见。 对部分可见线段,求出它与窗口边界的交点,并将窗口内的线段输出。
一、中点分割算法思想: 1、中点公式
7.2.2 中点分割算法
2、中点分割法求交点的规则 如图中所示,当线段P1P2求出中点P后,舍弃线段的哪部分,由下面 两条规则决定:
中点分割法求交点规则
复习题计算机图形学提纲 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的符号。
计算机图形学期末编程大作业

{Xs=dlgBresenhamline.m_Xs;
Ys=dlgBresenhamline.m_Ys;
Xe=dlgBresenhamline.m_Xe;
Ye=dlgBresenhamline.m_Ye;}
//使传入的端点坐标X值相等
2)Bresenham画圆算法
Bresenham画法与中点画法一样,也考虑从(0,R)到(R/ ,R/ )的八分之一圆周。取(0,R)为起点,按顺时针方向生成圆。从这段圆弧的任意一点出发,按顺时针方向生成圆时,为了最佳逼近该圆,下一像素的取法只有三种可能的选择:正右方像素,右下方像素和正下方像素。这三个像素中,与理想圆弧最近者为所求像素。
}
}
//斜率绝对值大于1
else
{//情况三:Y递增
if(Ys<=Ye)
{p=(dx<<1)-dy;
while(y<=Ye)
{dc.SetPixel(x,y,m_clr);
if(p<0)
{y++;p=p+(dx<<1);}
else
{x++;y++;p=p+((dx-dy)<<1);}
}
}
//情况四:Y递减
b.直线的绘制
图1-3直线参数对话框
鼠标左键点选菜单栏中的 菜单,会弹出下拉菜单,其中提供2种直线绘制的经典算法,包括DDA算法和Bresenham算法。我们可随意选择一种,例如Bresenham算法。
说表左键单击选定后,便会弹出参数输入对话框,如图3。
注意:由于在计算机的图形显示时,屏幕坐标默认以屏幕左上角点为(0,0)点,X轴方向水平指向右侧,Y轴方向竖直指向下侧。与我们实际中熟悉的坐标系不同,输入点坐标时要注意。例如直线的起止点坐标分别为(0,0)、(100,100),绘制结果如图5。
计算机图形学试题及答案

一、 判断题(10x1=10分)1、 构成图形的要素可分为两类:刻画形状的点、线、面、体的非几何要素与反映物体表面属性或材质的明暗、色彩等的几何要素。
( 错误 )2、 参数法描述的图形叫图形;点阵法描述的图形叫图像。
( 正确 )3、 EGA/VGA 为增强图形显示效果的一种图形处理软件的名称。
( 错误 )4、 对山、水等不规则对象进行造型时,大多采用过程式模拟方法。
( 正确 )5、 若两个图形是拓扑等价的,则一个图形可通过做弹性运动与另一个图形相重合。
( 正确 )6、 0阶参数连续性和0阶几何连续性的定义是相同的。
( 正确 )7、 Bezier 曲线可做局部调整。
( 错误 )8、 字符的图形表示分为点阵和矢量两种形式。
( 正确 ) 9、 LCD 表示发光二极管显示器。
( 错误 )10、 使用齐次坐标可以将n 维空间的一个点向量唯一的映射到n+1维空间中。
( 错误 ) 二、 填空题(15x2=30分)1、目前常用的PC 图形显示子系统主要由3个部件组成:(1)帧缓冲存储器、(2)显示控制器、(3)ROM BIOS 。
2、 图形的输入设备有(4)键盘、鼠标、光笔(至少写三种);图形的显示设备有(5)CRT 显示器、LCD 、投影仪(至少写三种)。
3、常用坐标系一般可以分为:建模坐标系、用户坐标系、(6观察坐标系、(7)规格化设备坐标系、(8)设备坐标系。
4、在多边形的扫描转换过程中,主要是通过确定穿越多边形区域的扫描线的覆盖区间来填充,而区域填充则是从(9)给定的位置开始涂描直到(10)指定的边界条件为止。
5、一个交互式计算机图形系统应具有(11)计算 、(12)存储、(13)对话、(14)输入和输出等五个方面的功能。
三、 简答题(5x6=30分)1、 请列举常用的直线段裁减算法(四种)。
答:答:直接求交算法、编码算法、中点再分算法、Cyrus-Beck 算法。
2、 考虑三个不同的光栅系统,分辨率依次为480640⨯,10241280⨯,20482560⨯。
哈工大chapter 05裁剪、反走样

Pm B P1
中点分割裁剪算法
中点分割裁剪算法
ϒ 对分辩率为2N次。 ϒ 主要过程只用到加法和除法运算,适合硬件 实现,它可以用左右移位来代替乘除法,这 样就大大加快了速度。
梁友栋-Barsky算法
设要裁剪的线段是P0P1。 P0P1和 窗口边界交于A,B,C,D四点,见图。 算法的基本思想是从A,B和P0三点中 找出最靠近的P1点,图中要找的点 是P0。从C,D和P1中找出最靠近P0的 点。图中要找的点是C点。那么P0C 就是P0P1线段上的可见部分。
哪些落在显示区之外,以便只显示落在显示区 内的那部分图形。这个选择过程称为裁剪。
图形裁剪算法,直接影响图形系统的效率。
点的裁剪
ϒ 图形裁剪中最基本的问题。
为(xL,yB),右上角坐标 为(xR,yT),对于给定点 P(x,y),则P点在窗口内的条 件是要满足下列不等式: xL <= x <= xR (xL,yB ϒ 并且yB <= y <= yT ) 否则,P点就在窗口外。 ϒ 问题:对于任何多边形窗口, 如何判别?
第五章 裁剪、反走样 方法
反走样方法 裁剪算法
反走样
ϒ 用离散量表示连续量引起的失真现象称之为走样
(aliasing) 。 光栅图形的走样现象
阶梯状边界; 图形细节失真; 狭小图形遗失:动画序列中时隐时现,产生闪烁。
时间上的混淆现象
轮子的转速是:1r/s(1HZ)
每0.75s采一次样(1/0.75HZ)
1
P0P1至少部分可见的充分条件是 max(0, t 0) ≤ min(1, t1 ) 且可见部分的参数区间为[max(0, t 0 ),min(1, t1)]。
t0 Q0 0 P0 t1 Q1 1 P1
直线裁剪算法

直线裁剪算法直线裁剪算法⼀、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、两者均只能应⽤于矩形窗⼝。
计算机图形学实验三

太原工业学院实验报告GetClientRect(&rect);//获得客户区的大小pDC->SetMapMode(MM_ANISOTROPIC);//pDC自定义坐标系pDC->SetWindowExt(rect.Width(),rect.Height());//设置窗口范围pDC->SetViewportExt(rect.Width(),-rect.Height());//设置视区范围,x轴水平向右,y轴垂直向上pDC->SetViewportOrg(rect.Width()/2,rect.Height()/2);//客户区中心为原点CDC memDC;//内存DCCBitmap NewBitmap,*pOldBitmap;//内存中承载的临时位图memDC.CreateCompatibleDC(pDC);//创建一个与显示pDC兼容的内存memDCNewBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());//创建兼容位图pOldBitmap=memDC.SelectObject(&NewBitmap);//将兼容位图选入memDCmemDC.FillSolidRect(rect,pDC->GetBkColor());//按原来背景填充客户区,否则是黑色memDC.SetMapMode(MM_ANISOTROPIC);//memDC自定义坐标系memDC.SetWindowExt(rect.Width(),rect.Height());memDC.SetViewportExt(rect.Width(),-rect.Height());memDC.SetViewportOrg(rect.Width()/2,rect.Height()/2);rect.OffsetRect(-rect.Width()/2,-rect.Height()/2);DrawWindowRect(&memDC);//绘制窗口if(PtCount>=1){memDC.MoveTo(Round(P[0].x),Round(P[0].y));memDC.LineTo(Round(P[1].x),Round(P[1].y));}pDC->BitBlt(rect.left,rect.top,rect.Width(),rect.Height(),&memDC,-rect.Width()/2,-rect.Height()/2,SRCCOPY);//将内存memDC中的位图拷贝到显示pDC中memDC.SelectObject(pOldBitmap);//恢复位图NewBitmap.DeleteObject();//删除位图}(2)绘制裁剪窗口void CTestView::DrawWindowRect(CDC* pDC)//绘制裁剪窗口{// TODO: Add your message handler code here and/or call defaultpDC->SetTextColor(RGB(128,0,255));pDC->TextOut(-10,Wyt+20,CString("窗口"));CPen NewPen3,*pOldPen3;//定义3个像素宽度的画笔NewPen3.CreatePen(PS_SOLID,3,RGB(255,128,0));pOldPen3=pDC->SelectObject(&NewPen3);pDC->Rectangle(Wxl,Wyt,Wxr,Wyb);pDC->SelectObject(pOldPen3);NewPen3.DeleteObject();}(3)Cohen-Sutherland算法void CTestView::Cohen()//Cohen-Sutherland算法{CP2 p;//交点坐标EnCode(P[0]);//起点编码EnCode(P[1]);//终点编码while(P[0].rc!=0 || P[1].rc!=0)//处理至少一个顶点在窗口之外的情况{if((P[0].rc & P[1].rc)!=0)//简弃之{PtCount=0;return;}if(0==P[0].rc)//确保P[0]位于窗口之外{CP2 Temp;Temp=P[0];P[0]=P[1];P[1]=Temp;}UINT RC=P[0].rc;double k=(P[1].y-P[0].y)/(P[1].x-P[0].x);//直线段的斜率//窗口边界按左、右、下、上的顺序裁剪直线段if(RC & LEFT)//P[0]点位于窗口的左侧{p.x=Wxl;//计算交点y坐标p.y=k*(p.x-P[0].x)+P[0].y;}else if(RC & RIGHT)//P[0]点位于窗口的右侧{p.x=Wxr;//计算交点y坐标p.y=k*(p.x-P[0].x)+P[0].y;}else if(RC & BOTTOM)//P[0]点位于窗口的下侧{p.y=Wyb;//计算交点x坐标p.x=(p.y-P[0].y)/k+P[0].x;}else if(RC & TOP)//P[0]点位于窗口的上侧{p.y=Wyt;//计算交点x坐标p.x=(p.y-P[0].y)/k+P[0].x;}EnCode(p);P[0]=p;}}void CTestView::EnCode(CP2 &pt)//端点编码函数{pt.rc=0;if(pt.x<Wxl)pt.rc=pt.rc|LEFT;else if(pt.x>Wxr)pt.rc=pt.rc|RIGHT;if(pt.y<Wyb)pt.rc=pt.rc|BOTTOM;else if(pt.y>Wyt)pt.rc=pt.rc|TOP;}(4)人机交互void CTestView::OnDrawpic(){// TODO: Add your command handler code herePtCount=0;bDrawLine=TRUE;MessageBox(CString("鼠标画线,剪刀裁剪"),CString("提示"),MB_OKCANCEL);Invalidate(FALSE);}运行结果:实验拓展:在屏幕上显示一个直线构成的图案,使用鼠标选择两点绘制矩形代表窗口对图案矩形裁剪。
- 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;
}
void Line_Clipping(float x1, float y1, float x2, float y2,float Wxl,float Wxr,float Wyt,float Wyb)//定义线段的坐标和矩形的四条边界
{
float dx=x2-x1,dy=y2-y1,umax=0.0,umin=1.0;
//比较左、右边界,获得最大的umax
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); //初始化glut
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); //初始化显示模式,采用单缓存,RGB彩色系统
glutInitWindowSize (500, 500); //初始化窗口大小
glutInitWindowPosition (100, 100); // 初始化窗口位置
glutCreateWindow ("直线的裁剪"); //创建窗口
myinit (); //自定义初始化
glutDisplayFunc(display); //注册显示函数
glutMouseFunc(mouse);
glutMainLoop(); //进入OpenGL的主循环。
开始工作
return 0;
}
实验结果:
经过大量的调试以后,运行的结果如下:
点击鼠标左键如图:
点击鼠标右键如图:。