How can I find the angle (from the vertical) between two points?

35 views (last 30 days)
I have two points, a blue circle and red star, and I want to find the angle between the two if a vertical line was drawn at the blue circle (see plot).
My code to make the points is below:
x1=2;
x2=5;
y1=2;
y2=4;
plot(x1,y1,'bo',x2,y2,'r*','MarkerSize',14)
xlim([0, 8])
ylim([0, 6])
I tried to compute the angle with atand like so:
atand((x1-x2)-(y1-y2))
and the output is -45. I am unsure if this is the correct method, and unsure why the value is negative.
Thank you!

Accepted Answer

Star Strider
Star Strider on 20 Jul 2022
The atan2d function is likely more accurate —
x1=2;
x2=5;
y1=2;
y2=4;
plot(x1,y1,'bo',x2,y2,'r*','MarkerSize',14)
xlim([0, 8])
ylim([0, 6])
axis('equal') % More Accurate Plot View
r2b = atan2d((y1-y2),(x1-x2))
r2b = -146.3099
b2r = atan2d((y2-y1),(x2-x1))
b2r = 33.6901
hold on
plot([x1 x2], [1 1]*y1,'--k')
plot([x1 x2],[y1 y2],'--g')
plot([1 1]*x1,[y1 y2],'--k')
hold off
text(3.5,2.5,sprintf('\\angle %.1f°',b2r))
text(2.5,3.5,sprintf('\\angle %.1f°',90-b2r))
.

More Answers (1)

Mathieu NOE
Mathieu NOE on 20 Jul 2022
hello jeremy
small typo in your code
the angle is given by :
atand((x1-x2)/(y1-y2))
and not
atand((x1-x2)-(y1-y2))
so the result here is : atand((x1-x2)/(y1-y2)) = 56.3099
It was quite obvious from the x and y unequal length of your vector that the result cannot be 45 deg.
Personnaly I also prefer to think in terms of vector so the end coodinates comes first - minus the start point coordinates
the result is the same but I feel better this way :
atand((x2-x1)/(y2-y1)) = 56.3099
yet another possibilty, when you have two vectors is to use the following code - same numerical result
x1=2;
x2=5;
y1=2;
y2=4;
plot(x1,y1,'bo',x2,y2,'r*','MarkerSize',14)
xlim([0, 8])
ylim([0, 6])
v1 = [0; 1]; % vertical line = reference
v2 = [x2-x1;y2-y1]
a = angle_btw(v1, v2) % in radians
ad = a *180/pi % in degrees
%% function to compute angle between 2 vectors
function a = angle_btw(v1, v2)
% The traditional approach to obtaining an angle between two vectors (i.e. arccos(dot(u, v) / (norm(u) * norm(v))),
% as presented in some of the other answers) suffers from numerical instability in several corner cases.
% The following code works for n-dimensions and in all corner cases (it doesn't check for zero length vectors, but that's easy to add).
% This code is adapted from a Julia implementation by Jeffrey Sarnoff (MIT license),
% in turn based on these notes by Prof. W. Kahan (page 15).
% Returns true if the value of the sign of x is negative, otherwise false.
signbit = @(x) x < 0;
u1 = v1 / norm(v1);
u2 = v2 / norm(v2);
y = u1 - u2;
x = u1 + u2;
a0 = 2 * atan(norm(y) / norm(x));
if not(signbit(a0) || signbit(pi - a0))
a = a0;
elseif signbit(a0)
a = 0.0;
else
a = pi;
end;
end

Products


Release

R2022a

Community Treasure Hunt

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

Start Hunting!