You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 11:03:36