下面的代码就是这样做的:
from mpl_toolkits import mplot3d
import numpy as np
from pyquaternion import Quaternion
import matplotlib.pyplot as plt
fig = plt.figure()
ax = plt.axes(projection="3d")
# draw vector
world_up = [0, 0, 0, 0, 0, 1]
local_up = [0, 0, 0, 1, 1, 1]
ax.quiver(*world_up, color='r')
ax.quiver(*local_up, color='b')
def normalize(vec):
normalized_v = vec / np.linalg.norm(vec)
return normalized_v
vector1 = normalize(np.array(world_up[3:]))
vector2 = normalize(np.array(local_up[3:]))
points = [np.array([0.1, 0.4, 0.5]) + vector2*0.2,
np.array([0.2, 0.5, 0.3]),
np.array([0.5, 0.2, 0.3]),
np.array([0.4, 0.1, 0.5]) - vector2*0.2]
for index, point in enumerate(points):
ax.scatter(*point)
dot_product = vector1.dot(vector2)
theta_rad = np.arccos(dot_product)
theta_deg = np.rad2deg(theta_rad)
vector3 = normalize(np.cross(vector1, vector2))
rotator = Quaternion(axis=vector3, angle=-theta_rad)
highest = 0
highest_index = 0
for index, point in enumerate(points):
new_point = rotator.rotate(point)
if new_point[2] > highest:
highest = new_point[2]
highest_index = index
ax.scatter(*new_point, c='gray')
ax.text(*rotator.rotate(points[highest_index]), "Highest", 'z', c='red')
ax.text(*points[highest_index], "Highest", 'z', c='red')
ax.set_xlim([-1.5, 1.5])
ax.set_ylim([-1.5, 1.5])
ax.set_zlim([-1.5, 1.5])
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')
ax.set_title("Vectors")
plt.show()
Check results here
任何人都可以提出改进或替代方法。