minimum distance when a circle is beetween two points

Hello,
I have a question, I have the situation like figure below, a circle and two points A and B. I want to go from point A to point B, I want a code that shows if we have such situations do : first go to A1 (which is the tangent point) then move across the circumference of the circle upto point B1, then go to point B.
How can I show this (Red) path in matlab and calculate the distance?

Risposte (3)

Simply get the x and y of the line using simple analytical equations (geometry, algebra) using the known coordinates of the center, point A, point B, and the known radius), then use plot:
plot(x, y, 'r-', 'LineWidth', 5); % Plot thick red curve.
To get the distance, you could just sum x and y segment lengths
distance = sum(sqrt(x(2:end) - x(1:end-1)) .^ 2 + (y(2:end) - y(1:end-1) .^ 2);
if you want MATLAB to do it quantitatively. Of course there is also an analytical equation using the pure mathematical equations of the lines and curve.

5 Commenti

I already have points A1 and B1 and the line segments from point A to A1 and point B1 to B, which I got using linspace, now I'm only missing the curved sections, I am computing the start angle and end angle of the arc in such a way:
center = roller_positions(:, cnt_arcs+1);
xc = center(1);
yc = center(2);
zc = center(3);
r = circle_radii(cnt_arcs+1) + rt;
p1 = points(:, n);
p2 = points(:, m);
sin_start = p1(3) - zc;
cos_start = p1(1) - xc;
sin_end = p2(3) - zc;
cos_end = p2(1) - xc;
%Here the start and end angle of the curve are computed based
%on the start and end points of the curve
start_angle = atan2(sin_start, cos_start);
end_angle = atan2(sin_end, cos_end);
th = linspace(start_angle, end_angle, 200);
% compute curve
num_angles = size(th, 2);
x_a = r * cos(th) + xc;
y_a = repmat(yc, 1, num_angles);
z_a = r * sin(th) + zc;
% compute matrix of points belonging to the arc
% p_arc = [x1 y1 z1;
% ....
% xk yk zk]'; where k is the number small linear segments that compose the arc
p_arc = [x_a; y_a; z_a];
However, I need the arc to be the shortest arc and some of the point combinations result in the longest path along the circle of radius r + rt represented with the dashed lines, like so:
where the purple dashed line circle and the dark blue dashed line circle are not the shortes arc between the points signaled in black.
I really need some help with this as I've gone into an if-else statement rampage trying to define the correct expression for each specific case, but there must be a better way.
Thanks in advance.
Well if it works, it works and I'm not sure I want to spend time finding you a "better way" when you already have a way that works, even if it's an if-else rampage.
No, I said I was "trying" to define the correct expression, I never actually found a way to make them all correct with the if-else, it's just too confusing that way...when I set the conditions some of the curves that were previously ok, became wrong, so I don't know what I was doing wrong.
OK, how can we help?
By the way, this is what your code does:
Unrecognized function or variable 'roller_positions'.
Error in test3 (line 1)
center = roller_positions(:, cnt_arcs+1);
If you're willing to help the function that computes the whole trajectory and the variables to load into the workspace are attached. plot_rollers.m is just a secondary function that plots the line and dashed line circles. You can run the trajectory.m with the inputs like so:
trajectory(circles, shapes, rt, plane_depth);
however the section of the code that I need help with is in the trajectory.m file, from line 76 to 113, which is sort of what I referenced in my first comment, where the curved segments are computed.
UPDATE: I had to change the way I was doing it to choose whether I wanted to draw the curve from point 1 to point 2 clockwise or Anti-clockwise. And now it should work. Since the code above is slightly deprecated as it wasn't functioning correctly, I will leave here the correct solution as an answer once I have it. It might be of help to someone.

Accedi per commentare.

function [X, Y, Z] = arc()
A = [1.66870803851856; 0.500000000000000; 1.22112689094119];
A1 = [0.791819441598963; 0.5; 1.03409208510982]; %your points belonging to the circle ircumference go here
B1 = [0.720451021787587; 0.5; 0.859809300488578];
B = [0.969580132133386;0.500000000000000;0.482295106876854];
r = 0.114; %your circle radius here
center = [0.8156; 0.5; 0.9226]; %your circle center here
winding_direction = 1; %direction in which you want your line to wrap around the circle, clockwise (1) or conter-clockwise (0)
xc = center(1);
yc = center(2);
zc = center(3);
%Separate the X, Y and Z components for easy plotting
P = []; %final path
Points =[A A1 B1 B];
% compute line between A and A1
x_l = linspace(A(1), A1(1), 200);
y_l = linspace(A(2), A1(2), 200);
z_l = linspace(A(3), A1(3), 200);
p_line = [x_l; y_l; z_l];
P = cat(2, P, p_line);
%compute the arc between A1 and B1
if (winding_direction == 1) %clockwise rotation
a = atan2(A1(3) - zc, A1(1) - xc);
b = atan2(B1(3) - zc, B1(1) - xc);
b = mod(b-a, 2*pi)+a; % Ensure that arc moves cw
elseif (winding_direction == 0) %counter-clockwise rotation
a = atan2(A1(3) - zc, A1(1) - xc);
b = atan2(B1(3) - zc, B1(1) - xc);
b = mod(b-a, 2*pi)+a-2*pi; % Ensure that arc moves ccw
end
t = linspace(a, b, 1000);
x_a = xc + r*cos(t);
y_a = repmat(yc, 1, 1000);
z_a = zc + r*sin(t);
p_arc = [x_a; y_a; z_a];
P = cat(2, P, p_arc);
% compute line between B1 and B
x_l = linspace(B1(1), B(1), 200);
y_l = linspace(B1(2), B(2), 200);
z_l = linspace(B1(3), B(3), 200);
p_line = [x_l; y_l; z_l];
P = cat(2, P, p_line)
num_p = size(P, 2);
X = zeros(1, num_p);
Y = zeros(1, num_p);
Z = zeros(1, num_p);
for q = 1:num_p
X(1, q) = P(1, q);
Y(1, q) = P(2, q);
Z(1, q) = P(3, q);
end
plot3(X, Y, Z, 'r-'), grid on, hold on, axis square;
plot3(Points(1,:), Points(2,:), Points(3,:), 'o', 'MarkerFaceColor', 'black');
view(180,0);
hold off
end

Richiesto:

il 27 Nov 2019

Risposto:

il 16 Giu 2020

Community Treasure Hunt

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

Start Hunting!

Translated by