Вот пример кода, который вращает данные 3d точки относительно случайно сгенерированной матрицы вращения, создание матрицы вращения берется из другого ответа .
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
# taken from /4201267/vraschenie-3d-vektora
def rotation_matrix(axis, theta):
"""
Return the rotation matrix associated with counterclockwise rotation about
the given axis by theta radians.
"""
axis = np.asarray(axis)
axis = axis / math.sqrt(np.dot(axis, axis))
a = math.cos(theta / 2.0)
b, c, d = -axis * math.sin(theta / 2.0)
aa, bb, cc, dd = a * a, b * b, c * c, d * d
bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
return np.array([[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
[2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
[2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc]])
# initial xyz coordinates
xs = [0, 1, 1, 1, 1, -1, -1, -1, -1]
ys = [0, 1, 1, -1, -1, 1, 1, -1, -1]
zs = [0, 1, -1, 1, -1, 1, -1, 1, -1]
atoms_initial = np.array([xs, ys, zs]).T
# specify rotation matrix parameters
# let us generate a random axis and angle for rotation
rotation_axis = np.random.uniform(low=0, high=1, size=3) # three numbers between 0 and 1
rotation_angle = np.random.uniform(low=0, high=2*np.pi, size=1) # random number between 0 and 2pi
print("Rotation axis:{}, rotation angle:{} radians".format(rotation_axis, rotation_angle))
# create our rotation matrix
rotmat = rotation_matrix(rotation_axis, rotation_angle)
# apply rotation matrix to our points
atoms_rotated = np.dot(atoms_initial, rotmat)
# draw
fig = plt.figure()
ax = Axes3D(fig)
ax.scatter(atoms_initial[:,0], atoms_initial[:,1], atoms_initial[:,2], marker='.', s=100, color='red')
ax.scatter(atoms_rotated[:,0], atoms_rotated[:,1], atoms_rotated[:,2], marker='.', s=100, color="green")
plt.show()