直线裁剪 Cohen-Sutherland 算法
Computer Graphics #001
编码
- 把平面按照裁剪窗口分为九块,用四位二进制数表示每一块区域。
在 A 、C 、E 、G 四个区域分别填入 2 i , i ∈ { 0 , 1 , 2 , 3 } 2^i,\;i\in\{0,1,2,3\} 2i,i∈{0,1,2,3} (不要求位置对应)
然后每个角落填入两个邻接块的值的或
比如假设 A = ( 0001 ) 2 , C = ( 0100 ) 2 A=(0001)_2,\;C=(0100)_2 A=(0001)2,C=(0100)2 那么 B = A ∣ C = ( 0101 ) 2 B=A|C=(0101)_2 B=A∣C=(0101)2
假设现在要裁剪线段
ℓ
\ell
ℓ
接下来只需要通过对线段
ℓ
\ell
ℓ 端点所属区域进行位运算来分类讨论
以下就都是高中数学内容了
裁剪
首先
0. 按位与和按位或结果相同表示线段完全在结果对应区域内
1. 按位或可以判断在剪裁区域 ( 0000 ) 中的线段(结果为 0000 )
2. 按位与可以判断在剪裁区域外且只过两个区域的线段 (结果为 2i )
接下来不能直接判断,需要求线段所在直线与 0000 区域四边界所在直线的交点
首先,两线段端点按位或得到交点所在边界。
eg.
C = ( 0010 ) 2 , E = ( 0100 ) 2 , G = ( 1000 ) 2 C=(0010)_2,\;E=(0100)_2,\;G=(1000)_2 C=(0010)2,E=(0100)2,G=(1000)2
D ∣ G = ( 1110 ) 2 D|G=(1110)_2 D∣G=(1110)2
接下来重复:
求出 交点所在边界所在直线 与 线段
ℓ
\ell
ℓ 所在直线 的交点中的某一个。
将 所在区域编码 与 该交点所在区域编码 按位或结果非 0 的那个端点 用这个点替换
(也可以替换后得到新的直线重复整个算法,可能会快一点)