Angle between two vectors matlab
Asked Answered
P

6

7

I want to calculate the angle between 2 vectors V = [Vx Vy Vz] and B = [Bx By Bz]. is this formula correct?

VdotB = (Vx*Bx + Vy*By + Vz*Bz)

 Angle = acosd (VdotB / norm(V)*norm(B))

and is there any other way to calculate it?

My question is not for normalizing the vectors or make it easier. I am asking about how to get the angle between this two vectors

Poseidon answered 20/8, 2013 at 8:32 Comment(2)
Seems to be more of a math question than a programming question.Saez
Depending on your language, you should add parentheses to make sure the product is evaluated before the division. If evaluated from left to right, this wouldn't be correct.Webbed
S
18

Based on this link, this seems to be the most stable solution:

atan2(norm(cross(a,b)), dot(a,b))
Saez answered 20/8, 2013 at 8:39 Comment(2)
That's why I am confused and I don't know which one is the correct one and whyPoseidon
Just read more via the link I provided. They are both correct in theory, but in practice this one is mentioned to provide more stable results (whilst the alternative with acos computes a bit faster).Saez
A
2

There are a lot of options:

a1 = atan2(norm(cross(v1,v2)), dot(v1,v2))
a2 = acos(dot(v1, v2) / (norm(v1) * norm(v2)))
a3 = acos(dot(v1 / norm(v1), v2 / norm(v2)))
a4 = subspace(v1,v2)

All formulas from this mathworks thread. It is said that a3 is the most stable, but I don't know why.

For multiple vectors stored on the columns of a matrix, one can calculate the angles using this code:

% Calculate the angle between V (d,N) and v1 (d,1)
% d = dimensions. N = number of vectors
% atan2(norm(cross(V,v2)), dot(V,v2))
c = bsxfun(@cross,V,v2);
d = sum(bsxfun(@times,V,v2),1);%dot
angles = atan2(sqrt(sum(c.^2,1)),d)*180/pi;
Aril answered 29/4, 2016 at 13:16 Comment(0)
N
1

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). See notes below.

% Get angle between two vectors
function a = angle_btw(v1, v2)

    % 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

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

Negrito answered 20/1, 2022 at 16:40 Comment(0)
D
0

You can compute VdotB much faster and for vectors of arbitrary length using the dot operator, namely:

VdotB = sum(V(:).*B(:));

Additionally, as mentioned in the comments, matlab has the dot function to compute inner products directly.

Besides that, the formula is what it is so what you are doing is correct.

Diffuse answered 20/8, 2013 at 8:35 Comment(4)
If you want to be concise at least recommend V*B'Saez
Is there some reason you have avoided the intrinsic dot function ?Cheder
@HighPerformanceMark Not apart from forgetting its existence.Diffuse
no there is no reason and the dot function works very well but just I wrote the question like this.Poseidon
E
0

This function should return the angle in radians.

function [ alpharad ] = anglevec( veca, vecb )
% Calculate angle between two vectors
alpharad = acos(dot(veca, vecb) / sqrt( dot(veca, veca) * dot(vecb, vecb)));
end

anglevec([1 1 0],[0 1 0])/(2 * pi/360) 
>> 45.00
Endomorphism answered 29/3, 2015 at 23:29 Comment(0)
R
0

The solution of Dennis Jaheruddin is excellent for 3D vectors, for higher dimensional vectors I would suggest to use:

acos(min(max(dot(a,b)/sqrt(dot(a,a)*dot(b,b)),-1),1))

This fixes numerical issues which could bring the argument of acos just above 1 or below -1. It is, however, still problematic when one of the vectors is a null-vector. This method also only requires 3*N+1 multiplications and 1 sqrt. It, however also requires 2 comparisons which the atan method does not need.

Rosary answered 8/1, 2020 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.