minimum distance when a circle is beetween two points
Afficher commentaires plus anciens
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?

Réponses (3)
Image Analyst
le 27 Nov 2019
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 commentaires
Veronica Spelbrink
le 29 Mai 2020
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.
Image Analyst
le 29 Mai 2020
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.
Veronica Spelbrink
le 30 Mai 2020
Modifié(e) : Veronica Spelbrink
le 30 Mai 2020
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.
Image Analyst
le 30 Mai 2020
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);
Veronica Spelbrink
le 30 Mai 2020
Modifié(e) : Veronica Spelbrink
le 31 Mai 2020
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.
Veronica Spelbrink
le 31 Mai 2020
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
darova
le 16 Juin 2020
0 votes
try this script

Catégories
En savoir plus sur Annotations dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!