裁剪算法

OpenGL中经常用到裁剪,这里记录下裁剪的一些基本算法和概念。

裁剪概念

裁剪就是去掉窗口外不可见的部分,保留在窗口中的内同。是OpenGL的管线中必不可少的一步,裁剪算法的执行效率会直接影响整个程序的效率。
裁剪可以按照线或面进行,一般使用规则裁剪框进行裁剪,也有用不规则图形进行裁剪,常见的是使用矩形框进行裁剪。
裁剪过程的难度随裁剪区域的复杂度和被裁剪物体的形状复杂程度增加。
这里用矩形裁剪框解释常用的裁剪算法。

点的裁剪

点的裁剪相对简单,已知矩形裁剪框的两个对角线顶点坐标A(x1,y1)、B(x2,y2),判断点P(x,y)是不是在A、B坐标范围内即可。
若:
min(x1,x2) <= x <= max(x1,x2);
min(y1,y2) <= y <= max(y1,y2);
则P点在裁剪框中,否则在裁剪框外。

直线的裁剪

这里说的直线,都是线段。线的裁剪算法有很多,常见的有:cohen-sutherland算法,中点分割裁剪算法,Liang-Barsky算法,beck算法等。

Cohen-Sutherland算法

这个算法的主要思想是,用四位掩码做运算判断线是否在裁剪框内,如果在或全部在裁剪框外,结束。如果部分在窗口中,用线和裁剪框的交点对线段进行分割,然后分割后的继续重复判断。步骤如下:

  1. 编码
    用裁剪框的延长线将整个坐标分成9个区域,分别用4位01进行编码。编码规则:
  • 前两位表示区域和裁剪框的上下关系:如果该区域在窗口的上方,编码为10;和裁剪框同位置,编码为00;在裁剪框下面,编码为01。
  • 后两位表示区域和裁剪框的左右关系,如果该区域在窗口的右边,编码为10;和裁剪框同位置,编码为00;在裁剪框左边,编码为01。
    这样对线段的两个端点求出编码C1和C2。


  1. 判断
    用C1和C2进行判断:
  • 若 C1=C2=0,两个端点在裁剪框内,结束判断。
  • 若 C1∧C2≠0,即做逻辑与操作,结果为非零时,线段两点在窗口的同侧,在裁剪框外,结束判断。
    若不是以上两种情况,有可能为三种情况:1、一个端点在裁剪框内,另一个端点在裁剪框外;2、两个端点都在裁剪框外,但是和裁剪框相交;3、线段斜挎三个区域,且都在裁剪框外。
    这时进入下一步运算。


  1. 求交点
    对上面三种情况中不能判断的直线,计算线段和裁剪框边界及延长线的交点,通过交点将线段分割成子线段,然后用子线段重复上面的1和2步骤。
    这里求子线段的交点时,可以用已有的编码快速判断出线段和裁剪框的那个边相交。如X点的编码时1000,Y点的编码是0000,表明第一位不同表明线段与裁剪框上边界相交。

中心分割算法

设要裁剪的线段是P0P1。从P0端点出发,找出离P0点最近的可见点。从P1端点出发,找出离P1点最近的可见点。这两个可见点的连线就是裁剪框中的要保留的部分。
找可见点的方法用二分法,先取线段的中点M点,判断P1M是否可见,如果不能定为不可见,用P1M线段再2分,重复判断。


你可能感兴趣的:(裁剪算法)