Find angular components between 2 vectors

48 Views Asked by At

How to find angle between 2 vector using python, preferably numpy or scipy; in terms of components of rotation about x,y,z axes?

For example in the code below, utilizing this, we can find the angle between 2 vectors.

import numpy as np

a = np.array([5,7,5])-np.array([1,2,3])
b = np.array([3.25842, 8.14983, 4.44192])-np.array([1,2,3])

def angle(v1, v2, acute):
    angle = np.arccos(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))
    if (acute == True):
        return angle
    else:
        return 2 * np.pi - angle

print(np.rad2deg(angle(v1=a, v2=b, acute=True)))
# returns: 18.531657948873978

Desired angles are alpha_ x,y,z components.

enter image description here

1

There are 1 best solutions below

0
Nick ODell On BEST ANSWER

I would suggest using the SciPy Rotation API.

If you have two vectors, you can find the rotation between them with Rotation.align_vectors(). SciPy then gives you six choices for how to represent the rotation. (See the documentation, and the six methods beginning with as_, for a list of which output formats you can use.)

The one which seems most similar to your question is Euler angles.

Example:

from scipy.spatial.transform import Rotation
rot, rssd = Rotation.align_vectors(a, b)
print(rot.as_euler('XYZ', degrees=True))

Output:

[  6.7385178    0.60887791 -17.29830824]

Notes:

  • as_euler() accepts an order of angles, and doing the rotations in a different order can give different results. I recommend reading the Wikipedia page to understand why.
  • as_euler() gives you a choice between intrinsic and extrinsic rotation angles. Use rot.as_euler('xyz', degrees=True) for extrinsic angles.
  • The rssd variable returned by align_vectors() represents distance between vectors after the rotation. See docs for more.