Finding coefficients (coordinates of center, rotation, etc.) from shape equation and data set? fitting custom equation

2 次查看(过去 30 天)
Hello good people of matlab :D
I am working on my thesis, colecting data from a 3d scanner. Loading them into the matlab and working on shape recognition, searching for center coordinants, rotation etc... It will be used for additive 3d print to an existing 3d printed object. The main idea is to place an object onto base of 160x160mm and figuring out what shape it is, what rotation and coordinants it has.
In my first task, I had a cone and by fitting its (well known) equation into Cftool I got not only coordinants of a center but also SSE etc, I have generated and adjusted the code... easy peasy. As for a cone no rotation is required.
But as for my second task, the same coefficients are wanted with an extra coeff. for rotation. The objects shape:
So bcs of covid19, I had simulated the data of shapes base in matlab from equation : Yk-a-sqrt(r^2-Xk.^2)).*(Yk+a+sqrt(r^2-Xk.^2)).*(Xk-r).*(Xk+r).*0.0002, wich I found in an answer1. on this forum here: https://math.stackexchange.com/questions/2678480/formula-for-a-stadium-shape-2d-capsule . After addition of Z data and making a figure, i was however able to get only a figure of Capsule.
So I have decided to search for center coordinants and rotation via base line of this shape :
from cf tool the model computed an complex values so it is no use :/ Even after tightening the coefficients. And there are no complex values doe. see next pic.
The next idea was to use Singular data deviation (principal component analysis) and in fact it kinda worked. However I had to use atan instead of atan2 and than compare coordinates Y on min and max values of X. to know whether it is in first or 2nd quadrant.
However if this is a right method or not, I am not sure.
I have searched and searched... maybe the solution is by using LSQNONLIN / FITNLM, they are able to work with complex values, but I have not been able to write an appropriate program.
IThe simulation of a data is skipped, my X and Y array values are in the X_and_Y.mat file.
in the code below You can see the my struggle:
clc
clear all
close all
% -------------------------------------------------------------------------%
% lsqnonlin attempt
% -------------------------------------------------------------------------%
load('X_and_Y.mat');
% Define function that the X values obey.
a = 10 % Arbitrary sample values I picked.
r = 15
Y = a^2*r^2+2*a*r^2./sqrt(r^2-X.^2-2*r^2*X.^2+r^4-2*a*X.^2./sqrt(r^2-X.^2)-a^2*X.^2+X.^4)./(r^2-X.^2);% Get a vector. No noise in this Y yet.
% Convert X and Y into a table, which is the form fitnlm() likes the input data to be in.
tbl = table(X', Y');
% Define the model as Y = a + exp(-b*x)
% Note how this "x" of modelfun is related to big X and big Y.
% x((:, 1) is actually X and x(:, 2) is actually Y - the first and second columns of the table.
modelfun = @(b,x) b(1).^2*b(2).^2+2*b(1)*b(2).^2./sqrt(b(2).^2-x.^2-2.*b(2).^2*x.^2+r.^4-2.*b(1).*x.^2./sqrt(b(2).^2-x.^2)-b(1).^2*x.^2+x.^4)./(b(2).^2-x.^2);
beta0 = [10, 15]; % Guess values to start with. Just make your best guess.
% Now the next line is where the actual model computation is done.
mdl = fitnlm(tbl, modelfun, beta0);
% Now the model creation is done and the coefficients have been determined.
% YAY!!!!
% Extract the coefficient values from the the model object.
% The actual coefficients are in the "Estimate" column of the "Coefficients" table that's part of the mode.
coefficients = mdl.Coefficients{:, 'Estimate'}
% Create smoothed/regressed data using the model:
yFitted = coefficients(1) + exp(-coefficients(2)*X);
% Now we're done and we can plot the smooth model as a red line going through the noisy blue markers.
hold on;
plot(X, yFitted, 'r-', 'LineWidth', 2);
grid on;
title('Exponential Regression with fitnlm()', 'FontSize', fontSize);
xlabel('X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
legendHandle = legend('Noisy Y', 'Fitted Y', 'Location', 'north');
legendHandle.FontSize = 25;
% Set up figure properties:
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Get rid of tool bar and pulldown menus that are along top of figure.
set(gcf, 'Toolbar', 'none', 'Menu', 'none');
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
For any help and advice I would be forever gratefull and I appreciate it in advance.
Edit:
I have come across the John D'Errico (2020) tool. A suite of minimal bounding objects (https://www.mathworks.com/matlabcentral/fileexchange/34767-a-suite-of-minimal-bounding-objects). See picture below.Looks very prommising still would like to know, which is the correct method doe.

回答(1 个)

darova
darova 2020-5-31
What about this? You can create a surface and use alphaShape to find anything you want
[x,y] = pol2cart(deg2rad(-90:10:90),10); % half arc
x = [x+5 -x-5];
y = [y flip(y)];
surf([x;3*x],[y;3*y],[x*0;x*0-20])
axis equal
  2 个评论
Lukas Vadovic
Lukas Vadovic 2020-6-1
Hi darova, thanks for your answer.
I have taken a look at yours proposition of dealing with my problem, but can not figure how exactly would you want to get rotation of object, center of object and some quality coefficients out of alphashape. Wich function you have on mind? I have chceckd and cant see any.
Thanks for any further taughts.
My attempt succeded only in reconstructing the shape, wich in real life I will have from the scanning.
see the pic. and a code.
clear all;
close all;
clc;
% Stredove suradnice X a Y
x=100;
y=100;
%/////////////////////////////////
r1=15;
r2=5;
k=0;
k1=0;
pocitadlo = 0;
zmena =0;
Coordinates_x=zeros();
Coordinates_x(1)=x+5;
Coordinates_y(1)=y-5;
Coordinates_z(1)=5;
for i =2:24
if zmena == 0
Coordinates_x(i) = x + (cosd(k) * r1);
Coordinates_y(i) = (Coordinates_y(1) - (r1*sind(k)));
Coordinates_z(i) = 0;
k=k+(180/11);
pocitadlo = pocitadlo + 1;
if pocitadlo == 2
zmena = 1
pocitadlo = 0;
continue;
end
end
if zmena == 1
k1=k1+(180/11);
Coordinates_x(i) = x + (cosd(k1) * r2);
Coordinates_y(i) = (Coordinates_y(1) - (r2*sind(k1)));
Coordinates_z(i) = 5;
pocitadlo = pocitadlo + 1;
if pocitadlo == 2
zmena = 0
pocitadlo = 0;
continue;
end
end
end
k=0;
k1=0;
zmena = 0;
pocitadlo = 0;
Coordinates_x(25)=x-5;
Coordinates_y(25)=y+5;
Coordinates_z(25) = 5;
for i =26:48
if zmena == 0
Coordinates_x(i) = x + (- cosd(k) * r1);
Coordinates_y(i) = (Coordinates_y(25) + (r1*sind(k)));
Coordinates_z(i) = 0;
k=k+(180/11);
pocitadlo = pocitadlo + 1;
if pocitadlo == 2
zmena = 1
pocitadlo = 0;
continue;
end
end
if zmena == 1
k1=k1+(180/11);
Coordinates_x(i) = x + (- cosd(k1) * r2);
Coordinates_y(i) = (Coordinates_y(25) + (r2*sind(k1)));
Coordinates_z(i) = 5;
pocitadlo = pocitadlo + 1;
if pocitadlo == 2
zmena = 0
pocitadlo = 0;
continue;
end
end
end
Coordinates_x(49) = Coordinates_x(1)
Coordinates_y(49) = Coordinates_y(1)
Coordinates_z(49) = 5;
% Suradnice v jednej premennej
Coordinates = zeros(3)
Coordinates = [Coordinates_x; Coordinates_y; Coordinates_z]
%///////////////
plot3(Coordinates_x,Coordinates_y,Coordinates_z,'-o')
xlim([x-20 x+20])
ylim([y-20 y+20])
a=[Coordinates_x' Coordinates_y' Coordinates_z'];
a = unique(a,'rows');
shp = alphaShape(a(:,1),a(:,2),a(:,3),40);
plot(shp)
darova
darova 2020-6-12
Here is the main idea:
  • convert surface to patch (to create triangles)
  • consider each triangle as tetrahedron (tetrahedron cetroid). Calculate volume of each tetrahedron
  • centroid of the whole geometry ( - volume of a tetrahedron, - centroid of a tetrahedron )
i made some calculations
Looks pretty good
Ask if something is needed
read also about static moment

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Surface and Mesh Plots 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by