My current implementation is
function angle(a, b)
return acosd(a⋅b/(norm(a)*norm(b)))
end
But, sometimes, it throws domain error as
LoadError: DomainError with 1.0000000000000002:
acos(x) not defined for |x| > 1
Is there any inbuilt function that provides such functionality? Or is there any method to ensure that a⋅b/(norm(a)*norm(b))
stays within [-1, 1]?
1 Like
The easiest way would be
function angle(a, b)
return acosd(clamp(a⋅b/(norm(a)*norm(b)), -1, 1))
end
3 Likes
Thank you! That works perfectly!
FWIW, this post warns about the inaccuracy of the acos
formula for small angles. Example reproduced below in Julia:
using LinearAlgebra
angled1(a, b) = acosd(clamp(a⋅b/(norm(a)*norm(b)), -1, 1))
angled2(a, b) = atand(norm(cross(a,b)),dot(a,b))
θ = 5e-9 # small angle in degrees
a = [1, 0, 0]
b = [cosd(θ), sind(θ), 0]
julia> angled1(a, b)
0.0
julia> angled2(a, b)
5.0e-9
4 Likes
There’s a package for that which used arctangent of half angle (the upside is that the domain of arctangent is \mathbb{R})
https://github.com/JeffreySarnoff/AngleBetweenVectors.jl