Got Questions? Get Answers.
Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Fitting a circle on measuring points

Subject: Fitting a circle on measuring points

From: Nicolaj Baramsky

Date: 8 Aug, 2010 12:38:05

Message: 1 of 9

Hey Guys,

my situation: I have a couple of thousends of data pairs which should be placed on a circle. Well at least a few of them.

Lets say, I measured a distance of 1 mm of the surface of a cylinder (d=10mm) which has defects (about 80%) on its surface in the middle of the measured distance. I have about 10k data pairs.

The problem is, that the x and y values of the data pairs are set anywhere in space, dependent on how I adjusted the measuring gadget.

The aim is to calculate the difference of volume from the intact cylinder to the cylinder with defects. But the defects are too small for getting them in another method, like weighing.

>>>> First question: How do i get the best fitting 10 mm circle on the datapairs at the edges of my measured data? What is your idea?

It doesn't work by constructing a lot of perpendicular bisector of the sides and let them cross each other, so I get a lot of middle points of the circle (which i have to average afterwards), because the lines are too close to each other, so the crossing points are wide spread, too wide for a proper average.

My next idea is to interpolate a function which is best a circle function.
>>>> How can I interpolate my own "type" of function (no polynome, no sin or cos, but a circle function) with my data?


Thanks for every comment on that!

Regards from Hamburg,
Nicolaj

Subject: Fitting a circle on measuring points

From: Miroslav Balda

Date: 8 Aug, 2010 14:11:04

Message: 2 of 9

"Nicolaj Baramsky" <nicolaj.baramskyREMOVETHIS@tu-harburg.de> wrote in message <i3m8fd$38u$1@fred.mathworks.com>...
> Hey Guys,
>
> my situation: I have a couple of thousends of data pairs which should be placed on a circle. Well at least a few of them.
>
> Lets say, I measured a distance of 1 mm of the surface of a cylinder (d=10mm) which has defects (about 80%) on its surface in the middle of the measured distance. I have about 10k data pairs.
>
> The problem is, that the x and y values of the data pairs are set anywhere in space, dependent on how I adjusted the measuring gadget.
>
> The aim is to calculate the difference of volume from the intact cylinder to the cylinder with defects. But the defects are too small for getting them in another method, like weighing.
>
> >>>> First question: How do i get the best fitting 10 mm circle on the datapairs at the edges of my measured data? What is your idea?
>
> It doesn't work by constructing a lot of perpendicular bisector of the sides and let them cross each other, so I get a lot of middle points of the circle (which i have to average afterwards), because the lines are too close to each other, so the crossing points are wide spread, too wide for a proper average.
>
> My next idea is to interpolate a function which is best a circle function.
> >>>> How can I interpolate my own "type" of function (no polynome, no sin or cos, but a circle function) with my data?
>
>
> Thanks for every comment on that!
>
> Regards from Hamburg,
> Nicolaj

Hi Nicolaj,
Maybe that the FEX file ID 22642 could help you.
Mira

Subject: Fitting a circle on measuring points

From: Jan Simon

Date: 8 Aug, 2010 18:39:05

Message: 3 of 9

Dear Nicolaj,

there are some further circle fit functions in the FEX. Just search for "circle fit".

Kind regards from Heidelberg, Jan

Subject: Fitting a circle on measuring points

From: Nicolaj Baramsky

Date: 9 Aug, 2010 08:06:05

Message: 4 of 9

Thanks for your answers! This is a good beginning.

I looked through all of this methods, but it seems they all give me the "best fitting circle" into my data, so they return the "best" radius.
I need to find the best fitting location for a circle with a fixed radius.
It is not possible for me to integrate that into one of the curce fitting algorithms (like Taubin).

Can you give me a hint?

Thanks a lot!

Nicolaj

Subject: Fitting a circle on measuring points

From: Miroslav Balda

Date: 9 Aug, 2010 21:08:19

Message: 5 of 9

"Nicolaj Baramsky" <nicolaj.baramskyREMOVETHIS@tu-harburg.de> wrote in message <i3octd$66$1@fred.mathworks.com>...
> Thanks for your answers! This is a good beginning.
>
> I looked through all of this methods, but it seems they all give me the "best fitting circle" into my data, so they return the "best" radius.
> I need to find the best fitting location for a circle with a fixed radius.
> It is not possible for me to integrate that into one of the curce fitting algorithms (like Taubin).
>
> Can you give me a hint?
>
> Thanks a lot!
>
> Nicolaj

Hi Nicolaj,
Your task could be solved by the following code:
----------------------------------------------

% Nicolaj.m
% Needs FEX functions:
% www.mathworks.com/matlabcentral/fileexchange/9033
% www.mathworks.com/matlabcentral/fileexchange/9035
% www.mathworks.com/matlabcentral/fileexchange/17534

close all
err = inp('error ',0.1); % measuremet error
cp = inp('Center',[2,1]); % Center point
                            % Generate data:
r = 3;
phi = 2*pi/10*(0:9)';
XY = [cos(phi), sin(phi)]*r;
xy = XY + ones(length(phi),1)*cp + randn(length(phi),2)*err;
                            % residuals:
r2 = r*r;
res = @(p) (xy(:,1)-p(1)).^2 + (xy(:,2)-p(2)).^2 - r2;

[p,ssq,cnt] = LMFnlsq(res,rand(2,1),'Display',-1)

fig(4);
plot(xy(:,1),xy(:,2),'o'); hold on; grid
XY = XY + ones(length(phi),1)*p';
plot(XY(:,1),XY(:,2),'*r');
plot(cp(1),cp(2),'xb', p(1),p(2),'hr')

axis equal
----------------------------------------------
with one of solutions:

>> Nicolaj
          error = 0.1000 =>
          Center = 2.0000 ... 1.0000 =>
******************************************************************* itr nfJ SUM(r^2) x dx
******************************************************************* 0 1 8.1157e+002 2.7219e-001 0.0000e+000
                        1.9881e-001 0.0000e+000
   1 2 3.8459e+001 1.6296e+000 -1.3574e+000
                        8.3130e-001 -6.3248e-001
   2 3 2.1078e+000 2.0275e+000 -3.9789e-001
                        1.0218e+000 -1.9050e-001
   3 4 2.0892e+000 2.0366e+000 -9.1278e-003
                        1.0265e+000 -4.6802e-003
 
   4 5 2.0892e+000 2.0366e+000 -1.6348e-005
                        1.0265e+000 -8.5803e-006
p =
    2.0366
    1.0265
ssq =
    2.0892
cnt =
     4

It is obvious that the solution has been reached in 4 iterations, in which the sum of squares of residuals dropped down by 2 orders. The plotted results are quite good.

Hope it helps.

Mira

Subject: Fitting a circle on measuring points

From: Nicolaj Baramsky

Date: 10 Aug, 2010 09:52:04

Message: 6 of 9

Thank you very much!!

Nicolaj

Subject: Fitting a circle on measuring points

From: Nicolaj Baramsky

Date: 10 Aug, 2010 14:58:05

Message: 7 of 9

The program works very fine for one single calculation.
Do I have to set a couple of vars back before i start the routine again?

I have a Matrix which contains four rows of pairs of data:

xy = [
x11 y11 x21 y21 x31 y31 x41 y41
x12 y12 x22 y22 x32 y32 x42 y42
x13 y13 x23 y23 x33 y33 x43 y43
x13 y14 x24 y24 x34 y34 x44 y44
]

soemthing like that.
I want to finde the middle points for each row with the following code:
(durchmesser = diameter; mittelpunkt = middle point)

mittelpunkte = zeros(4,2);
ssqs = zeros(4,1);

err = 0.002;
cp = [0.8,-4.9];
r2 = 5;
for i =1:4
    j=2*i-1;
    res = @(p) (xy(:,j)-p(1)).^2 + (xy(:,j+1)-p(2)).^2 - r2;
    [p,ssq,cnt] =LMFnlsq(res,[-1;-5],'Display',-1,'xTol',1e-8,'FunTol',1e-8);
    mittelpunkte(i)=p(1);
    mittelpunkte(i+4)=p(2);
    ssqs(i)=ssq;
end



But the result is, that only the calculation of the first row the iteration works fine:

The middle points are (x and y cooridnates)
   0.368374615862839 -4.977713121786886
   0.867764471106047 -4.914736713757876
   0.866466160216724 -4.913231160578434
   0.864868475942583 -4.911810869157897

SSQ for earch iterations are:
   0.000481104234919 <--- see the huge difference to the other ones!
   0.023268759661560
   0.020660058447488
   0.021206672812456



What did i forget?
Making more steps for the iterations changes nothing. So it must be a kind of initial problem.


Thanks a lot!
Nicolaj









*************************************************
  itr nfJ sum(r^2) x dx
*************************************************
   0 1 3.3770e+003 -1.0000e+000 0.0000e+000
                       -5.0000e+000 0.0000e+000
   1 2 6.8409e+002 3.5038e-001 -1.3504e+000
                       -5.1610e+000 1.6102e-001
   2 3 2.1454e-001 3.6805e-001 -1.7673e-002
                       -4.9810e+000 -1.8001e-001
   3 4 4.8113e-004 3.6837e-001 -3.2410e-004
                       -4.9777e+000 -3.3010e-003
   4 5 4.8110e-004 3.6837e-001 -1.0901e-007
                       -4.9777e+000 -1.1111e-006
 
   5 6 4.8110e-004 3.6837e-001 -2.9573e-011
                       -4.9777e+000 2.4418e-012

*************************************************
  itr nfJ sum(r^2) x dx
*************************************************
   0 1 5.6133e+003 -1.0000e+000 0.0000e+000
                       -5.0000e+000 0.0000e+000
   1 2 2.5388e+003 8.6903e-001 -1.8690e+000
                       -5.2638e+000 2.6379e-001
   2 3 2.6187e+000 8.6781e-001 1.2231e-003
                       -4.9263e+000 -3.3751e-001
   3 4 2.3272e-002 8.6776e-001 4.1860e-005
                       -4.9148e+000 -1.1529e-002
   4 5 2.3269e-002 8.6776e-001 4.6656e-008
                       -4.9147e+000 -1.3483e-005
 
   5 6 2.3269e-002 8.6776e-001 -1.8488e-010
                       -4.9147e+000 -2.0236e-011

*************************************************
  itr nfJ sum(r^2) x dx
*************************************************
   0 1 5.6365e+003 -1.0000e+000 0.0000e+000
                       -5.0000e+000 0.0000e+000
   1 2 2.5298e+003 8.6764e-001 -1.8676e+000
                       -5.2617e+000 2.6169e-001
   2 3 2.5989e+000 8.6650e-001 1.1326e-003
                       -4.9247e+000 -3.3695e-001
   3 4 2.0664e-002 8.6647e-001 3.8629e-005
                       -4.9132e+000 -1.1491e-002
   4 5 2.0660e-002 8.6647e-001 4.4456e-008
                       -4.9132e+000 -1.3394e-005
 
   5 6 2.0660e-002 8.6647e-001 1.7052e-010
                       -4.9132e+000 -1.4988e-011

*************************************************
  itr nfJ sum(r^2) x dx
*************************************************
   0 1 5.6576e+003 -1.0000e+000 0.0000e+000
                       -5.0000e+000 0.0000e+000
   1 2 2.5192e+003 8.6592e-001 -1.8659e+000
                       -5.2596e+000 2.5956e-001
   2 3 2.5791e+000 8.6490e-001 1.0213e-003
                       -4.9233e+000 -3.3629e-001
   3 4 2.1210e-002 8.6487e-001 3.4814e-005
                       -4.9118e+000 -1.1445e-002
   4 5 2.1207e-002 8.6487e-001 3.9691e-008
                       -4.9118e+000 -1.3289e-005
 
   5 6 2.1207e-002 8.6487e-001 8.9575e-011
                       -4.9118e+000 -1.1246e-011

Subject: Fitting a circle on measuring points

From: Nicolaj Baramsky

Date: 10 Aug, 2010 15:03:05

Message: 8 of 9

I should add:

The iteration works fine for all data! When i change the second row with the first row, all works fine for the new first row.

So it is no problem of the data also.

Subject: Fitting a circle on measuring points

From: Miroslav Balda

Date: 10 Aug, 2010 20:34:04

Message: 9 of 9

"Nicolaj Baramsky" <nicolaj.baramskyREMOVETHIS@tu-harburg.de> wrote in message <i3rpdt$at3$1@fred.mathworks.com>...
SNIP

> mittelpunkte = zeros(4,2);
> ssqs = zeros(4,1);
>
> err = 0.002;
> cp = [0.8,-4.9];
> r2 = 5;
> for i =1:4
> j=2*i-1;
> res = @(p) (xy(:,j)-p(1)).^2 + (xy(:,j+1)-p(2)).^2 - r2;
> [p,ssq,cnt] =LMFnlsq(res,[-1;-5],'Display',-1,'xTol',1e-8,'FunTol',1e-8);
> mittelpunkte(i)=p(1);
> mittelpunkte(i+4)=p(2);
> ssqs(i)=ssq;
> end

SNIP

The code looks strange. You defined mittelpunkte as a matrix 4x2, however you
address it as if it were a vector. I thing, that the proper code of the cycle could be as it follows (it has not been tested):

j=1:2:size(mittelpunkte,2);
for i =1:4
    res = @(i,p) (xy(i,j)-p(1))'.^2 + (xy(i,j+1)-p(2))'.^2 - r2;
    [p,ssqs(i),cnt] =LMFnlsq(res,[-1;-5],'Display',-1,'xTol',1e-8,'FunTol',1e-8);
    mittelpunkte(i,:) = p';
end

Since all 4 rows are giving virtually the same result, it could be solved as a single problem for getting an average center point:

xy = [......];
r = ......;
r2 = r*r;
XY = xy';
XY = XY(:);
i = 1:2:length(XY);
res = @(p) (XY(i)-p(1)).^2 + (XY(i+1)-p(2)).^2-r2;
[mittelpunkte,ssqs,cnt] =LMFnlsq(res,[-1;-5],'Display',-1,'xTol',1e-8,'FunTol',1e-8);

If the data are well spread, the initial guess fo the solution can be set before calling the function LMFnlsq by a command:

p0 = [mean(XY(i));mean(XY(i+1))];

I hope that there is no error.
Best regards.

Mira

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us