# rotation_matrix_from_vectors

## `rotation_matrix_from_vectors(vec1, vec2)`

Find the rotation matrix that aligns one vector to another.

Parameters:

Name Type Description Default
`vec1`
required
`vec2`
required

Returns:

Name Type Description
`R` `(2,2) or (3,3) numpy array such that R.dot(vec1) ~= vec2`
Notes

Taken from https://stackoverflow.com/questions/45142959/calculate-rotation-matrix-to-align-two-vectors-in-3d-space

The vectors do not need to be unit norm, but the output matrix will always be a pure rotation matrix; i.e., it will only align one vector in the direction of the other, without scaling it.

Examples:

``````v1 = np.random.randn(3)
# normalize
v1 = v1/np.linalg.norm(v1)
v2 = np.random.randn(3)
# normalize
v2 = v2/np.linalg.norm(v2)
R = rotation_matrix_from_vectors(v1,v2)
v1_aligned = R.dot(v1)
print(v1_aligned)
print(v2)
``````
Source code in `src/gpytoolbox/rotation_matrix_from_vectors.py`
 ``` 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64``` ``````def rotation_matrix_from_vectors(vec1, vec2): """ Find the rotation matrix that aligns one vector to another. Parameters ---------- vec1: (2,) or (3,) numpy array vec2: (2,) or (3,) numpy array Returns ------- R: (2,2) or (3,3) numpy array such that R.dot(vec1) ~= vec2 Notes ----- Taken from https://stackoverflow.com/questions/45142959/calculate-rotation-matrix-to-align-two-vectors-in-3d-space The vectors do not need to be unit norm, but the output matrix will always be a pure rotation matrix; i.e., it will only align one vector in the direction of the other, without scaling it. Examples -------- ```python v1 = np.random.randn(3) # normalize v1 = v1/np.linalg.norm(v1) v2 = np.random.randn(3) # normalize v2 = v2/np.linalg.norm(v2) R = rotation_matrix_from_vectors(v1,v2) v1_aligned = R.dot(v1) print(v1_aligned) print(v2) ``` """ # normalized a, b = (vec1 / np.linalg.norm(vec1)), (vec2 / np.linalg.norm(vec2)) dim = len(a) assert dim == len(b) # this is dimension agnostic even if it doesn't seem like it v = np.cross(a, b).flatten() if any(v): #if not all zeros then if dim==2: theta = np.arccos(np.dot(a, b)) # with correct sign if np.cross(a, b) < 0: theta = -theta R = np.array([[np.cos(theta), -np.sin(theta)], [np.sin(theta), np.cos(theta)]]) return R else: assert dim == 3 c = np.dot(a, b) s = np.linalg.norm(v) kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]]) return np.eye(3) + kmat + kmat.dot(kmat) * ((1 - c) / (s ** 2)) else: # is it a reflection? R = np.eye(dim) if np.dot(a, b) < 0: R = -R return R ``````