直线段扫描转换
直线裁剪算法
点裁剪
对于任意的点P(x,y),若满足下列两对不等式:
{
x
l
e
f
t
⩽
x
⩽
x
r
i
g
h
t
y
b
o
t
t
o
m
⩽
y
⩽
y
t
o
p
\left\{\begin{matrix} x_{left} \leqslant x \leqslant x_{right} \\ y_{bottom} \leqslant y \leqslant y_{top} \end{matrix}\right.
{xleft⩽x⩽xrightybottom⩽y⩽ytop
则点P在矩形窗口内,太费时
直线段剪裁
- 直线段完全在窗口内
- 完全在窗口外
- 与窗口边界相交
Cohen-Sutherland 算法
对每条线段的端点都赋四位2进制码 D 3 D 2 D 1 D 0 D_{3}D_{2}D_{1}D_{0} D3D2D1D0,编码规则如下
- 若 x < x l e f t x < x_{left} x<xleft, 则 D 0 = 1 , 否 则 D 0 = 0 则D_{0}=1,否则D_{0} = 0 则D0=1,否则D0=0
- 若 x > x r i g h t x > x_{right} x>xright, 则 D 1 = 1 , 否 则 D 1 = 0 则D_{1}=1,否则D_{1} = 0 则D1=1,否则D1=0
- 若 y < y b o t t o m y < y_{bottom} y<ybottom, 则 D 2 = 1 , 否 则 D 2 = 0 则D_{2}=1,否则D_{2} = 0 则D2=1,否则D2=0
- 若 y > y t o p y > y_{top} y>ytop, 则 D 3 = 1 , 否 则 D 3 = 0 则D_{3}=1,否则D_{3} = 0 则D3=1,否则D3=0
先求出端点p1,p2的编码code1,code2,然后进行二进制或运算和与运算:
- 若code1 | code2 = 0,对应直线段应取之
- 若code1 &code2 != 0,对应线段应弃之
- 若都不满足,则按左右下上的顺序求出直线段与窗口的交点,在交点处将线段一分为二, 重复进行直到,剩下的直线段全在窗口中,取之
中点分割算法
通过二分逼近来确定直线段和窗口的交点
上文讲的Cohen-Sutherland算法一样,先对直线段点进行编码。
求中点:
- 若中点不在窗口内,则把中点合理窗口边界最远点构成的线段丢掉,以线段上的另一点和该中点再构成线段求其中点
- 若中点在窗口内,则以中点和最远点构成线段,求中点,直到中点与窗口边界的坐标值在规定的误差范围内。
Liang-Barsky算法
- (1)用参数方程表示一条直线
x = x 1 + u ⋅ ( x 2 − x 1 ) = x 1 + △ x ⋅ u y = y 1 + u ⋅ ( y 2 − y 1 ) = y 1 + △ y ⋅ u 0 ⩽ u ⩽ 1 x = x_{1} +u\cdot(x_{2} - x_{1}) = x_{1} +\triangle x\cdot u\\y = y_{1} + u\cdot(y_{2} - y_{1}) = y_{1} + \triangle y\cdot u\\ \quad 0\leqslant u \leqslant 1 x=x1+u⋅(x2−x1)=x1+△x⋅uy=y1+u⋅(y2−y1)=y1+△y⋅u0⩽u⩽1 - (2)把被裁减的红色直线段看成是一条由方向的线段,把窗口的四条边分成两类:入边和出边
如 果 用 u 1 , u 2 分 别 表 示 线 段 ( u 1 ⩽ u 2 ) 可 见 部 分 的 开 始 和 结 束 如果用u_{1},u_{2}分别表示线段(u_{1}\leqslant u_{2})可见部分的开始和结束 如果用u1,u2分别表示线段(u1⩽u2)可见部分的开始和结束
u 1 = m a x ( 0 , u l , u b ) u 2 = m i n ( 1 , u t , u r ) u_{1} = max(0,u_{l},u_{b})\\u_{2} = min(1,u_{t},u_{r}) u1=max(0,ul,ub)u2=min(1,ut,ur)