Liang-Barsky算法的原理与代码
Liang-Barsky裁剪算法
原理
- 用参数方程表示一条直线,用方程表示直线$P_{1}P_{2}$,其中$t$就是直线的斜率,$\mathrm{t} \in[0,1]:$
$$ \begin{equation}
\left\{
\begin{aligned}
x(t)=x_{1}+\left(x_{2}-x_{1}\right) t&=x_{1}+t \Delta x \qquad 0<t<1 \\
y(t)=y_{1}+\left(y_{2}-y_{1}\right) t&=y_{1}+t \Delta y \qquad 0<t<1
\end{aligned}
\right.
\end{equation} $$
$$\begin{aligned}
&x_{L}<x<x_{R}\
&y_{B}<y<y_{T}
\end{aligned}$$
把直线方程代入得到不等式:
$$ \begin{equation}
\left\{
\begin{aligned}
& -t \Delta x<x_{1}-x_{L} & t \Delta x<x_{R}-x_{1} \\
& -t \Delta y<y_{1}-y_{B} & t \Delta y<y_{T}-y_{1}
\end{aligned}
\right.
\end{equation} $$
即
$$t d_{i}<q_{i} \quad i=1,2,3,4$$
$$\begin{array}{llll}
d_{1}=-\Delta x & d_{2}=\Delta x & d_{3}=-\Delta y & d_{4}=\Delta y \\
q_{1}=x_{1}-x_{L} & q_{2}=x_{R}-x_{1} & q_{3}=y_{1}-y_{B} & q_{4}=y_{T}-y_{1}
\end{array}$$
- 把被裁剪的红色直线段看成是一条有方向的线段,把窗口的四条边分成两类:
入边:左边界和下边界——从裁剪框外向裁剪框内
出边:右边界和上边界——从裁剪框内向裁剪框外 - 分情况讨论
- $ d=0 :$
$ q<0 $, 说明直线与裁剪框平行,并且位于裁剪框的外面,直线为不可见,可抛弃,直接结束;
$ q\geq0 $,说明直线在它所平行的窗口边界的内部,还需进一步计算确定直线是否在窗口内、外、或者相交 - $ d<0 $,说明直线是从裁剪边界的外部延伸到内部
- $ d>0 $, 说明直线是从裁剪边界的内部延伸到外部
对于$ d\neq0 $,可以利用式子计算直线与边界k的交点的参数$ u $。对于每条直线,可以计算直线位于裁剪窗口内线段的参数$ d_1 $和$ d_2 $.
$ d_1 $的值是由那些使得直线是从外部延伸到内部的窗口边界决定。对于这些边计算$ r_i=q_i/d_i $,$ d_i= max(r_i,0) $.
$ d_2 $的值是由那些使得直线是从内部延伸到窗口边界决定,$ d_2=min(r_i,1) $.
如果$ d_1 $$ d_2 $这条直线完全在窗口的外面,不可见,可抛弃,否则,根据参数$ u $的两个值,计算出裁剪后线段的端点.
代码
代码的思路:画一个矩形,来作为一个裁剪窗口,然后画一条黄色的直线。如果直线没有经过矩形区域,则为黄色,如果穿过矩形区域,则使用Liang-Barskey算法来进行裁剪,裁剪之后,再进行画一条黑色的直线来覆盖。
1 | /*liang-barsky.cpp*/ |