Nicholl-Lee-Nicholl线段裁剪算法学习与详解
【算法简介】
Nicholl-Lee-Nicholl(NLN)算法通过在裁剪窗口边界创建多个区域,从而避免对一个直线段进行多次裁剪。
Cohen-Sutherland算法中,在找到与裁剪窗口边界的交点之前或完全舍弃该线段之前,必须对一条线段进行多次求交计算。NLN算法则在求交计算前进行更多的区域测试,从而减少求交计算。
与Cohen-Sutherland算法和梁友栋-Barsky算法相比,NLN算法的比较次数和除法次数减少。但NLN算法仅用于二维裁剪。
【算法描述】
确定一线段完全在裁剪窗口内部或外部的初始测试可以像前两个算法一样用区域码测试来完成。如果一个线段不能明确接受或拒绝,则NLN算法进一步建立另外的裁剪区域。
对于端点为P0和Pend的线段,首先确定P0位于裁剪窗口的九个可能区域的位置。在下图中只需考虑三个区域。若位于其他六个区域之一,则可以利用对称变换将其变换到下图三个区域之一。
例如,在裁剪窗口正上方的区域,可以相对于直线y=-x投影到裁剪窗口的左边区域;或使用90度逆时针旋转,可以达到同样效果。
假定P0和Pend不同时在裁剪窗口的内部,下一步判断Pend相对于P0的位置。为此,根据P0的位置在平面上创立新的区域。新区域的边界是以P0为起点、穿过窗口顶点的射线。
1、如果P0在裁剪窗口之内,Pend在窗口之外,就设置四个区域,如下图所示。根据包含Pend点的某一个区域(L,T,R和B),可得线段与窗口交点。
2、如果P0位于窗口的左边区域,则设定四个区域:L、LT、LR、LB,如下图所示,这四个区域决定了线段的唯一边界。
如Pend在L区域,我们在左边界上裁剪该线段,且保存从交点到Pend之间的线段。
如果Pend在LT区域,则存储窗口左边界和上边界之间的线段部分。
对区域LR、LB处理类似。若Pend不在这四个区域,则舍弃整个线段。
3、当P0在窗口的左上方时,有如下图的两种情况。
如果P0接近裁剪窗口左边界,使用图中(a)的区域;
如果P0接近窗口的上边界,使用图中(b)的区域。
如果Pend在区域T、L、LT、TR、TB、LR或LB中,则确定了求交计算的唯一裁剪窗口边界,否则舍弃整个线段。
为了确定Pend位于哪个区域,要比较该线段的斜率和裁剪区域边界的斜率。
例如,上述情况2中,若P0在裁剪边界的左边并且满足:
斜率 P 0 P R T ‾ < \overline{P_{0}P_{RT}}< P0PRT<斜率 P 0 P e n d ‾ < \overline{P_{0}P_{end}}< P0Pend<斜率 P 0 P T L ‾ \overline{P_{0}P_{TL}} P0PTL
则:Pend在区域LT中。