【计算机图形学】小白谈计算机图形学(三)二维图形裁剪篇之Cohen-Sutherland代码裁剪算法,中点分割裁剪算法,Liang-Barsky算法详解

引言

管中窥豹,坐井观天,自然界中有一个个窗口让我们观察她的曼妙。计算机也有这样的窗口,让我们在全部中观察局部的现象。这里我们谈谈二维图形的裁剪。

如何裁剪

假定直线段用 p 1 ( x 1 , y 1 ) p1(x1,y1) p1(x1,y1) p 2 ( x 2 , y 2 ) p2(x2,y2) p2(x2,y2)表示。直线段和剪裁窗口的可能关系:

  • 完全落在窗口内
  • 完全落在窗口外
  • 与窗口边界相交
    在这里插入图片描述

Cohen-Sutherland代码裁剪算法

基本思想

以窗口为基准进行分区,再以 D 3 D 2 D 1 D 0 D_3D_2D_1D_0 D3D2D1D0 (上下右左) 以外赋1,以内赋0的二进制形式给每个区命名,随之进行位与运算进行分析。
在这里插入图片描述

Cohen-Sutherland操作步骤

  • code1=0且code2=0,则该线段在窗口内,取之。
  • code1和code2 按位进行与运算,其结果不为0,即code1&code2≠0,则两端点必在窗口外的同一部位,弃之。
  • 都不成立,此时需要求出直线段与窗口边界的交点,在交点处把线段一分为二,其中必有一段完全在窗口以外,弃之。根据交点位置赋予新的四位编码,直到code1=0且code2=0为止。

优点:利用编码的思想,实现了对完全可见和不可见直线段的快速接受和拒绝。
缺点:部分可见查找较慢。

中点分割裁剪算法(对分法)

基本思想

同样对直线段端点进行分区编码,对前两种情况进行一样的处理。

线段和窗口有交点情况

  • 核心思想:通过二分法逼近来确定直线与窗口的交点,由于到达像素级别便不再可分,故不会无限循环下去。
    在这里插入图片描述
  • p 1 p_1 p1出发,找出离 p 1 p_1 p1最近的可见点 A A A; 从 p 2 p_2 p2出发,找出离 p 2 p_2 p2最近的可见点 B B B; A B AB AB p 1 p 2 p_1p_2 p1p2的可见部分。

缺点:代码裁剪与矢量裁剪都要计算直线段与窗口边界的交点,大量乘除运算降低执行效率

Liang-Barsky算法

Liang的初发现

  • 参数方程表示直线段
    { x = x 1 + Δ x ∗ u y = y 1 + Δ y ∗ u ( 0 ≤ u ≤ 1 ) \left\{ \begin{aligned} x& = x_1+\Delta x*u\\ y& = y_1+\Delta y*u\\ (&0\leq u\leq1) \end{aligned} \right. xy(=x1+Δxu=y1+Δyu0u1)
    在这里插入图片描述
  • 把直线段看成一条有方向的线段,把窗口分为入边(直线由窗口外向窗口内移动,即左边界和下边界)和出边(直线由窗口内向窗口外移动,即右边界和上边界)加上自身总共 6 6 6个点在这里插入图片描述

如何判断入边出边?如何判断 u u u值?

判断一条线在窗口内的部分即判断窗口内点的取值范围,接下来所有推导将都会使用到起点 p 1 ( x 1 , y 1 ) p_1(x_1,y_1) p1(x1,y1):
{ x l e f t ≤ x 1 + Δ x ∗ u ≤ x r i g h t y b o t t o m ≤ y 1 + Δ y ∗ u ≤ y t o p \left\{ \begin{aligned} &x_{left} \leq x_1+\Delta x*u \leq x_{right}\\ &y_{bottom} \leq y_1+\Delta y*u \leq y_{top} \end{aligned} \right. {xleftx1+Δxuxrightybottomy1+Δyuytop
我们得到点关于窗口四边的四个不等式,同时我们进行优化:
{ p 1 = − Δ x q 1 = x 1 − x L p 2 = Δ x q 2 = x R − x 1 p 3 = − Δ y q 3 = y 1 − y B p 4 = Δ y q 4 = y T − y 1 \left\{ \begin{aligned} &p_1 =-\Delta x &q_1=x_1-x_L\\ &p_2 =\Delta x &q_2=x_R-x_1\\ &p_3=-\Delta y &q_3=y_1-y_B\\ &p_4 =\Delta y &q_4=y_T-y_1\\ \end{aligned} \right. p1=Δxp2=Δxp3=Δyp4=Δyq1=x1xLq2=xRx1q3=y1yBq4=yTy1

u ∗ p k ≤ q k u*p_k\leq q_k upkqk

即满足上述条件就是我们寻找的点,那么我们想到当取等号即 u = q k p k u=\frac{q_k}{p_k} u=pkqk的时候,即是入边与出边四点:
在这里插入图片描述
那么如何判断入边和出边呢:由 p k p_k pk判断,这里不明白可以点击进行学习
p k < 0 p_k<0 pk<0时为入边, p k > 0 p_k>0 pk>0时为出边,所以得Liang-Barsky算法的式子
{ p 1 = − Δ x q 1 = x 1 − x L p 2 = Δ x q 2 = x R − x 1 p 3 = − Δ y q 3 = y 1 − y B p 4 = Δ y q 4 = y T − y 1 u = q k p k \left\{ \begin{aligned} &p_1 =-\Delta x &q_1=x_1-x_L\\ &p_2 =\Delta x &q_2=x_R-x_1\\ &p_3=-\Delta y &q_3=y_1-y_B\\ &p_4 =\Delta y &q_4=y_T-y_1\\ &u=\frac{q_k}{p_k} \end{aligned} \right. p1=Δxp2=Δxp3=Δyp4=Δyu=pkqkq1=x1xLq2=xRx1q3=y1yBq4=yTy1

{ u m a x = m a x ( 0 , u k ∣ p k < 0 , u k ∣ p k < 0 ) u m i n = m i n ( 1 , u k ∣ p k > 0 , u k ∣ p k > 0 ) \left\{ \begin{aligned} &u_{max}=max(0,u_{k|pk<0},u_{k|pk<0})\\ &u_{min}=min(1,u_{k|pk>0},u_{k|pk>0})\\ \end{aligned} \right. {umax=max(0,ukpk<0,ukpk<0)umin=min(1,ukpk>0,ukpk>0)
得到最大最小的值
在这里插入图片描述

Liang-Barsky算法特点

  • 直线方程参数化
  • 直线段看成有方向的
  • 把窗口的四条边分为入边和出边

超链接

如果你还想了解其他内容:
小白谈计算机图形学(一)如何画线
小白谈计算机图形学(二)如何画圆
小白谈计算机图形学(三)二维图形裁剪
小白谈计算机图形学(四)二维三维图形变换—1

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Cohen-Sutherland直线段裁剪算法是一种用于裁剪直线段的算法。它通过对直线段的端点进行编码,并利用位运算来决定是否需要进行裁剪算法的步骤如下: 1. 将裁剪窗口分为九个区域,对应于二进制编码的九个位: - 0000: 线段完全在裁剪窗口内部 - 0001: 线段与窗口左边界相交 - 0010: 线段与窗口右边界相交 - 0100: 线段与窗口下边界相交 - 1000: 线段与窗口上边界相交 - 0101: 线段与窗口左下角相交 - 1001: 线段与窗口左上角相交 - 0110: 线段与窗口右下角相交 - 1010: 线段与窗口右上角相交 2. 对直线段的两个端点进行编码,并根据编码判断线段是否需要进行裁剪。 - 如果两个端点的编码都为0000,表示线段完全在裁剪窗口内部,无需裁剪。 - 如果两个端点的编码的逻辑与运算结果不为0000,表示线段与窗口有交点,需要进行裁剪。 - 如果两个端点的编码的逻辑与运算结果为0000,表示线段与窗口无交点,且整条线段都在裁剪窗口外部,无需裁剪。 3. 如果线段需要进行裁剪,则根据需要裁剪的边界进行处理: - 如果线段与左边界相交,则根据线段方向求出相交点的坐标,并更新线段的起点。 - 如果线段与右边界相交,则根据线段方向求出相交点的坐标,并更新线段的终点。 - 如果线段与下边界相交,则根据线段方向求出相交点的坐标,并更新线段的起点。 - 如果线段与上边界相交,则根据线段方向求出相交点的坐标,并更新线段的终点。 4. 重复步骤2和步骤3,直到线段不需要裁剪或者已经被完全裁剪中点分割算法是另一种裁剪直线段的算法。它通过递归地将线段分割为左半边和右半边,并对每一半进行裁剪,直到无法再分割或者线段完全在裁剪窗口内部。 这两种算法都可以用来实现直线段的裁剪,具体选择哪种算法取决于具体的应用场景和需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一拳Marx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值