How can I determine the angle between two vectors in MATLAB?
1,413 次查看(过去 30 天)
显示 更早的评论
How can I determine the angle between two vectors in MATLAB?
I have two vectors. Is there a MATLAB function that can determine the angle between them?
采纳的回答
MathWorks Support Team
2020-5-27
编辑:MathWorks Support Team
2020-5-27
There is no in-built MATLAB function to find the angle between two vectors. As a workaround, you can try the following:
CosTheta = max(min(dot(u,v)/(norm(u)*norm(v)),1),-1);
ThetaInDegrees = real(acosd(CosTheta));
7 个评论
Akihumi
2020-5-27
Hi, did you miss out a bracket for the min? I got an error and only resolve it with the following code instead.
CosTheta = max(min(dot(u,v)/(norm(u)*norm(v)),1),-1);
ThetaInDegrees = real(acosd(CosTheta));
Bruno Luong
2024-9-28
编辑:Bruno Luong
2024-9-28
This is actually incorrect for complex vectors
CosTheta = max(min(dot(u,v)/(norm(u)*norm(v)),1),-1);
ThetaInDegrees = real(acosd(CosTheta));
The correct code is
CosTheta = max(min(real(dot(u,v))/(norm(u)*norm(v)),1),-1);
ThetaInDegrees = acos(CosTheta)
更多回答(2 个)
James Tursa
2015-7-9
编辑:James Tursa
2019-1-5
This topic has been discussed many times on the Newsgroup forum ... if I looked hard enough I'm sure I could find several Roger Stafford posts from many years ago on this. E.g., here is one of them:
The basic acos formula is known to be inaccurate for small angles. A more robust method is to use both the sin and cos of the angle via the cross and dot functions. E.g.,
atan2(norm(cross(u,v)),dot(u,v));
An extreme case to clearly show the difference:
>> a = 1e-10 % start with a very small angle
a =
1e-10
>> u = 4*[1 0 0] % arbitrary non-unit vector in X direction
u =
4 0 0
>> v = 5*[cos(a) sin(a) 0] % vector different from u by small angle
v =
5 5e-10 0
>> acos(dot(u,v)/(norm(u)*norm(v))) % acos formulation does not recover the small angle
ans =
0
>> atan2(norm(cross(u,v)),dot(u,v)) % atan2 formulation does recover the small angle
ans =
1e-10
3 个评论
James Tursa
2020-2-3
To get a full circle result where "direction" of the angle is important, see this link for one possible strategy:
Bruno Luong
2022-12-3
@Felix Fischer If you want to find angles of multiple vector pairs put in matrix, use vecnorm rather than norm.
Bruno Luong
2024-9-28
编辑:Bruno Luong
2024-9-28
There is a good formula from Kahan, chap 12 of this Mindless paper, for given x and y two vectors of length(m) - in R^m, the angle theta between x and y can be computed as
nx = norm(x);
ny = norm(y);
xx = x*ny;
yy = y*nx;
a = xx-yy;
b = xx+yy;
theta = 2*atan(sqrt(sum(a.^2)/sum(b.^2)))
The advantage of this method is good stability and in case of
nx = norm(x) = ny = norm(y) (= 1, not required)
the code can be reduced to
a = x-y;
b = x+y;
theta = 2*atan(sqrt(sum(a.^2)/sum(b.^2)))
or more compactly
theta = 2*atan(sqrt(sum((x-y).^2)/sum((x+y).^2)))
% or
theta = 2*atan(norm(x-y)/norm(x+y))
The number of arithmetic operations is less than the atan2 formula in James Tursa's answer (only applied in R^3) which is numericall more stable than TMW answer using only dot product.
Note that this implementation does not have issue when b is all-0 vector. But in case both x and y are 0s - so as a and b, Kahan method returns NaN rather than 0 as with atan2. IMO NaN is mathemetically more coherent result.
Beside this degenerated case the result is in interval [0,pi].
NOTE: For complex vectors replace any statements of the form sum(u.^2) by sum(u.*conj(u)); with u being a, b, or x-y, x+y.
1 个评论
Bruno Luong
2024-10-1
Same comparison and observe the robustness
a = 1e-10 % start with a very small angle
u = 4*[1 0 0] % arbitrary non-unit vector in X direction
v = 5*[cos(a) sin(a) 0] % vector different from u by small angle
acos(dot(u,v)/(norm(u)*norm(v))) % acos formulation does not recover the small angle
atan2(norm(cross(u,v)),dot(u,v)) % atan2 formulation does recover the small angle
nu = norm(u);
nv = norm(v);
xx = u*nv;
yy = v*nu;
a = xx-yy;
b = xx+yy;
theta = 2*atan(sqrt(sum(a.^2)/sum(b.^2)))
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!