曲线拟合:在Matlab中将一些具有不同长度/点数的曲线分成三维曲线

时间:2016-04-13 13:22:38

标签: matlab 3d curve-fitting

假设我有许多不同长度的曲线(每条曲线中的点数和点距离都是变化的)。我能在3D空间中找到最适合这组线的曲线吗?

Matlab中的代码示例将不胜感激。

示例数据集:

第1条曲线有10个点。

   18.5860   18.4683   18.3576   18.2491   18.0844   17.9016   17.7709   17.6401   17.4617   17.2726
   91.6178   91.5711   91.5580   91.5580   91.5701   91.6130   91.5746   91.5050   91.3993   91.2977
   90.6253   91.1090   91.5964   92.0845   92.5565   93.0199   93.5010   93.9785   94.4335   94.8851

第二条曲线有8个点。

   15.2091   15.0894   14.9765   14.8567   14.7360   14.6144   14.4695   14.3017
   90.1138   89.9824   89.8683   89.7716   89.6889   89.6040   89.4928   89.3624
   99.4393   99.9066  100.3802  100.8559  101.3340  101.8115  102.2770  102.7296

所需的曲线可以代表这两条存在的曲线。

我一直在考虑将这些曲线作为点分散并从中排出一条线。但是我可以从许多代码片段在线获得直线。

所以我错过了某些东西,或者有人提供了一些暗示。谢谢。

1 个答案:

答案 0 :(得分:0)

很难提出一个没有更多细节的防弹解决方案,但这是一种适用于所提供的样本数据的方法。我找到了最适合所有点的线,然后参数化了最佳拟合线上的所有点。然后我分别对每个维度进行了最小二乘多项式拟合。这产生了一个三维参数曲线,似乎很适合数据。 请注意,除了多项式最小二乘法之外的曲线拟合方法可能更适合某些情况 - 只需用首选拟合函数替换polyfit和polyval。

希望这有用!

clear;
close all;

pts1=[18.5860   18.4683   18.3576   18.2491   18.0844   17.9016   17.7709   17.6401   17.4617   17.2726;
   91.6178   91.5711   91.5580   91.5580   91.5701   91.6130   91.5746   91.5050   91.3993   91.2977;
   90.6253   91.1090   91.5964   92.0845   92.5565   93.0199   93.5010   93.9785   94.4335   94.8851]';
pts2=[ 15.2091   15.0894   14.9765   14.8567   14.7360   14.6144   14.4695   14.3017;
   90.1138   89.9824   89.8683   89.7716   89.6889   89.6040   89.4928   89.3624;
   99.4393   99.9066  100.3802  100.8559  101.3340  101.8115  102.2770  102.7296]';

%Combine all of our curves into a single point cloud
X = [pts1;pts2];

%=======================================================
%We want to first find the line of best fit
%This line will provide a parameterization of the points
%See accepted answer to http://stackoverflow.com/questions/10878167/plot-3d-line-matlab

% calculate centroid
x0 = mean(X)';

% form matrix A of translated points
A = [(X(:, 1) - x0(1)) (X(:, 2) - x0(2)) (X(:, 3) - x0(3))];

% calculate the SVD of A
[~, S, V] = svd(A, 0);

% find the largest singular value in S and extract from V the
% corresponding right singular vector
[s, i] = max(diag(S));
a = V(:, i);
%=======================================================
a=a / norm(a);
%OK now 'a' is a unit vector pointing along the line of best fit.
%Now we need to compute a new variable, 't', for each point in the cloud
%This 't' value will parameterize the curve of best fit.
%Essentially what we're doing here is taking the dot product of each
%shifted point (contained in A) with the normal vector 'a'
t = A * a;

tMin = min(t);
tMax = max(t);

%This variable represents the order of our polynomial fit
%Use the smallest number that produces a satisfactory result
polyOrder = 8;

%Polynomial fit all three dimensions separately against t
pX = polyfit(t,X(:,1),polyOrder);
pY = polyfit(t,X(:,2),polyOrder);
pZ = polyfit(t,X(:,3),polyOrder);

%And that's our curve fit: (pX(t),pY(t),pZ(t))

%Now let's plot it.
tFine = tMin:.01:tMax;
fitXFine = polyval(pX,tFine);
fitYFine = polyval(pY,tFine);
fitZFine = polyval(pZ,tFine);

figure;
scatter3(X(:,1),X(:,2),X(:,3));
hold on;
plot3(fitXFine,fitYFine,fitZFine);
hold off;

Curve fit