目的
给定控制点
思路
类比贝塞尔曲线,令
表示一条以
其中
理论推导
我们希望找到一个函数
尝试令
权重性质
从曲线
令
与
的解析解
实际上,可以给出
曲线生成效果
下面是控制点坐标如下表所示时该算法生成的曲线:
代码
代码中未应用式(5)及其优化。
clear all;
controlPoints = [0, 0; 1, 2; 3, -1; 4, 3; 6, 1];
n = size(controlPoints, 1);
t = 0:0.01:n-1;
x = zeros(size(t));
y = zeros(size(t));
% 计算傅里叶系数
coeff = GetFourierCoefficient(n);
for i = 1:n
% 计算第i个控制点的权重
weight = GetFourierWeight(coeff, t, i - 1, n);
% 计算第i个控制点的x坐标
x = x + weight * controlPoints(i, 1);
% 计算第i个控制点的y坐标
y = y + weight * controlPoints(i, 2);
end
% 画出控制多边形
plot(controlPoints(:, 1), controlPoints(:, 2), 'r*');
hold on; grid on; axis equal;
% 画出拟合的曲线
plot(x, y, 'b-');
title('傅里叶级数权重法拟合曲线')
function coeff = GetFourierCoefficient(n)
if mod(n, 2) == 0
A = zeros(n / 2 + 1, n / 2 + 1);
b = zeros(n / 2 + 1, 1);
b(1) = 1;
for i = 0:n / 2
A(i + 1, :) = cospi(2 * i * (0:n / 2) / n);
end
coeff = A \ b;
else
A = zeros((n + 1) / 2, (n + 1) / 2);
b = zeros((n + 1) / 2, 1);
b(1) = 1;
for i = 0:(n - 1) / 2
A(i + 1, :) = cospi(2 * i * (0:(n + 1) / 2 - 1) / n);
end
coeff = A \ b;
end
end
function weight = GetFourierWeight(coeff, t, k, n)
if mod(n, 2) == 0
weight = coeff(1) * ones(size(t));
for i = 1:n / 2
weight = weight + coeff(i + 1) * cospi(2 * i * (t - k) / n);
end
else
weight = coeff(1) * ones(size(t));
for i = 1:(n - 1) / 2
weight = weight + coeff(i + 1) * cospi(2 * i * (t - k) / n);
end
end
end