Finding closest circle to a general circle
1 view (last 30 days)
Show older comments
Hi,
For my research, I have to calculate three circular orbits. One original orbit and two other orbits. I have to find the most closest circle to the original circle. From visualization, it can be seen that the red circle is the closest one to original (green) cirle. But I am looking for analytical way to make conclusions on circles. Because sometimes circles become to closer to original circle, where visualization works not fine, in this case I have to decide by looking at analytical result. But I am in a doubt how to calculate analytically. I have used some methods which gives different unrelated results.
Would be nice if someone helps me to solve it:))
Green - original (3rd circle)
Red - 1st circle
Blue - 2nd circle
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1243497/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1243502/image.png)
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1243507/image.png)
From pictures may look like ellipses but orginally they are inclined circles! Figures are provided from different angles. 2D view also provided
2 Comments
Accepted Answer
Matt J
on 27 Dec 2022
Edited: Matt J
on 27 Dec 2022
Here's another possible method using pdist2. Assume we have Nx3 matrices XYZ1, XYZ2 whose rows are the points (x,y,z) on orbit 1 and orbit 2 respectively. Then,
difference=max( pdist2(XYZ1,XYZ2,'euc','Smallest',1) )
measures the largest gap between the 2 orbits. Example:
t=(0:0.5:359.5)';
XYZ1=[cosd(t),sind(t),0*t]; %radius=1, center=[0,0,0]
XYZ2=[cosd(t),sind(t),0*t]*1.1 + [0,0.1,0]; %radius=1.1, center=[0,0.1,0]
difference=max( pdist2(XYZ1,XYZ2,'euc','Smallest',1) )
plot(XYZ1(:,1), XYZ1(:,2),...
XYZ2(:,1), XYZ2(:,2)); axis equal
2 Comments
More Answers (1)
Karim
on 26 Dec 2022
You could try to fit a plane trought each circle, comput the normal of that plane. And then determine the angle between the normal of each circle and the reference circle. See below for a demonstration of the concept.
First we need a bit of code to generate a circle in 3D:
% create a circle
tht = linspace(0,2*pi,100);
Cirle_Grid = [cos(tht); sin(tht); 0*tht];
% define some rotation functions so that we can orient our circle in 3D
% space
RotX = @(t) [1 0 0; 0 cos(t) -sin(t); 0 sin(t) cos(t)];
RotY = @(t) [cos(t) 0 sin(t); 0 1 0;-sin(t) 0 cos(t)];
RotZ = @(t) [cos(t) -sin(t) 0; sin(t) cos(t) 0; 0 0 1];
% create some random oriented circles, we choose the data such that circle
% 2 will be the closest and we have a third circle which is fully random
C1x = rand;
C1y = rand;
C1z = rand;
C2x = C1x + 0.1*rand;
C2y = C1y + 0.1*rand;
C2z = C1z + 0.1*rand;
Circ1 = RotZ(C1x) * RotY(C1y) * RotX(C1z) * Cirle_Grid;
Circ2 = RotZ(C2x) * RotY(C2y) * RotX(C2z) * Cirle_Grid;
Circ3 = RotZ(rand) * RotY(rand) * RotX(rand) * Cirle_Grid;
% make a plot to see if evrything is working
figure
hold on
plot3(Circ1(1,:),Circ1(2,:),Circ1(3,:),'b')
plot3(Circ2(1,:),Circ2(2,:),Circ2(3,:),'r')
plot3(Circ3(1,:),Circ3(2,:),Circ3(3,:),'g')
hold off
grid on
view(3)
Now lets look for the circle closest to a reference circle, here let's take Circ1 as the reference circle.
% first find the normals to the circles, i included the function below
[N1,C1] = CircleNormal(Circ1);
[N2,C2] = CircleNormal(Circ2);
[N3,C3] = CircleNormal(Circ3);
% plot the circles and the normal's
figure
hold on
plot3(Circ1(1,:),Circ1(2,:),Circ1(3,:),'b')
plot3(Circ2(1,:),Circ2(2,:),Circ2(3,:),'r')
plot3(Circ3(1,:),Circ3(2,:),Circ3(3,:),'g')
quiver3(C1(1),C1(2),C1(3),N1(1),N1(2),N1(3),'b')
quiver3(C2(1),C2(2),C2(3),N2(1),N2(2),N2(3),'r')
quiver3(C3(1),C3(2),C3(3),N3(1),N3(2),N3(3),'g')
hold off
grid on
view(3)
% now determine the angles between the normals
Ang_21 = atan2(norm(cross(N2,N1)), dot(N2,N1))
Ang_31 = atan2(norm(cross(N3,N1)), dot(N3,N1))
And indeed, as we can see Ang_21 is smaller en hence is the circel which is "closest" to our reference circle :)
function [N,Center] = CircleNormal(Grid)
Center = mean(Grid,2);
Grid = Grid - repmat(Center, 1, size(Grid,2));
[U,S,V] = svd(Grid',0);
N = -1/V(end,end)*V(:,end);
end
6 Comments
See Also
Categories
Find more on Vector Fields in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!