如何在Processing中使用Bresenham直线算法实现网格直线绘制并解决异常
问题定位
你的Bresenham直线实现存在3处核心逻辑错误:
- 提前计算了
gradient、error参数,未考虑起止坐标交换后的delta值变化,参数完全不匹配实际绘制场景 plotLineLow、plotLineHigh的循环范围硬编码了全局的鼠标坐标变量,没有使用传入的起止坐标,当起止坐标交换后循环条件直接不成立,导致反方向直线无法绘制- 斜率大于1的高斜率场景下,
gradient、error的初始化公式错误,应该适配高斜率场景的计算逻辑,而非沿用低斜率的公式
修复方案
你可以直接使用整合版的Bresenham实现,不需要拆分高低斜率两个函数,逻辑更简洁也不容易出错:
void lineDrawing() { int x0 = mouseOldCordX, y0 = mouseOldCordY; int x1 = mouseNewCordX, y1 = mouseNewCordY; // 计算坐标差和步进方向 int deltaX = Math.abs(x1 - x0); int deltaY = Math.abs(y1 - y0); int stepX = x0 < x1 ? 1 : -1; int stepY = y0 < y1 ? 1 : -1; // 初始化误差项 int error = deltaX - deltaY; while (true) { // 绘制当前坐标点 world[x0][y0].state = selectedState; // 到达终点终止循环 if (x0 == x1 && y0 == y1) break; int doubleError = 2 * error; // 调整x坐标 if (doubleError > -deltaY) { error -= deltaY; x0 += stepX; } // 调整y坐标 if (doubleError < deltaX) { error += deltaX; y0 += stepY; } } }
如果你要保留原有拆分两个函数的结构,只要修改以下几点即可:
- 交换起止坐标后重新计算对应delta、gradient、error参数
- 将两个绘制函数的循环范围改为使用传入的起止坐标,不要使用全局鼠标变量
- 高斜率场景下gradient改为
2*deltaX,error初始值改为2*deltaX - deltaY
内容的提问来源于stack exchange,提问作者Raflow
相关产品推荐
相关产品推荐

