如何通过Bresenham抛物线算法获取抛物线点?(Lua实现问题)
Bresenham抛物线算法修正方案
原代码存在的问题
- 未使用
x0, y0起点参数,绘制起点逻辑错误 - 误差项
p的初始值不符合Bresenham算法的推导逻辑 - 直接计算抛物线的精确y值,未通过误差累积选择最优像素,无法保证曼哈顿距离步长的要求
- 缺少
deltaYmax垂直绘制范围的限制支持
修正后的实现代码
-- 辅助函数:向像素列表添加点 local function setPixel(pixels, x, y) table.insert(pixels, {x = x, y = y}) end function getParabolaBresenham(x0, y0, a, b, c, deltaXmax, deltaYmax) local pixels = {} -- 初始化当前坐标为起点 local x = x0 local y = y0 -- 强制起点贴合抛物线(若起点偏离可根据需求调整此逻辑) local expectedY = a * x * x + b * x + c if y ~= expectedY then y = expectedY end setPixel(pixels, x, y) -- 初始化Bresenham误差项,基于抛物线离散化推导 local p = 2 * a * x + b deltaXmax = deltaXmax or math.huge deltaYmax = deltaYmax or math.huge while math.abs(x - x0) <= deltaXmax and math.abs(y - y0) <= deltaYmax do -- 根据抛物线开口方向确定y步长 local yStep = a > 0 and 1 or -1 local nextX = x + 1 local nextY1 = y local nextY2 = y + yStep -- 计算两个候选点到抛物线的误差,选择更接近的像素 local err1 = math.abs(nextY1 - (a * nextX * nextX + b * nextX + c)) local err2 = math.abs(nextY2 - (a * nextX * nextX + b * nextX + c)) if err1 <= err2 then x = nextX y = nextY1 p = p + 2 * a else x = nextX y = nextY2 p = p + 2 * a - 2 * math.abs(a) * 2 end setPixel(pixels, x, y) end return pixels end
关键修正说明
- 起点参数利用:直接从
x0,y0开始绘制,若起点不在抛物线上,强制修正到抛物线上(可根据需求调整逻辑) - 误差项正确推导:基于抛物线方程的离散化误差,每步选择曼哈顿距离最近的像素,保证步长符合需求
- 双向范围限制:同时支持
deltaXmax(水平范围)和deltaYmax(垂直范围),超出任一限制则停止绘制 - 适配抛物线开口方向:根据
a的正负自动调整y方向的步长,支持开口向上/向下的抛物线
内容的提问来源于stack exchange,提问作者darkfrei
相关产品推荐
相关产品推荐

