【问题标题】:How to create a line in a grid using Bresenham's line algorithm in Processing如何在处理中使用 Bresenham 的线算法在网格中创建一条线
【发布时间】:2021-10-17 02:38:12
【问题描述】:

我想使用 Bresenham 的 algorithm 创建一条线,但唯一有效的线是从左到右的水平线,向上的线根本不起作用,对角线向下绘制的线出现在错误的位置,线条越垂直,鼠标位置变化与绘制的线条之间的距离越大,最多为 3 个单元格。我正在使用 java 和处理库。这是所有相关 code 的链接。主要代码是这样的:

void lineDrawing()
{
  int deltaX = mouseNewCordX - mouseOldCordX, deltaY = mouseNewCordY - mouseOldCordY;
  int gradient = deltaY + deltaY, error = gradient - deltaX;

  if (abs(deltaY) < abs(deltaX))
  {
    if (mouseOldCordX > mouseNewCordX)
    {
      plotLineLow(mouseOldCordX, mouseOldCordY, deltaX, deltaY, gradient, error);
    } else 
    {
      plotLineLow(mouseNewCordX, mouseNewCordY, deltaX, deltaY, gradient, error);
    }
  } else 
  {
    if (mouseOldCordY > mouseNewCordY)
    {
      plotLineHigh(mouseOldCordX, mouseOldCordY, deltaX, deltaY, gradient, error);
    } else
    {
      plotLineHigh(mouseNewCordX, mouseNewCordY, deltaX, deltaY, gradient, error);
    }
  }
}

void plotLineLow(int x0, int y0, int deltaX, int deltaY, int gradient, int error)
{
  int yIncrease = 1;

  if (deltaY < 0)
  {
    yIncrease = -1;
    deltaY = -deltaY;
  }

  for (int x = mouseOldCordX; x <= mouseNewCordX; x += 1)
  {

    world[x][y0].state = selectedState;

    error += gradient;

    if (error >= 0)
    {
      y0 += yIncrease;
      error -= (deltaX + deltaX);
    }
  }
}

void plotLineHigh(int x0, int y0, int deltaX, int deltaY, int gradient, int error)
{
  int xIncrease = 1;

  if (deltaX < 0)
  {
    xIncrease = -1;
    deltaX = -deltaX;
  }

  for (int y = mouseOldCordY; y <= mouseNewCordY; y += 1)
  {

    world[x0][y].state = selectedState;

    error += gradient;

    if (error >= 0)
    {
      x0 += xIncrease;
      error -= (deltaY + deltaY);
    }
  }
}

【问题讨论】:

  • 不同的东西有不同的Bresenham的线图,但是最基本的需要分case,dx&gt;dydy&gt;=dx,因为累加器只在一定范围内起作用。
  • 我已将代码分为适当的情况:``` if (abs(deltaY) mouseNewCordX) { plotLineLow(mouseOldCordX, mouseOldCordY, deltaX, deltaY,梯度,误差); } else { plotLineLow(mouseNewCordX,mouseNewCordY,deltaX,deltaY,梯度,错误); } } else { if (mouseOldCordY > mouseNewCordY) { plotLineHigh(mouseOldCordX, mouseOldCordY, deltaX, deltaY, gradient, error); } else { plotLineHigh(mouseNewCordX,mouseNewCordY,deltaX,deltaY,梯度,错误); } }```
  • 我明白了。嗯,你从哪里得到初始值?
  • 我从中得到初始值: void mousePressed() { mouseOldCordX = mouseX/cellSize; mouseOldCordY = mouseY/cellSize; //world[mouseOldCordX][mouseOldCordY].state = selectedState; } void mouseReleased() { mouseNewCordX = mouseX/cellSize; mouseNewCordY = mouseY/cellSize;画线(); }
  • 不,我的意思是,错误应该初始化为一半,这样会更好。 Wikipedia 有完整的案例。 (我不知道为什么有人对你投了反对票;我认为这是一个有效的问题。)

标签: algorithm processing bresenham


【解决方案1】:

我能够使用维基百科创建一个有效的代码:

    void lineDrawing()
    {
      int xIncrease = mouseOldCordX < mouseNewCordX ? 1 : -1;  
      int yIncrease = mouseOldCordY < mouseNewCordY ? 1 : -1;
      int deltaX =  abs(mouseNewCordX - mouseOldCordX);
      int deltaY = -abs(mouseNewCordY - mouseOldCordY);
      int error = deltaX + deltaY;
    
      while (true) 
      {
        world[mouseOldCordX][mouseOldCordY].state = selectedState;
    
        if ((mouseOldCordX == mouseNewCordX) && (mouseOldCordY == mouseNewCordY)) break;
    
        int doubleError = 2 * error;
    
        if (doubleError >= deltaY) 
        { 
          error += deltaY;
          mouseOldCordX += xIncrease;
        }
    
        if (doubleError <= deltaX)
        {
          error += deltaX;
          mouseOldCordY += yIncrease;
        }
      }
    }

【讨论】:

  • 这个解决方案有什么比我的更优化的?
  • 轻微。我的每个内循环进行 2 次比较。你的 3. 通过常量而不是变量递增/递减可能会更快一些。我只是想您可能希望看到实现 Bresenham 的方法不止一种。
  • 还有一个不符合颗粒的版本,它更复杂,但速度更快,因为它一次输出多个像素。
猜你喜欢
  • 1970-01-01
  • 2018-11-04
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-15
相关资源
最近更新 更多