Computes the angle between pairs of 3D vectors. Accepts either
single vectors (length-3 numeric) or matrices where each row is a
vector (n x 3). Vectorized for efficient computation across time
frames.
Usage
vectorAngle(v1, v2, degrees = TRUE)
Arguments
- v1
Numeric vector of length 3 or matrix with 3 columns.
- v2
Numeric vector of length 3 or matrix with 3 columns.
- degrees
Logical. If TRUE (default), return angles in
degrees. If FALSE, return in radians.
Value
Numeric vector of angles. Length 1 for vector inputs,
or nrow(v1) for matrix inputs.
Details
The angle is computed as:
$$\theta = \arccos\left(\frac{v_1 \cdot v_2}{|v_1| |v_2|}\right)$$
The dot product is clamped to \([-1, 1]\) before applying
acos to avoid numerical issues. If either vector has zero
magnitude, the result is NA.
The result is unsigned, in \([0, 180]\): it says how far apart the two
vectors are but not which side of v1 that v2 lies on, so mirror-image
configurations (joint flexion versus hyperextension) are indistinguishable.
For the signed variant, measured about a plane normal and therefore able to
separate the two, use calculateJointAngles(..., signed = TRUE).
References
Winter DA (2009). "Biomechanics and Motor Control of Human Movement."
4th ed. Wiley.
Grood ES, Suntay WJ (1983). "A joint coordinate system for the clinical
description of three-dimensional motions: application to the knee."
Journal of Biomechanical Engineering, 105(2), 136-144.
Examples
# 90-degree angle
vectorAngle(c(1, 0, 0), c(0, 1, 0))
#> [1] 90
# Vectorized across rows
v1 <- matrix(c(1,0,0, 0,1,0), nrow = 2, byrow = TRUE)
v2 <- matrix(c(0,1,0, 0,0,1), nrow = 2, byrow = TRUE)
vectorAngle(v1, v2)
#> [1] 90 90