如何计算旋转角度Ax、Ay、Az使指定点精准落在Y轴上?
三维点集旋转:将指定直线对齐至Y轴的角度计算
问题说明
给定三维空间中的一组点,指定point1与point2构成直线。先将所有点平移,使point1移至原点;再通过绕X、Y、Z轴的三次旋转,让point2精准落在Y轴上(x、z坐标为0),需计算对应的旋转角度Ax(绕X轴)、Ay(绕Y轴)、Az(绕Z轴)。
原始测试代码及结果
import numpy as np points = np.array([[0.36266313,0.70320135,0.88975275], [0.26227164,0.32188661,0.39514979], [0.26100571,0.63643259,0.20245194], [0.25701545,0.59125069,0.80146842], [0.23185588,0.19422526,0.68689653]]) point1, point2 = points[0], points[2] # 平移所有点,使point1到原点 points = points - point1 point2 = point2 - point1 point1 = point1 - point1 def rotate_points_around_point(points, angle_degrees, axis, center_point): translated_points = points - center_point angle_radians = np.radians(angle_degrees) # 定义各轴旋转矩阵(右手定则) rotation_matrix = { 'x': np.array([[1, 0, 0], [0, np.cos(angle_radians), -np.sin(angle_radians)], [0, np.sin(angle_radians), np.cos(angle_radians)]]), 'y': np.array([[np.cos(angle_radians), 0, np.sin(angle_radians)], [0, 1, 0], [-np.sin(angle_radians), 0, np.cos(angle_radians)]]), 'z': np.array([[np.cos(angle_radians), -np.sin(angle_radians), 0], [np.sin(angle_radians), np.cos(angle_radians), 0], [0, 0, 1]]) } rotated_points = np.dot(translated_points, rotation_matrix[axis].T) rotated_points = rotated_points + center_point return rotated_points # 待计算的旋转角度 Ax = 96 Ay = -3.0626 Az = -8.38675 # 按X→Y→Z顺序旋转 points = rotate_points_around_point(points, Ax, "x", point1) points = rotate_points_around_point(points, Ay, "y", point1) points = rotate_points_around_point(points, Az, "z", point1) print(points)
运行结果:
[[ 0. 0. 0. ] [-0.004306 0.538135 -0.332422] [ 0. 0.697979 0. ] [-0.084459 0.11303 -0.107608] [-0.066404 0.267493 -0.49128 ]
角度计算方法
要计算将平移后的point2旋转至Y轴的角度,可通过向量对齐+欧拉角分解的方式实现,步骤如下:
- 获取目标向量:平移后
point2的坐标为P,目标方向为Y轴正方向。 - 构建旋转矩阵:计算能将向量
P旋转至Y轴的旋转矩阵,可通过Rodrigues公式推导或直接使用工具库生成。 - 分解欧拉角:将旋转矩阵分解为代码中使用的X→Y→Z顺序的旋转角度。
自动化计算角度的代码实现
替换原始代码中角度赋值部分,使用以下代码自动计算Ax、Ay、Az:
from scipy.spatial.transform import Rotation as R # 平移后的point2向量 P = point2 vec_length = np.linalg.norm(P) # 目标方向:Y轴正方向 target_vec = np.array([0, vec_length, 0]) # 计算单位向量 u = P / vec_length v = target_vec / vec_length # 构建旋转矩阵 cross_vec = np.cross(u, v) dot_product = np.dot(u, v) # 处理向量反向的特殊情况 if np.isclose(dot_product, -1.0): rotation_matrix = -np.eye(3) else: # 使用Rodrigues公式构建旋转矩阵 skew_sym = np.array([ [0, -cross_vec[2], cross_vec[1]], [cross_vec[2], 0, -cross_vec[0]], [-cross_vec[1], cross_vec[0], 0] ]) rotation_matrix = np.eye(3) + skew_sym + np.dot(skew_sym, skew_sym) / (1 + dot_product) # 将旋转矩阵分解为XYZ顺序的欧拉角(单位:度) rot = R.from_matrix(rotation_matrix) Ax, Ay, Az = rot.as_euler('xyz', degrees=True) print(f"计算得到的旋转角度:Ax={Ax:.4f}, Ay={Ay:.4f}, Az={Az:.4f}")
验证结果
运行上述代码后,得到的角度与示例中的手动输入值基本一致,旋转后point2将精准落在Y轴上。
内容的提问来源于stack exchange,提问作者mehran
相关产品推荐
相关产品推荐

