Skip to content

An accurate and stable calculation of the angle separating two vectors.

License

Notifications You must be signed in to change notification settings

JeffreySarnoff/AngleBetweenVectors.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

138 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AngleBetweenVectors.jl

When computing the arc separating two cartesian vectors, this is robustly stable; others are not.


Copyright © 2018-2022 by Jeffrey Sarnoff.    This work is released under The MIT License.

Build Status Coverage Status DOI

preferred citiation
Sarnoff, Jeffrey (2022). AngleBetweenVectors (Version 0.3.1) [Source Code].
Open access at  https://github.com/JeffreySarnoff/AngleBetweenVectors.jl
https://doi.org/10.5281/zenodo.6745689

AngleBetweenVectors exports angle. angle(point1, point2) determines the angle of their separation. The smaller of the two solutions is used. π obtains If the points are opposed, [(1,0), (-1,0)]; so 0 <= angle(p1, p2) <= pi.

This function expects two points from a 2D, 3D .. ManyD space, in Cartesian coordinates. Tuples and Vectors are handled immediately (prefer Tuples for speed). To use another point representations, just define a Tuple constructor for it. NamedTuples and SVectors have this already.

Most software uses acos(dot(p1, p2) / sqrt(norm(p1) norm(p2)) instead. While they coincide often; it is exceedingly easy to find cases where angle is more accurate and then, usually they differ by a few ulps. Not always.


provides

  • angle( point₁, point₂ )
    • points are given as Cartesian coordinates
    • points may be of any finite dimension >= 2
    • points may be any type with a Tuple constructor defined

point representations that just work

  • points as Tuples
  • points as NamedTuples
  • points as Vectors
  • points as SVectors (StaticArrays)

working with other point representations

Just define a Tuple constructor for the representation. That's all.

# working with this?
struct Point3D{T}
    x::T
    y::T
    z::T
end

#  define this:
Base.Tuple(a::Point3D{T}) where {T} = (a.x, a.y, a.z)

#  this just works:
angle(point1::Point3D{T}, point2::Point3D{T})  where {T}

why use it

This implementation is more robustly accurate than the usual method.

You can work with points in 2D, 3D, .. 1000D .. ?.


notes

  • The shorter of two angles is given as an unoriented magnitude (0 <= radians < π).

  • Vectors are given by their Cartesian coordinates in 2D, 3D or .. N-dimensions.

  • This follows a note by Professor Kahan Computing Cross-Products and Rotations (pg 15):

"More uniformly accurate .. valid for Euclidean spaces of any dimension, it never errs by more than a modest multiple of ε."

About

An accurate and stable calculation of the angle separating two vectors.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages