直线裁剪

2025年3月17日 | 阅读 7 分钟

它通过使用线段裁剪算法执行。线段裁剪算法是

  1. Cohen Sutherland 线段裁剪算法
  2. 中点细分线段裁剪算法
  3. 梁-Barsky 线段裁剪算法

Cohen Sutherland 线段裁剪算法

在算法中,首先,它检测线段是否位于屏幕内部或外部。所有线段都属于以下类别之一

  1. Visible
  2. 不可见
  3. 裁剪情况

1. 可见:如果线段位于窗口内,即线段的两个端点都位于窗口内。线段可见,将按原样显示。

2. 不可见:如果线段位于窗口外,它将不可见并被拒绝。此类线段将不会显示。如果满足以下任何一个不等式,则认为该线段不可见。设 A (x1,y2) 和 B (x2,y2) 是线段的端点。

xmin,xmax是窗口的坐标。

ymin,ymax也是窗口的坐标。
          x1>xmax
          x2>xmax
          y1>ymax
          y2>ymax
          x1<xmin
          x2<xmin
          y1<ymin
          y2<ymin

3. 裁剪情况:如果线段既不可见也不是不可见的情况。它被认为是裁剪情况。首先,根据下面给出的九个区域找到线段的类别。所有九个区域都被分配了代码。每个代码是 4 位。如果线段的两个端点都有尾部位为零,则认为该线段可见。

Line Clipping

中心区域的代码为 0000,即区域 5 被认为是一个矩形窗口。

下图显示了各种类型的线段

Line Clipping

线段 AB 是可见情况
线段 OP 是不可见情况
线段 PQ 是一条不可见的线段
线段 IJ 是裁剪候选者
线段 MN 是裁剪候选者
线段 CD 是裁剪候选者

Cohen Sutherland 线段裁剪的优点

  1. 它非常快速地计算端点,并快速拒绝和接受线段。
  2. 它可以裁剪比屏幕尺寸大得多的图片。

Cohen Sutherland 线段裁剪算法

步骤 1:计算线段两个端点的位置

步骤 2:对这两个端点执行 OR 运算

步骤 3:如果 OR 运算给出 0000
       那么
                线段被认为是可见的
       否则
          对两个端点执行 AND 运算
      如果 AND ≠ 0000
          那么线段是不可见的
        else
      And=0000
    线段被认为是裁剪情况。

步骤 4:如果线段是裁剪情况,找到与窗口边界的交点
                m=(y2-y1 )(x2-x1)

(a) 如果位 1 为“1”,则线段与矩形窗口的左边界相交
                y3=y1+m(x-X1)
                其中 X = Xwmin
                其中 Xwmin是窗口的 X 坐标的最小值

(b) 如果位 2 为“1”,则线段与右边界相交
                y3=y1+m(X-X1)
                其中 X = Xwmax
                其中 X 更多是窗口的 X 坐标的最大值

(c) 如果位 3 为“1”,则线段与底边界相交
                X3=X1+(y-y1)/m
                      其中 y = ywmin
                ywmin是窗口的 Y 坐标的最小值

(d) 如果位 4 为“1”,则线段与顶边界相交
                X3=X1+(y-y1)/m
                      其中 y = ywmax
                ywmax是窗口的 Y 坐标的最大值

Cohen-Sutherland 线段裁剪算法示例

设 R 为矩形窗口,其左下角位于 L (-3, 1),右上角位于 R (2, 6)。 找到图中端点的区域代码

Line Clipping

点 (x, y) 的区域代码是根据方案设置的
位 1 = sign (y-ymax)=sign (y-6)         位 3 = sign (x-xmax)= sign (x-2)
位 2 = sign (ymin-y)=sign(1-y)         位 4 = sign (xmin-x)=sign(-3-x)

其中

Line Clipping

所以

                A (-4, 2)→ 0001         F (1, 2)→ 0000
                B (-1, 7) → 1000         G (1, -2) →0100
                C (-1, 5)→ 0000         H (3, 3) → 0100
                D (3, 8) → 1010         I (-4, 7) → 1001
                E (-2, 3) → 0000         J (-2, 10) → 1000

我们通过测试问题中找到的区域代码,将线段放入适当的类别中。

类别 1(可见): EF 因为两个端点的区域代码都是 0000。

类别 2(不可见): IJ 因为 (1001) AND (1000) =1000(不是 0000)。

类别 3(裁剪候选): AB 因为 (0001) AND (1000) = 0000,CD 因为 (0000) AND (1010) =0000,以及 GH。 因为 (0100) AND (0010) =0000。

裁剪候选者是 AB, CD,GH。

在裁剪 AB 中,A 的代码是 0001。为了将 1 推到 0,我们裁剪与边界线 xmin=-3 的交点。 得到的交点是 I1 (-3,3Line Clipping)。 我们裁剪(不显示)AI1 和 I1 B。I1 的代码是 1001。 I1 B 的裁剪类别是 3,因为 (0000) AND (1000) 是 (0000)。现在 B 在窗口外(即它的代码是 1000),因此我们通过裁剪与线 ymax=6 的交点将 1 推到 0。得到的交点是 l2 (-1Line Clipping,6)。 因此 I2 B 被裁剪。I2 的代码是 0000。剩余的线段 I1 I2 被显示,因为两个端点都位于窗口内(即它们的代码是 0000)。

对于裁剪 CD,我们从 D 开始,因为它位于窗口外。它的代码是 1010。我们通过裁剪与线 ymax=6 的交点将第一个 1 推到 0。得到的交点 I3 是 (Line Clipping,6),它的代码是 0000。因此 I3 D 被裁剪,而剩余的线段 CI3 的两个端点都编码为 0000,因此它被显示。

对于裁剪 GH,我们可以从 G 或 H 开始,因为它们都在窗口外。G 的代码是 0100,我们通过裁剪与线 ymin=1 的交点将 1 推到 0。得到的交点是 I4 (2Line Clipping,1),它的代码是 0010。 我们裁剪 GI4 并处理 I4 H。线段 I4 H 不显示,因为 (0010) AND (0010) =0010。

使用 Cohen Sutherland 算法执行线段裁剪的程序

输出

Line Clipping
下一个主题中点细分算法