假设我们有一个向量 n,我们想要找到一个围绕中心 p1 的圆,其半径为 r,与 n 正交。这是一个带有代码的工作示例
p1 = np.array([-21.03181359, 4.54876345, 19.26943601])
n = np.array([-0.06592715, 0.00713031, -0.26809672])
n = n / np.linalg.norm(n) # normalise n
r = 0.5
x = np.array([1,0,0]).astype(np.float64) # take a random vector of magnitude 1
x -= x.dot(n) * n / np.linalg.norm(n)**2 # make it orthogonal to n
x /= np.linalg.norm(x) # normalize
# find first point on circle (x1).
# currently it has magnitude of 1, so we multiply it by the r
x1 = p1 + (x*r)
# vector from lumen centre to first circle point
p1x1 = x1 - p1
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]])
# rotate the vector p1x1 around the axis n with angle theta
circle = []
for theta in range(0,360,6):
circle_i = np.dot(rotation_matrix(n, np.deg2rad(theta)), p1x1)
circle.append(circle_i+p1)
ax = axes3d.Axes3D(plt.figure(figsize=(10,10)))
ax.scatter3D(*np.array(circle).T, s=10, c='red')
ax.scatter3D(*p1.T, s=10, c='black')
ax.set_xlabel('X', size=40)
ax.set_ylabel('Y', size=40)
ax.set_zlabel('Z', size=40)
ax.set_xlim(-19,-22)
ax.set_ylim(2,5)
ax.set_zlim(18,21)