我正在尝试实现在球坐标系中旋转的功能。 最后,我需要用Javascript实现,但首先,我想使其在python中工作,因为我对这种语言更加熟悉。
我想要一个以参数为参数的功能 rotate :
到目前为止,我使用http://stla.github.io/stlapblog/posts/RotationSphericalCoordinates.html中的方法:
执行:
import numpy as np
from math import cos, sin, atan, pi
from cmath import exp, phase
#####################################################
def rotate(alpha, theta, phi, THETA, PHI, degrees=True):
## DEGREES TO RAD
if degrees:
alpha = pi/180 * alpha
theta = pi/180 * theta
phi = pi/180 * phi
THETA = pi/180 * THETA
PHI = pi/180 * PHI
psi_ = Psi_(alpha, theta, phi, THETA, PHI)
theta_ = 2 * atan(abs(psi_[1][1])/abs(psi_[0][0]))
phi_ = phase(psi_[1][1]) - phase(psi_[0][0])
## RAD TO DEGREES
if degrees:
return theta_ * 180/pi, phi_ * 180/pi
return theta_, phi_
#####################################################
def Psi_(alpha, theta, phi, THETA, PHI):
return Rn(THETA, PHI, alpha) * \
Psi(alpha, theta, phi)
#####################################################
def Psi(alpha, theta, phi):
return np.array([
[cos(theta)/2],
[exp(1j*phi) * sin(theta/2)]
])
#####################################################
def Rn(THETA, PHI, alpha):
return Rz(PHI) * \
Ry(THETA) * \
Rz(alpha) * \
Ry(THETA).conj().T * \
Rz(PHI).conj().T
#####################################################
def Rx(alpha):
return np.array([
[cos(alpha/2), -1j * sin(alpha/2)],
[-1j * sin(alpha/2), cos(alpha/2)]
])
#####################################################
def Ry(alpha):
return np.array([
[cos(alpha/2), -sin(alpha/2)],
[sin(alpha/2), cos(alpha/2)]
])
#####################################################
def Rz(alpha):
return np.array([
[exp(-1j * alpha/2), 0],
[0, exp(1j * alpha/2)]
])
#####################################################
if __name__ == "__main__":
print(rotate(
alpha = 90, # roation angle
theta = 90, # point theta
phi = 0, # point phi
THETA = 0, # axis theta
PHI = 0, # axis phi
degrees = True # angles in degrees
))
这应该提供一个新的cothenate theta = 90和phi =90。我得到的是theta = 180和phi = 90。
我真正不确定的部分是旋转函数中theta_和psi_的计算。在文章中,它说psi_应该是2x1矩阵,但是我得到的是2x2矩阵。
这是我的实现尝试:
{{1}}
感谢您的帮助!
答案 0 :(得分:0)
如我的评论中所述,我不认为如果实际上想围绕任意<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<input type="text" v-model.number="count" @input="alert">
<button @click="add">+1</button>
</div>
,x
和y
旋转是最聪明的解决方案轴。所以我会用四元数。这实际上使用了z
,x
,y
向量,但是qubit解决方案也使用了所有的z
,sine
方法,因此这里没有优点也没有缺点
atan
提供
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
class Quaternion( object ):
"""
Simplified Quaternion class for rotation of normalized vectors only!
"""
def __init__( self, q0, qx, qy, qz ):
"""
Internally uses floats to avoid integer division issues.
@param q0: int or float
@param qx: int or float
@param qy: int or float
@param qz: int or float
"""
self._q0 = float( q0 )
self._qx = float( qx )
self._qy = float( qy )
self._qz = float( qz )
"""
Note if interpreted as rotation q0 -> -q0 doesn't make a difference
q0 = cos( w ) so -cos( w ) = cos( w + pi ) and as the rotation
is by twice the angle it is either 2w or 2w + 2pi, the latter being equivalent to the former.
"""
def conjugate(q):
"""
@return Quaternion
"""
conjq = Quaternion( q._q0, -q._qx, -q._qy, -q._qz )
return conjq
def __mul__(q, r):
"""
Non commutative quaternion multiplication.
@return Quaternion
"""
if isinstance(r, Quaternion):
mq0 = q._q0 * r._q0 - q._qx * r._qx - q._qy * r._qy - q._qz * r._qz
mqx = q._q0 * r._qx + q._qx * r._q0 + q._qy * r._qz - q._qz * r._qy
mqy = q._q0 * r._qy - q._qx * r._qz + q._qy * r._q0 + q._qz * r._qx
mqz = q._q0 * r._qz + q._qx * r._qy - q._qy * r._qx + q._qz * r._q0
out = Quaternion(mq0, mqx, mqy, mqz)
elif isinstance( r, ( int, long, float ) ):
out = r * q
else:
raise TypeError
return out
def __getitem__( q, idx ):
"""
@return float
"""
if idx < 0:
idx = 4 + idx
if idx in [ 0, 1, 2, 3 ]:
out = (q._q0, q._qx, q._qy, q._qz)[idx]
else:
raise IndexError
return out
theta, phi = .4, .89
xA, yA, zA = np.sin( theta ) * np.cos( phi ), np.sin( theta ) * np.sin( phi ), np.cos( theta )
Theta, Phi = .5, 1.13
xB, yB, zB = np.sin( Theta ) * np.cos( Phi ), np.sin( Theta ) * np.sin( Phi ), np.cos( Theta )
qB = Quaternion( 0, xB, yB, zB )
cX = [ xB ]
cY = [ yB ]
cZ = [ zB ]
for alpha in np.linspace( 0.1, 6, 20 ):
qA = Quaternion( np.cos( 0.5 * alpha ), xA * np.sin( 0.5 * alpha ), yA * np.sin( 0.5 * alpha ), zA * np.sin( 0.5 * alpha ) )
qAi = qA.conjugate()
qBr = qA * ( qB * qAi )
cX += [ qBr[1] ]
cY += [ qBr[2] ]
cZ += [ qBr[3] ]
print np.arccos( qBr[3] ), np.arctan2( qBr[2], qBr[1] )
fig = plt.figure()
ax = fig.add_subplot( 111, projection='3d' )
u = np.linspace( 0, 2 * np.pi, 50 )
v = np.linspace( 0, np.pi, 25 )
x = .9 * np.outer( np.cos( u ), np.sin( v ) )
y = .9 * np.outer( np.sin( u ), np.sin( v ) )
z = .9 * np.outer( np.ones( np.size( u ) ), np.cos( v ) )
ax.plot_wireframe( x, y, z, color='g', alpha=.3 )
ax.plot( [ 0, xA ], [ 0, yA ],[ 0, zA ], color='r' )
ax.plot( [ 0, xB ], [ 0, yB ],[ 0, zB ], color='b' )
ax.plot( cX, cY, cZ , color='b' )
plt.show()
和