Я пытаюсь повернуть vector1 (красный) так, чтобы он выровнялся с vector2 (синий) в трехмерном пространстве. Однако следует использовать только вращения вокруг осей X и Z.

До сих пор я решил эту проблему, используя алгоритм оптимизации, который пытается минимизировать углы вокруг осей X и Z между векторами. В большинстве случаев это сработало довольно хорошо, но, поскольку мне приходится вычислять множество этих векторов, это слишком медленно.
Код, который я использовал для подхода к оптимизации:
vector1 = np.array([0., -1., 0.])
vector2 = np.array([0.2, -0.2, -0.5])
def find_a_c(x, *args):
vector1, vector2 = args[0], args[1]
angle_x, angle_z = x[0], x[1]
# Rotation matrices to rotate around X and Z
Rx = np.array([[1., 0., 0.],
[0., np.cos(angle_x), -np.sin(angle_x)],
[0., np.sin(angle_x), np.cos(angle_x)]])
Rz = np.array([[np.cos(angle_z), -np.sin(angle_z), 0.],
[np.sin(angle_z), np.cos(angle_z), 0.],
[0., 0., 1.]])
vector1 = vector1.dot(Rx).dot(Rz)
# calulate the angle between the vectors around X and Z
angle_x = angle_between_vectors([vector2[1], vector2[2]], [vector1[1], vector1[2]])
angle_z = angle_between_vectors([vector2[0], vector2[1]], [vector1[0], vector1[1]])
return np.abs(angle_x) + np.abs(angle_z)
solution = minimize(fun=find_a_c,
x0=[0., 0.],
args=(vector1, vector2))
angle_x, angle_z = solution.x[0], solution.x[1]
print("Angle around X: {}°\nAngle around Z: {}°".format(np.rad2deg(angle_x), np.rad2deg(angle_z)))
Распечатывает:
Angle around X: -60.46948402478365°
Angle around Z: -45.0000003467713°
Теперь я ищу аналитический подход, который решает мою проблему. Например, матрица вращения, сформированная с двумя углами поворота (вокруг X и Z), чтобы выровнять vector1 с vector2.