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

5 views (last 30 days)
Jeremy Salerno on 20 Jul 2022
Answered: Star Strider on 20 Jul 2022
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!

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 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

R2022a

### Community Treasure Hunt

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

Start Hunting!