我可以轻松跳过Bresenham线算法中的像素吗?

时间:2013-03-08 13:35:41

标签: algorithm optimization graphics bresenham

我有一个程序使用Bresenham's line algorithm来扫描一行中的像素。这是读取像素而不是写入像素,在我的特定情况下,阅读它们代价很高。

然而,我可以确定不需要读取一些像素范围。它看起来像这样:

Normal scan of all pixels:

*start
 \
  \
   \
    \
     \
      *end

Scan without reading all pixels:

*start
 \
  \
        - At this point I know I can skip (for example) the next 100 pixels
          in the loop. Crucially, I can't know this until I reach the gap.
     \
      *end

中间的间隙要快得多,因为我可以在不读取像素的情况下迭代像素。

但是,我能否以任何方式修改循环,直接在循环内直接向前跳转100个像素,直接计算线算法中前面100步所需的值?

2 个答案:

答案 0 :(得分:0)

Bresenhams中点算法通过总计数字差异 delta_x =(by-ay)计算从(ax,ay) - >(bx,by)的理论线开始的点的“距离” ,delta_y =(ax-bx)。

因此,如果想要跳过7个像素,则必须添加accum + = 7 * delta_x;然后除以delta_y可以检查应该在y方向上移动了多少像素并且取余数accum = accum%delta_y应该能够在正确的位置继续。

好处是算法起源于避免分裂的必要性......

免责声明:任何被告知可能需要通过半增量调整。

答案 1 :(得分:0)

您的主循环基本上类似于:

  while (cnt > 0) // cnt is 1 + the biggest of abs(x2-x1) and abs(y2-y1)
  {
    ReadOrWritePixel(x, y);

    k += n; // n is the smallest of abs(x2-x1) and abs(y2-y1)
    if (k < m) // m is the biggest of abs(x2-x1) and abs(y2-y1)
    {
      // continuing a horizontal/vertical segment
      x += dx2; // dx2 = sgn(x2-x1) or 0
      y += dy2; // dy2 = sgn(y2-y1) or 0
    }
    else
    {
      // beginning a new horizontal/vertical segment
      k -= m;
      x += dx1; // dx1 = sgn(x2-x1)
      y += dy1; // dy1 = sgn(y2-y1)
    }

    cnt--;
  }

因此,跳过一些q像素相当于以下调整(除非我在某处犯了错误):

  • cnt new = cnt old - q
  • k new =(k old + n * q)%m
  • x new = x old +((k old + n * q)/ m)* dx1 +(q - (( k old + n * q)/ m))* dx2
  • y new = y old +((k old + n * q)/ m)* dy1 +(q - (( k old + n * q)/ m))* dy2

注意/和%是整数除法和模运算符。