现在有一条二次贝塞尔曲线,控制点坐标分别为: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))