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