Issue while fitting semi-circle on a set of points

In this figure I would like to fit a semi-circle on the green curve
The ref code for plotting semi-circle is as follows
function Circ = semi_circle(xc,yc,R,flag)
theta=linspace(pi/2,-pi/2,100);
xcircle = R*cos(theta')+xc;
ycircle = R*sin(theta')+yc;
if flag
plot(xcircle,ycircle);
end
Circ=[xcircle,ycircle];
end
xc,yc and R are obtained as follows
First compute normals for left seg 1 using LineNormals2D,then project the points on left seg1 using the angles in LineNormals2D I will then look at where these projections intersect left_seg2 using InterX. The intersectin point will be the center and the distance between the center and the poin t on left seg 1 will be radius
The green points are enclosed left_seg1 and left_seg2.
Any help/suggestions will be appreciated.

 Accepted Answer

I recommend circularFit from
In addition to doing more careful data pre-normalization than the Bucher Izhak code routine, it contains methods for post-plotting the fit.
>> fobj=circularFit([left_seg,left_seg2])
fobj =
circularFit with properties:
center: [133.7487 51.8286]
radius: 4.3551
>> plot(fobj)

2 Comments

ok i will try out your method also,unfortunately i don't have to access to matlab on my personal system.I tried pratt circle fitting but the result wasn't correct because I want the circle to lie inside the boundary described by those points,as shown in the main figure.
To get it inside the points, you have to identify the 3 points that are closest to the middle. So use the original code to find the center. Then get the distances of all points to that center, then sort, and take the 3 shortest distances and fit a cirvle through only those 3 points.

Sign in to comment.

More Answers (2)

I'd suggest you use the FAQ to fit a circle through the points you have circled:
function [xCenter, yCenter, radius, a] = circlefit(x, y)
% circlefit(): Fits a circle through a set of points in the x - y plane.
% USAGE :
% [xCenter, yCenter, radius, a] = circlefit(X, Y)
% The output is the center point (xCenter, yCenter) and the radius of the fitted circle.
% "a" is an optional output vector describing the coefficients in the circle's equation:
% x ^ 2 + y ^ 2 + a(1) * x + a(2) * y + a(3) = 0
% by Bucher Izhak 25 - Oct - 1991
numPoints = numel(x);
xx = x .* x;
yy = y .* y;
xy = x .* y;
A = [sum(x), sum(y), numPoints;
sum(xy), sum(yy), sum(y);
sum(xx), sum(xy), sum(x)];
B = [-sum(xx + yy) ;
-sum(xx .* y + yy .* y);
-sum(xx .* x + xy .* y)];
a = A \ B;
xCenter = -.5 * a(1);
yCenter = -.5 * a(2);
radius = sqrt((a(1) ^ 2 + a(2) ^ 2) / 4 - a(3));

3 Comments

ok thanks i will try it and update you
Not sure what's in your mat files. It's not what you showed in your original post
s1 = load('left_seg1.mat')
s2 = load('left_seg2.mat')
x1 = s1.left_seg(1, :)
y1 = s1.left_seg(2, :)
x2 = s2.left_seg2(1, :)
y2 = s2.left_seg2(2, :)
plot(x1, y1, 'b-', 'LineWidth', 2);
hold on;
plot(x2, y2, 'r-', 'LineWidth', 2);
grid on;
oh right left seg1 and left seg 2 combine to make the green curve in the figure,I will upload the entire figure points later.

Sign in to comment.

12 Comments

That's the outside/containing/bounding circle, not the inside circle. I asked John if he had a largest inside circle and he said that, for the general case, it was not easy to do so he hadn't done it.
That's not what the doc says:
function [C,R] = incircle(x,y)
% incircle: compute the maximal in-circle of the polygonal convex hull of a set of points in the plane
%
% [C,R] = incircle(x,y)
% Called with a pair of vectors of the same length,
% incircle computes the convex hull in 2-dimensions,
% then finds the maximal radius in-circle that lies
% entirely within the polygon of the convex hull.
Hmmm....Maybe he changed it since I talked with him. I'll give it a test.
But it sounds like it finds the largest circle in the convex hull, which is the outer points, not the largest circle on the interior.
So in the above diagram it would find a circle that lies in the band of dots near the outer convex perimeter, not within the clear space of the interior.
I couldn't test it. It requires a toolbox I don't have:
Error using optimset (line 147)
No default options available: the function 'linprog' does not exist on the path.
Okay i tried both methods basically I used the circular fitting suggested by Matt and then applied image analyst's last comment.[To get it inside the points, you have to identify the 3 points that are closest to the middle. So use the original code to find the center. Then get the distances of all points to that center, then sort, and take the 3 shortest distances and fit a cirvle through only those 3 points.]
The final result is this.
Now although the circle comes in the interior,I would like to get the semi-circle and not the full circle.
That way i can then simply connect the points along the diameter which is our main objective
I have also enclosed the result by applying just the circular fit written by john
Once you have the radius and center, you can construct an arc going from the right most x to the left most x by extracting the y values above the center, then determine the starting and ending angles, and using the FAQ to construct an arc.
Hi,I have one final question.
If i was interested in plotting the chords of a circle,how would I go about that I checked the FAQs and wasn't able to find an exact match.
i came across this link
However this only gives me the two points that lie along the diameter.How can I extend this to obtain all the chords in a circle.
Matt J
Matt J on 29 Sep 2021
Edited: Matt J on 29 Sep 2021
But a circle has infinitely many chords. How is the finite subset that you want specified?
Mostly I am interested in the chords that intersect either the left curve or right curve.Secondly the chord should be perpendicular to the line passing through that point of intersection.Does that help?
Also,could you let me know if my approach to finding the diameter is correct.If i can do that then that is also sufficient .Thanks @@Matt J for replying back.
Basically I want something similar to the image shown above.This is a sample image i searched online,and not an exact representation of the data i am working on.
Well your data has a jagged perimeter but then you give an example for a perfect circle, which is not super helpful. Can you tell me where you'd draw chords, lines, and circles in this set of points. Do you have an outer circle, inner circle, fitted circle? Which circle do the chord segments end on???
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 25;
fprintf('Beginning to run %s.m ...\n', mfilename)
numPoints = 200;
angles = linspace(0, 360, numPoints);
radius = 10;
x = radius * cosd(angles);
y = radius * sind(angles);
noiseFactor = 2.0;
x = x + noiseFactor * rand(1, numPoints);
y = y + noiseFactor * rand(1, numPoints);
% Sort by angles
angles = atan2d(y, x);
[sortedAngles, sortOrder] = sort(angles, 'ascend');
y = y(sortOrder);
x = x(sortOrder);
x(end+1) = x(1);
y(end+1) = y(1);
plot(x, y, 'b-', 'LineWidth', 3);
grid on;
axis equal;
g = gcf;
g.WindowState = 'maximized'
fprintf('Done running %s.m.\n', mfilename)
Also explain this line:
"the chord should be perpendicular to the line passing through that point of intersection."
What point? Where was the point??? As you know, all chords must automatically be perpendicular to a line drawn from the center of a perfect circle, so I'm not sure what you're envisioning where this might not be the case.
Basically I want to connect the two end points that lie on the circumfrence of the circle like this.
My approach tends to fail here
Here we have two points one is the purple point and the second point is the point where the cicle intersects the red line.
However,the line that joins these two points must be perpendicular to the tangent that passes through the bottom of the circle.,and that is not happening here.So I would like to know what can I do to achieve this.
Here are a few more examples
Again in this case the angle between the black line and tangent is not 90 but somewhere between 60 and 70 degree.
Let me know if you have any doubts or if you need anything else.
In your magnified example, the black line from the top/magenta point, through the center of the circle to the bottom of the circle IS "perpendicular to the tangent that passes through the bottom of the circle". By definition, any line from the center of a circle to the perimeter of the circle is necessarily perpendicular to a tangent of the circle at the point where the line crosses the perimeter. You are not showing the line tangent to the circle but if you did, you would see that it's perpendicular to the black line through the center.
ah thanks ,is it okay if I share some more examples to get your second opinion.

Sign in to comment.

Categories

Asked:

on 22 Sep 2021

Commented:

on 30 Sep 2021

Community Treasure Hunt

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

Start Hunting!