向量的旋转(Python)

向量的旋转(Python),python,vector,3d,rotation,angle,Python,Vector,3d,Rotation,Angle,我使用以下代码通过两个2D旋转在3D中旋转矢量: 注:我是 np.array([11.231303753070549, 9.27144871768164, 18.085790226916288]) 下图中以蓝色显示的预定义向量 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D def angle_between(p1, p2): ang1 = np.ar

我使用以下代码通过两个2D旋转在3D中旋转矢量:

注:我是

np.array([11.231303753070549, 9.27144871768164, 18.085790226916288])
下图中以蓝色显示的预定义向量

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def angle_between(p1, p2):
    ang1 = np.arctan2(*p1[::-1])
    ang2 = np.arctan2(*p2[::-1])
    return ((ang1 - ang2) % (2 * np.pi))

L = np.vstack([L,np.zeros(3)])
line_xy = [0.,1.]
line_L = [L[0,0],L[0,1]]
a = angle_between(line_xy, line_L)

def rotation(vector,theta):    
        v1_new = (vector[0]*np.cos(theta)) - (vector[1]*np.sin(theta))
        v2_new = (vector[1]*np.cos(theta)) + (vector[0]*np.sin(theta))        
        z_trans = [v1_new,v2_new,vector[2]]
        line_yz= [0.,1.]
        theta2 = angle_between(line_yz, [z_trans[1],z_trans[2]])
        v1_new = (z_trans[0]*np.cos(theta2)) - (z_trans[1]*np.sin(theta2))
        v2_new = (z_trans[1]*np.cos(theta2)) + (z_trans[0]*np.sin(theta2))
        y_trans = np.array([z_trans[0],v1_new,v2_new])        
        return z_trans,y_trans

L2,L3 = rotation(L[0,:],a)

L2 = np.vstack([L2,np.zeros(3)])
L3 = np.vstack([L3,np.zeros(3)])

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
#ax.scatter(x1*1000,y1*1000,z1*1000,c ='r',zorder=2)
ax.plot(L[:,0],L[:,1],L[:,2],color='b',zorder=1)
line = np.array([[0,0,0],[0,0,15]])
ax.plot(line[:,0],line[:,1],line[:,2],color = 'g')
ax.set_xlabel('X Kpc')
ax.set_ylabel('Y Kpc')
ax.set_zlabel('Z Kpc')

ax.plot(L2[:,0],L2[:,1],L2[:,2],color='g')
ax.plot(L3[:,0],L3[:,1],L3[:,2],color='y')
我在这里做的是计算x=0,y=1之间的角度(这是线的xy部分),然后使用旋转函数的第一部分绕z轴旋转:

v1_new = (vector[0]*np.cos(theta)) - (vector[1]*np.sin(theta))
v2_new = (vector[1]*np.cos(theta)) + (vector[0]*np.sin(theta))        
z_trans = [v1_new,v2_new,vector[2]]
然后重复该过程,但这次使用旋转功能的第二部分绕x轴旋转:

line_yz= [0.,1.]
theta2 = angle_between(line_yz, [z_trans[1],z_trans[2]])
v1_new = (z_trans[0]*np.cos(theta2)) - (z_trans[1]*np.sin(theta2))
v2_new = (z_trans[1]*np.cos(theta2)) + (z_trans[0]*np.sin(theta2))
y_trans = np.array([z_trans[0],v1_new,v2_new]) 
通过标准二维旋转方程进行旋转:

x'=x cos(θ)-y sin(θ) y'=y cos(θ)+x sin(θ)

但由于某些原因,在第二次旋转后,该线(黄色)与绿线(旋转该向量的原始目标)不对齐

我尝试过检查弧度和度数的角度,但它似乎只适用于弧度


当检查角度θ2时,它的角度大约为35度,这看起来似乎是合理的

我不太清楚你的问题,但希望这会有所帮助

如果要围绕特定轴旋转三维矢量,请利用而不是元素(如上文所述)。 下面是绕任意轴旋转三维矢量的代码:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def unit_vector(vector):
    """ Returns the unit vector of the vector."""
    return vector / np.linalg.norm(vector)

def angle_between(v1, v2):
    """Finds angle between two vectors"""
    v1_u = unit_vector(v1)
    v2_u = unit_vector(v2)
    return np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))

def x_rotation(vector,theta):
    """Rotates 3-D vector around x-axis"""
    R = np.array([[1,0,0],[0,np.cos(theta),-np.sin(theta)],[0, np.sin(theta), np.cos(theta)]])
    return np.dot(R,vector)

def y_rotation(vector,theta):
    """Rotates 3-D vector around y-axis"""
    R = np.array([[np.cos(theta),0,np.sin(theta)],[0,1,0],[-np.sin(theta), 0, np.cos(theta)]])
    return np.dot(R,vector)

def z_rotation(vector,theta):
    """Rotates 3-D vector around z-axis"""
    R = np.array([[np.cos(theta), -np.sin(theta),0],[np.sin(theta), np.cos(theta),0],[0,0,1]])
    return np.dot(R,vector)
将原始蓝色向量旋转45度(pi/2)


我不太清楚你的问题,但希望这会有所帮助

如果要围绕特定轴旋转三维矢量,请利用而不是元素(如上文所述)。 下面是绕任意轴旋转三维矢量的代码:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def unit_vector(vector):
    """ Returns the unit vector of the vector."""
    return vector / np.linalg.norm(vector)

def angle_between(v1, v2):
    """Finds angle between two vectors"""
    v1_u = unit_vector(v1)
    v2_u = unit_vector(v2)
    return np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))

def x_rotation(vector,theta):
    """Rotates 3-D vector around x-axis"""
    R = np.array([[1,0,0],[0,np.cos(theta),-np.sin(theta)],[0, np.sin(theta), np.cos(theta)]])
    return np.dot(R,vector)

def y_rotation(vector,theta):
    """Rotates 3-D vector around y-axis"""
    R = np.array([[np.cos(theta),0,np.sin(theta)],[0,1,0],[-np.sin(theta), 0, np.cos(theta)]])
    return np.dot(R,vector)

def z_rotation(vector,theta):
    """Rotates 3-D vector around z-axis"""
    R = np.array([[np.cos(theta), -np.sin(theta),0],[np.sin(theta), np.cos(theta),0],[0,0,1]])
    return np.dot(R,vector)
将原始蓝色向量旋转45度(pi/2)


这个问题有一个通用的解决方案。给定一个向量,一个旋转轴和一个逆时针的角度,我写了一个简单的代码,当然对于前面提到的情况也是有效的。它所做的是:

  • 将矢量投影到由旋转轴定义的平面上
  • 在平面中旋转向量的分量
  • 最后将所有部件重新组装在一起,以得出最终结果
  • 
    将numpy作为np导入
    将matplotlib.pyplot作为plt导入
    从mpl_toolkits.mplot3d导入Axes3D
    导入matplotlib
    def旋转(v、erot、角度):
    rotmeasure=np.linalg.norm(erot)
    erot=erot/旋转测量;
    标准=np.点(v,erot)
    vplane=v-norme*erot
    plnorm=np.linalg.norm(vplane)
    ep=vplane/plnorm
    eo=np.交叉(erot,ep)
    vrot=(正余弦角)*ep+正余弦角)*eo*plnorm+norme*erot
    返回(vrot)
    如果需要,您可以使用一个示例进行检查,该示例绘制了旋转产生的“伞”:

    axrot=np.array([1,0,1]); v=np.array([1.,1.,1.]) fig3 = plt.figure(3) ax3d = fig3.add_subplot(111, projection='3d') ax3d.quiver(0,0,0,axrot[0],axrot[1],axrot[2],length=.5, normalize=True, color='black') angles=np.linspace(0,2,10)*np.pi for i in range(len(angles)): vrot=rotve(v,axrot,angles[i]); ax3d.quiver(0,0,0,vrot[0],vrot[1],vrot[2],length=.1, normalize=True, color='red') ax3d.quiver(0,0,0,v[0],v[1],v[2],length=.1, normalize=True, color='blue') ax3d.set_title('rotations') fig3.show() plt.show()
    axrot=np.数组([1,0,1]);v=np.数组([1,1,1.])) 图3=plt.图(3) ax3d=fig3.添加_子图(111,投影=3d') ax3d.quivel(0,0,0,axrot[0],axrot[1],axrot[2],长度=0.5,normalize=True,color='black') 角度=np.linspace(0,2,10)*np.pi 对于范围内的i(len(角度)): vrot=旋转(v,axrot,角[i]); ax3d.quiver(0,0,0,vrot[0],vrot[1],vrot[2],长度=0.1,规格化=True,颜色=red') ax3d.quiver(0,0,0,v[0],v[1],v[2],长度=0.1,normalize=True,color='blue') ax3d.set_标题(“旋转”) 图3.show() plt.show()
    这个问题有一个通用的解决方案。给定一个向量,一个旋转轴和一个逆时针的角度,我写了一个简单的代码,当然对于前面提到的情况也是有效的。它所做的是:

  • 将矢量投影到由旋转轴定义的平面上
  • 在平面中旋转向量的分量
  • 最后将所有部件重新组装在一起,以得出最终结果
  • 
    将numpy作为np导入
    将matplotlib.pyplot作为plt导入
    从mpl_toolkits.mplot3d导入Axes3D
    导入matplotlib
    def旋转(v、erot、角度):
    rotmeasure=np.linalg.norm(erot)
    erot=erot/旋转测量;
    标准=np.点(v,erot)
    vplane=v-norme*erot
    plnorm=np.linalg.norm(vplane)
    ep=vplane/plnorm
    eo=np.交叉(erot,ep)
    vrot=(正余弦角)*ep+正余弦角)*eo*plnorm+norme*erot
    返回(vrot)
    如果需要,您可以使用一个示例进行检查,该示例绘制了旋转产生的“伞”:

    axrot=np.array([1,0,1]); v=np.array([1.,1.,1.]) fig3 = plt.figure(3) ax3d = fig3.add_subplot(111, projection='3d') ax3d.quiver(0,0,0,axrot[0],axrot[1],axrot[2],length=.5, normalize=True, color='black') angles=np.linspace(0,2,10)*np.pi for i in range(len(angles)): vrot=rotve(v,axrot,angles[i]); ax3d.quiver(0,0,0,vrot[0],vrot[1],vrot[2],length=.1, normalize=True, color='red') ax3d.quiver(0,0,0,v[0],v[1],v[2],length=.1, normalize=True, color='blue') ax3d.set_title('rotations') fig3.show() plt.show()
    axrot=np.数组([1,0,1]);v=np.数组([1,1,1.])) 图3=plt.图(3) ax3d=fig3.添加_子图(111,投影=3d') ax3d.quivel(0,0,0,axrot[0],axrot[1],axrot[2],长度=0.5,normalize=True,color='black') 角度=np.linspace(0,2,10)*np.pi 对于范围内的i(len(角度)): vrot=旋转(v,axrot,角[i]); ax3d.quiver(0,0,0,vrot[0],vrot[1],vrot[2],长度=0.1,规格化=True,颜色=red') ax3d.quiver(0,0,0,v[0],v[1],v[2],长度=0.1,normalize=True,color='blue') ax3d.set_标题(“旋转”) 图3.show() plt.show()
    请包括
    L
    和所需的结果向量。你认为你犯了一个数学错误还是编程错误?嗨,我已经在顶部的“注释”中包含了L。我认为这是一个编程错误,很可能是由于我在数学上处理问题的方式造成的。对于您指定的
    L
    ,这一行,
    line\u L=[L[0,0],L[0,1]
    ,抛出了一个类型错误。请提供一个我已经更新了L的数组,而不是一个列表,所以现在应该可以工作了。这项工作是从一个更大的工作,所以道歉,但我确实提供了。只需注意,“scipy.space.transform.Rotation”现在做所有的旋转,而不需要经过所有的理论。请包括
    L
    和所需的结果向量。你认为你犯了一个数学错误还是编程错误?嗨,我已经在顶部的“注释”中包含了L。我认为这是一个编程错误,很可能是由于我在数学上处理问题的方式造成的。对于您指定的
    L
    ,这一行,
    line\u L=[L[0,0],L[0,1]
    ,抛出了一个类型错误。请提供一个我已经更新了L的数组,而不是一个列表,所以现在应该可以工作了。这项工作是从一个更大的作品,所以道歉,但我提供了提供。只是一个n