如何将椭圆锥体拟合到一组数据?

时间:2015-05-04 03:25:20

标签: matlab regression curve-fitting ellipse best-fit-curve

我有一组三维数据(300点),可以创建一个看起来像两个锥体或椭圆体相互连接的表面。我想找到一种方法来找到该数据集的最佳拟合椭球或锥的方程。回归方法并不重要,越容易越好。我基本上需要一种方法,代码或matlab函数来计算这些数据的椭圆方程的常数。

2 个答案:

答案 0 :(得分:0)

matlab函数function addProduct(){ var isValid = true; var url = "http://zamger.etf.unsa.ba/wt/proizvodi.php?brindexa=16390"; var amount = document.form.kolicina.value; var naziv = document.form.naziv.value; var slikaurl = document.form.url.value; var validity = validateFields(naziv, slikaurl, amount); if(!validity) return false; var product = { naziv: naziv, kolicina: amount, slika: slikaurl }; var requestObject = new XMLHttpRequest(); requestObject.onreadystatechange = function(event) { if (requestObject.readyState == 4 && requestObject.status == 200) { loadProducts(); event.preventDefault(); } } requestObject.open("POST", url, true); requestObject.setRequestHeader("Content-type","application/x-www-form-urlencoded"); requestObject.send("akcija=dodavanje" + "&brindexa=16390&proizvod=" + JSON.stringify(product)); } 可以采用任意拟合表达式。需要花一些时间来确定参数,但可以完成。

您首先要创建一个fit对象,其中包含一个表示您预期形式的字符串。你需要自己设计出最符合你期望的表达方式,我将以a cone expression from the Mathworld site为例,并将其重新排列为z

fittype

如果它是一个简单的形式,那么matlab可以解决哪些是变量,哪些是系数但是有一些更复杂的东西,你可以试一试。

'fitoptions'对象包含方法的配置:根据您的数据集,您可能需要花一些时间指定上限和下限,起始值等。

ft = fittype('sqrt((x^2 + y^2)/c^2) + z_0', ...
     'independent', {'x', 'y'}, 'coeff', {'c', 'z_0'});

然后获得输出

fo = fitoptions('Upper', [one, for, each, of, your, coeffs, in, the, order, they, appear, in, the, string], ...
     'Lower', [...], `StartPoint', [...]);

警告:我已经完成了大量的2D数据集和docs状态它适用于三个但我自己没有这样做,所以上面的代码可能不起作用,检查文档以确保你'我的语法正确。

可能值得从简单的拟合表达式开始,这是线性的,这样您就可以使代码正常工作。然后将表达式换成锥形并四处游戏,直到你得到一些看起来像你期待的东西。

在你得到合适之后,一个好的技巧是你可以使用你在拟合中使用的字符串表达式上的[fitted, gof] = fit([xvals, yvals], zvals, ft, fo); 函数来评估字符串的内容,就像它是一个matlab表达式一样。这意味着您需要使用与字符串表达式中的变量和系数相同的工作空间变量。

答案 1 :(得分:0)

你也可以尝试使用fminsearch,但是为了避免落在局部最小值上,你需要一个很好的起点给定系数(尝试消除其中一些)。

以下是2D椭圆的示例:

% implicit equation
fxyc = @(x, y, c_) c_(1)*x.^2 + c_(2).*y.^2 + c_(3)*x.*y + c_(4)*x + c_(5).*y - 1; % free term locked to -1

% solution (ellipse)
c_ = [1, 2, 1, 0, 0]; % x^2, y^2, x*y, x, y (free term is locked to -1)

[X,Y] = meshgrid(-2:0.01:2);
figure(1);
fxy = @(x, y) fxyc(x, y, c_);
c = contour(X, Y, fxy(X, Y), [0, 0], 'b');
axis equal;
grid on;
xlabel('x');
ylabel('y');          
title('solution');          

% we sample the solution to have some data to fit
N = 100; % samples
sample = unique(2 + floor((length(c) - 2)*rand(1, N)));
x = c(1, sample).';
y = c(2, sample).';

x = x + 5e-2*rand(size(x)); % add some noise
y = y + 5e-2*rand(size(y));

fc = @(c_) fxyc(x, y, c_); % function in terms of the coefficients
e = @(c) fc(c).' * fc(c); % squared error function

% we start with a circle
c0 = [1, 1, 0, 0, 0];

copt = fminsearch(e, c0)

figure(2);
plot(x, y, 'rx');
hold on
fxy = @(x, y) fxyc(x, y, copt);
contour(X, Y, fxy(X, Y), [0, 0], 'b');
hold off;
axis equal;
grid on;
legend('data', 'fit');
xlabel('x');                    %# Add an x label
ylabel('y');          
title('fitted solution');

enter image description here