如何将一条线精确地放置在 Y 轴上?

问题描述 投票:0回答:1

假设我们有几个点位于三维空间中。现在,我们指定两个点,命名为point1point2。为了简化问题,我们将这两点视为一条线。现在我们将 point1 移动到原点。这种平移使得所有点都相应地移位。现在,所有点都必须旋转,以便 point2 恰好位于 Y 轴 上,这意味着它的 x 和 z 坐标应该为零。但是需要执行哪些具体计算来确定所有这些点应旋转的方向,以便 point2 精确定位在Y 轴上?

我非常感谢您的帮助。

如果我想更精确地问我的问题,AxAyAz的值应该如何计算?

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]

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

# ======== Question ========
Ax = 96
Ay = -3.0626
Az = -8.38675
# ======== Question ========

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 ]]

我很重视您提供的见解和指导。

python numpy 3d rotation angle
1个回答
0
投票

平移这些点,使您的第一个参考点位于原点。

设B为平移后第二参考点的位置向量。

关键步骤:取 B 的向量叉积和 y 方向上的单位向量(按顺序)。得到的向量将具有最终旋转轴的方向和幅值norm(B)x1xsin(theta),其中theta是旋转角度。

您可以根据该轴和旋转角度创建旋转矩阵。这是您需要的single旋转矩阵。

以下代码执行此操作。请注意,浮点运算会在点 [2] 中留下 1e-16 阶的 x 和 z 坐标:实际上是 0。

import math
import numpy as np
import matplotlib.pyplot as plt


def rotationMatrix( a, theta ):        # rotation matrix for a rotation of angle theta about axis a
    R = np.zeros( ( 3, 3 ) )
    n = a / np.linalg.norm( a )
    C = math.cos( theta )
    S = math.sin( theta )

    R[0,0] = C + n[0] * n[0] * ( 1.0 - C )
    R[0,1] =     n[0] * n[1] * ( 1.0 - C ) - n[2] * S
    R[0,2] =     n[0] * n[2] * ( 1.0 - C ) + n[1] * S
    R[1,1] = C + n[1] * n[1] * ( 1.0 - C )
    R[1,2] =     n[1] * n[2] * ( 1.0 - C ) - n[0] * S
    R[1,0] =     n[1] * n[0] * ( 1.0 - C ) + n[2] * S
    R[2,2] = C + n[2] * n[2] * ( 1.0 - C )
    R[2,0] =     n[2] * n[0] * ( 1.0 - C ) - n[1] * S
    R[2,1] =     n[2] * n[1] * ( 1.0 - C ) + n[0] * S

    return R


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]])

A = points[0]                                            # First reference point
points -= A                                              # Translate such that A goes to origin
B = points[2]                                            # B is the point you want to rotate onto the y axis (did you mean [2]?)

Y = np.array( [0.0, 1.0, 0.0 ] )                         # Unit vector along y axis
axis = np.cross( B, Y )                                  # Axis of rotation (not normalised)
mag = np.linalg.norm( axis )
if ( abs(mag) < 1.0e-20 ): axis = np.array([1.0,0,0])    # Already on y axis, so rotation axis is irrelevant
sintheta = mag / np.linalg.norm( B )                     # Sine of angle of rotation
theta = math.asin( sintheta )
if np.dot( B, Y ) < 0: theta = math.pi - theta           # Appropriate angle to rotate to the POSITIVE y axis

R = rotationMatrix( axis, theta )                        # Find rotation matrix

points = ( R @ (points.T) ).T                            # Rotate points
print( points )

输出:

[[ 0.00000000e+00  0.00000000e+00  0.00000000e+00]
 [-7.51354446e-02  5.38134329e-01 -3.23848081e-01]
 [-3.85256819e-17  6.97979012e-01 -2.79186184e-16]
 [-1.05473850e-01  1.13030002e-01 -8.71090761e-02]
 [-1.69698494e-01  2.67492963e-01 -4.65798002e-01]]
© www.soinside.com 2019 - 2024. All rights reserved.