How to find angle between two vectors?

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

The easiest way would be

function angle(a, b)
    return acosd(clamp(a⋅b/(norm(a)*norm(b)), -1, 1))
end
2 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
3 Likes

There’s a package for that which used arctangent of half angle (the upside is that the domain of arctangent is \mathbb{R})