加入x旋转旋转点功能

Add x rotation to rotate point function

我有这个功能:

def rotatePoint(p1, p2, a):
    if a == 0: return p2
    x1, y1, z1 = p1
    x2, y2, z2 = p2

    d12 = math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) + (z2 - z1) * (z2 - z1))

    aP1P2 = math.atan2(z2 - z1, x2 - x1)  # In radians, not degrees
    aP1P3 = aP1P2 - math.radians(a)

    x3 = x1 + d12 * math.cos(aP1P3)
    y3 = y2# same as P1 an P2
    z3 = z1 + d12 * math.sin(aP1P3)
    
    p3 = (x3, y3, z3)
    
    return p3
    

它可以在 y 平面上绕另一个点旋转。例如:

p1 = (0,0,0) 
p2 = (0,0,20) 
a = 45 
                
print(rotatePoint(p1,p2,a))

#Outputs:(14.142135623730951, 0, 14.14213562373095) 

如何改变它,使其也可以绕 x 平面旋转?

编辑: 我查看了旋转矩阵,但无法弄清楚。这就是我得到的,我知道这是错误的。它有什么问题:

def getRotationMatrix(a1, a2, a3):
    
    sin = math.sin
    cos = math.cos
    
    xrot = cos(a2) * cos(a3)  *  cos(a1)*sin(a3)+sin(a1)*sin(a2)*cos(a3)    *  sin(a1)*sin(a3) - cos(a1)*sin(a2)*cos(a3)
    yrot = -cos(a2)*sin(a3)   *  cos(a1)*cos(a3) - sin(a1)*sin(a2)*sin(a3)  *  sin(a1)*cos(a3) + cos(a1)*sin(a2)*sin(a3)
    zrot = sin(a2)            *  -sin(a1)*cos(a2)                           *  cos(a1)*cos(a2)
    
    return [xrot, yrot, zrot]

我认为你的做法是正确的。只有一个问题。 xrot、yrot 和 zrot 是每个包含三个组件的列表。所以删除乘号并用逗号替换并将它们放入列表中。下面是一个天真的实现。旋转的顺序是important先x轴,再y轴再z轴。在你的情况下没关系,因为你想绕一个轴旋转。您可以通过将其他两个角度设置为零来使用以下功能。在进一步使用之前,请通过对多个案例进行测试来仔细检查此方法的结果。如果有错误请告诉我。我只测试了两个简单的案例。

import math
def TranslateToOriginAndReturnUndoVector(x1,y1,z1):
    return (x1,y1,z1)

def getRotationMatrix(a1, a2, a3, x1, y1, z1, x2, y2, z2):

    ## Step 1 translate to origin
    x_translated, y_translated, z_translated = TranslateToOriginAndReturnUndoVector(x1,y1,z1)

    ## Step 2 Calculate Rotation Matrix and new x,y,z w.r.t Step 1 values
    sin = math.sin
    cos = math.cos
    
    xrot = [cos(a2) * cos(a3)  , cos(a1)*sin(a3)+sin(a1)*sin(a2)*cos(a3)   , sin(a1)*sin(a3) - cos(a1)*sin(a2)*cos(a3)]
    yrot = [-cos(a2)*sin(a3)   ,  cos(a1)*cos(a3) - sin(a1)*sin(a2)*sin(a3)  ,  sin(a1)*cos(a3) + cos(a1)*sin(a2)*sin(a3)]
    zrot = [sin(a2)            ,  -sin(a1)*cos(a2)                           ,  cos(a1)*cos(a2)]
    x_new = 0
    y_new = 0
    z_new = 0
    for i in range(3):
        x_new += xrot[i]*(x2 - x_translated)
        y_new += yrot[i]*(y2 - y_translated)
        z_new += zrot[i]*(z2 - z_translated)
    x_new, y_new, z_new = round(x_new, 3), round(y_new,3), round(z_new,3)
    ## Step 3, Undo Step 1
    x_new, y_new, z_new = x_new + x_translated, y_new + y_translated, z_new + z_translated

    ## Return the new values
    return (x_new, y_new, z_new)

print(getRotationMatrix(0,math.pi/4,0,0,0,0, 20,20, 20))
print(getRotationMatrix(0,math.pi/4,0,10,10,10, 20,20, 20))

给出以下输出。

(0.0, 20.0, 28.284)
(10.0, 20.0, 24.142)

我正在关注 -

中介绍的转换细节

https://en.wikipedia.org/wiki/Davenport_chained_rotations https://en.wikipedia.org/wiki/Rotation_matrix

def rotatePoint(p1, p2, a):
    '''
    https://en.wikipedia.org/wiki/Davenport_chained_rotations
    https://en.wikipedia.org/wiki/Rotation_matrix

    '''
    # rotation in degrees
    # convert to radians
    alpha,beta,gamma=[math.radians(x) for x in a]
    print(f'Rotation angles = {alpha},{beta},{gamma}')
    # math functions alias
    cos=math.cos
    sin=math.sin

    Rx_alpha=np.array([[1.0        ,   0.0     ,    0.0    ],
                       [0.0        , cos(alpha),-sin(alpha)],
                       [0.0        , sin(alpha),cos(alpha) ]])
    
    Ry_beta=np.array([[ cos(beta),   0.0,   sin(beta)],
                      [       0.0,   1.0,   0.0      ],
                      [-sin(beta),   0.0,   cos(beta)]])

    Rz_gamma=np.array([[cos(gamma) ,-sin(gamma),0.0],
                       [sin(gamma) , cos(gamma),0.0],
                       [0.0        , 0.0       ,1.0]])

    R=np.matmul(np.matmul(Rz_gamma,Ry_beta),Rx_alpha)

    print(f'Rotation matrix = {R}')
    
    # calculate the vector about point p1,
    
    point_vector=np.array(p2)-np.array(p1)
    point_vector_magnitude=np.linalg.norm(point_vector)
    # normalized
    point_vector=point_vector/point_vector_magnitude


    print(f'point_vector={point_vector}')
    print(f'point_vector_magnitude={point_vector_magnitude}')

    rotated_vector=np.matmul(R,point_vector)*point_vector_magnitude

    # calculate the transformed point p3
    p3=np.array(p1)+rotated_vector
    print(f'New Rotate point {p3}')

支票:

rotatePoint([0,0,0],[0,0,20],[0,0,45])

输出:

Rotation angles = 0.0,0.0,0.7853981633974483
Rotation matrix = [[ 0.70710678 -0.70710678  0.        ]
 [ 0.70710678  0.70710678  0.        ]
 [ 0.          0.          1.        ]]
point_vector=[0. 0. 1.]
point_vector_magnitude=20.0
unit_rotated_vector =[0. 0. 1.]
New Rotate point [ 0.  0. 20.]

rotatePoint([0,0,0],[0,0,20],[45,0,0])

输出:

Rotation angles = 0.7853981633974483,0.0,0.0
Rotation matrix = [[ 1.          0.          0.        ]
 [ 0.          0.70710678 -0.70710678]
 [ 0.          0.70710678  0.70710678]]
point_vector=[0. 0. 1.]
point_vector_magnitude=20.0
unit_rotated_vector =[ 0.         -0.70710678  0.70710678]
New Rotate point [  0.         -14.14213562  14.14213562]