计算贝塞尔曲线上点坐标

现在有一条二次贝塞尔曲线,控制点坐标分别为:P0(3,8),P1(2,3),P2(2,7),如果想要返回 10 个在贝塞尔曲线上的点,可以理解为将该曲线分成10端(实际是11个点组成,不过我们的逻辑是返回除最后一个点外的10个点)

如果想对贝塞尔曲线有更深入的理解,可以学习这篇文章:贝塞尔曲线的理解

给定点P0、P1,线性贝塞尔曲线只是一条两点之间的直线,公式如下:

二次贝塞尔曲线的路径由给定点P0、P1、P2构成,公式如下: 

P0、P1、P2、P3四个点在平面或在三维空间中定义了三次贝塞尔曲线,公式如下: 

 

 n阶贝贝塞尔线可如下推断。给定点P0、P1、…、Pn,其贝塞尔曲线即:

--[[**
     * @param poss      贝塞尔曲线控制点坐标
     * @param precision 精度,需要计算的该条贝塞尔曲线上的点的数目
     * @return 该条贝塞尔曲线上的点(二维坐标)
     */]]
    
local function Point(x, y)
    return { x = x, y = y }
end    

local function v2s(value )
    local restLevel = 5
    local sp = ""
    local typ = type(value)
    if typ=="string" then
        return '\"' .. value .. '\"'
    elseif typ~="table" then
        return tostring(value)
    end
    restLevel = restLevel - 1
    if restLevel<0 then
        return "..."
    end
    local nsp = sp .. "  "
    local tb = {}
    local idxs = {}
    for k, v in ipairs(tb) do
        idxs[k] = true
        tb[#tb+1] = "[" .. k .. "] = " .. v2s(v, nsp, restLevel)
    end
    for k, v in pairs(value) do
        if not idxs[k] then
            k = (type(k)=="string") and ('\"'..k..'\"') or tostring(k)
            tb[#tb+1] = "[" .. k .. "] = " .. v2s(v, nsp, restLevel)
        end
    end
    if not tb[1] then
        return "{}"
    end
    nsp = "\n" .. nsp
    return "{"..nsp .. table.concat(tb, ","..nsp) .. "\n" .. sp .. "}";
end

function bezierCalculate(poss, precision) 

    --维度,坐标轴数(二维坐标,三维坐标...)
    local dimersion = 2

    -- 贝塞尔曲线控制点数(阶数)
    local number = #poss

    --控制点数不小于 2 ,至少为二维坐标系
    if (number < 2 or dimersion < 2) then
        return nil
    end

    local result = {}

    --计算杨辉三角
    local mi = {};
    mi[0] = 1
    mi[1] = 1
    for i = 3, number, 1 do
        local t = {}
        for j = 0, i-2, 1 do
            t[j] = mi[j]
        end

        mi[0] = 1
        mi[i - 1] = 1

        for j = 0, i-3, 1 do
            mi[j + 1] = t[j] + t[j + 1]
        end
    end

    --计算坐标点
    for i = 0, precision-1, 1 do
        local t = i / precision;
        local p = Point(0, 0);
        table.insert(result, p)

        for j = 0, dimersion-1, 1 do
            local temp = 0.0;
            for k = 0, number-1, 1 do
                local sNum = 1
                if j == 0 then
                    sNum = poss[k + 1].x
                else
                    sNum = poss[k + 1].y
                end
                temp = temp + math.pow(1 - t, number - k - 1) *sNum * math.pow(t, k) * mi[k]
            end

            if j == 0 then
                p.x = temp
            else
                p.y = temp
            end
        end

   
        p.x = math.floor(p.x);
        p.y = math.floor(p.y);
    end
    return result;
end

local temp = {
    {
        x = 0,
        y = 0
    },
    {
        x = 3,
        y = 8
    },
    {
        x = 10,
        y = 10
    },

}
local result = bezierCalculate(temp, 4)
print("wwwwwwwwwww", v2s(result))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值