Python Numpy-坐标系之间的变换
使用Numpy,我想在坐标系之间变换位置向量 要帮助将问题形象化,请执行以下操作: 我在三维空间中有两个平面。 每个平面由其中心定义:Python Numpy-坐标系之间的变换,python,numpy,3d,linear-algebra,coordinate-systems,Python,Numpy,3d,Linear Algebra,Coordinate Systems,使用Numpy,我想在坐标系之间变换位置向量 要帮助将问题形象化,请执行以下操作: 我在三维空间中有两个平面。 每个平面由其中心定义: C[0] = (X0, Y0, Z0) C[1] = (X1, Y1, Z1) (X、Y、Z参照全球坐标系) 和它的法向量: H[0] = (cos(alpha[0])*sin(A[0]), cos(alpha[0])*cos(A[0]), sin(A[0]) H[1] = (cos(alpha[1])*sin(A[1]), cos(alpha[1])*c
C[0] = (X0, Y0, Z0)
C[1] = (X1, Y1, Z1)
(X、Y、Z参照全球坐标系)
和它的法向量:
H[0] = (cos(alpha[0])*sin(A[0]), cos(alpha[0])*cos(A[0]), sin(A[0])
H[1] = (cos(alpha[1])*sin(A[1]), cos(alpha[1])*cos(A[1]), sin(A[1])
alpha
=仰角
A
=方位角
H = np.array([[-0.23, -0.45, 0.86], [-0.12, -0.24, 0.86]])
我有一个点p(xp,yp,0)
位于平面0
(xp
,yp
是指一个以C[0]
为中心的局部坐标系,当alpha=a=0
时,其xyz
轴与全局xyz
轴对齐)
我使用以下函数将平面0的局部坐标系转换为全局坐标系:
import numpy as np
def rotateAxisX(alpha):
'''
Rotation about x axis
:param alpha: plane altitude angle in degrees
:return: x-axis rotation matrix
'''
rotX = np.array([[1, 0, 0], [0, np.cos(np.deg2rad(alpha)), np.sin(np.deg2rad(alpha))], [0, -np.sin(np.deg2rad(alpha)), np.cos(np.deg2rad(alpha))]])
return rotX
def rotateAxisZ(A):
'''
Rotation about z axis
:param A: plane azimuth angle in degrees
:return: z-axis rotation matrix
'''
rotZ = np.array([[np.cos(np.deg2rad(A)), np.sin(np.deg2rad(A)), 0], [-np.sin(np.deg2rad(A)), np.cos(np.deg2rad(A)), 0], [0, 0, 1]])
return rotZ
def local2Global(positionVector, planeNormalVector, positionVectorLocal):
'''
Convert point from plane's local coordinate system to global coordinate system
:param positionVector: plane center in global coordinates
:param planeNormalVector: the normal vector of the plane
:param positionVectorLocal: a point on plane (xp,yp,0) with respect to the local coordinate system of the plane
:return: the position vector of the point in global coordinates
>>> C = np.array([-10,20,1200])
>>> H = np.array([-0.23, -0.45, 0.86])
>>> p = np.array([-150, -1.5, 0])
>>> P = local2Global(C, H, p)
>>> np.linalg.norm(P-C) == np.linalg.norm(p)
True
'''
alpha = np.rad2deg(np.arcsin(planeNormalVector[2]))
A = np.where(planeNormalVector[1] > 0, np.rad2deg(np.arccos(planeNormalVector[1] / np.cos(np.deg2rad(alpha)))), 360 - np.rad2deg(np.arccos(planeNormalVector[1] / np.cos(np.deg2rad(alpha)))))
positionVectorGlobal = positionVector + np.dot(np.dot(rotateAxisZ(A), rotateAxisX(90 - alpha)), positionVectorLocal)
return positionVectorGlobal
上述措施似乎如预期的那样奏效
然后我计算一条线从平面0上的一个点通过的交点p(xp,yp,0)
,其方向向量为S=(0.56,-0.77,0.3)
因此,第一次转型是成功的
现在让我们在全局坐标中找到交点E
>>> t = np.dot(H[intersectedPlaneIndex], C[intersectedPlaneIndex, :] - P) / np.dot(H[intersectedPlaneIndex], S)
>>> E = P + S * t
>>> np.around(E, 2)
array([ 2.73, -0.67, 1.19])
到目前为止,我找到了位于平面1上的点E
(全局坐标)
问题是:
如何将点E
从全局坐标转换为平面1的坐标系,并获得E(xe,ye,0)
我试过:
def global2Local(positionVector, planeNormalVector, positionVectorGlobal):
'''
Convert point from global coordinate system to plane's local coordinate system
:param positionVector: plane center in global coordinates
:param planeNormalVector: the normal vector of the plane
:param positionVectorGlobal: a point in global coordinates
:note: This function translates the given position vector by the positionVector and rotates the basis axis in order to obtain the positionVectorCoordinates in plane's coordinate system
:warning: it does not function as it should
'''
alpha = np.rad2deg(np.arcsin(planeNormalVector[2]))
A = np.where(planeNormalVector[1] > 0, np.rad2deg(np.arccos(planeNormalVector[1] / np.cos(np.deg2rad(alpha)))), 360 - np.rad2deg(np.arccos(planeNormalVector[1] / np.cos(np.deg2rad(alpha)))))
positionVectorLocal = np.dot(np.dot(np.linalg.inv(rotateAxisZ(A)), np.linalg.inv(rotateAxisX(90 - alpha))), positionVectorGlobal - positionVector) + positionVectorGlobal
return positionVectorLocal
以及:
乍一看,这似乎没问题,只要e[2]接近零,但是
>>> np.linalg.norm(E-C[intersectedPlaneIndex])
7.2440723159783182
>>> np.linalg.norm(e)
6.0470140356703537
因此,这种转变是错误的。有什么想法吗?我建议大家阅读和阅读。对于第一个问题,我们来看看同质坐标的概念,对于不同原点的空间变换,这是有点必要的。对于第二个,请查看摄影机“注视”变换是如何执行的。只要有正交基向量(从角度很容易得到),就可以使用第二个基向量中的方程进行变换。评论中链接的帖子似乎涵盖了类似的内容。我过去常常执行这种转换您在
positionVectorLocal
行中的内容太多了。很难理解它在做什么。添加了更多细节并更改了Global2本地模块
def global2Local(positionVector, planeNormalVector, positionVectorGlobal):
'''
Convert point from global coordinate system to plane's local coordinate system
:param positionVector: plane center in global coordinates
:param planeNormalVector: the normal vector of the plane
:param positionVectorGlobal: a point in global coordinates
:note: This function translates the given position vector by the positionVector and rotates the basis axis in order to obtain the positionVectorCoordinates in plane's coordinate system
:warning: it does not function as it should
'''
alpha = np.rad2deg(np.arcsin(planeNormalVector[2]))
A = np.where(planeNormalVector[1] > 0, np.rad2deg(np.arccos(planeNormalVector[1] / np.cos(np.deg2rad(alpha)))), 360 - np.rad2deg(np.arccos(planeNormalVector[1] / np.cos(np.deg2rad(alpha)))))
positionVectorLocal = np.dot(np.dot(np.linalg.inv(rotateAxisZ(A)), np.linalg.inv(rotateAxisX(90 - alpha))), positionVectorGlobal - positionVector) + positionVectorGlobal
return positionVectorLocal
>>> e = global2Local(C[intersectedPlaneIndex], H[intersectedPlaneIndex], E)
>>> e
array([ -2.54839059e+00, -5.48380179e+00, -1.42292121e-03])
>>> np.linalg.norm(E-C[intersectedPlaneIndex])
7.2440723159783182
>>> np.linalg.norm(e)
6.0470140356703537