Unity 坐标系与右手坐标系位姿(旋转和位移)转换
Unity 坐标系和右手坐标系的位姿(位移和姿态)的相互转换,使用向量来表示位移,使用四元数来表示旋转。
注意:此文章已经被我移动到 博客园,若发现此处访问受限,请移步博客园。
Unity 坐标系与右手坐标系位姿(旋转和位移)转换
下图是 Unity 使用的坐标系和右手坐标系的示意图:

可以清楚地看到,Unity 中用的是左手坐标系,且是 z 轴向前,y 轴向上;而右手坐标系是 x 轴向前,z 轴向上(当然也可以自己规定怎么放)。
现需要把 Unity 的一个位姿转换为右手坐标系下的位姿。
位移转换
位移转换其实很简单,假设在 Unity 中的位移是 v u v_u vu,右手坐标系的位移是 v r v_r vr,那么把 v r v_r vr 转换为 v u v_u vu 则是:
v u x = − v r y v u y = v r z v u z = v r x v_{ux} = -v_{ry} \\ v_{uy} = v_{rz} \\ v_{uz} = v_{rx} vux=−vryvuy=vrzvuz=vrx
其中 v u x v_{ux} vux 表示 v u v_u vu 的 x 坐标,其它以此类推。
要把 v u v_u vu 转换为 v r v_r vr 的话,反过来就可以了。
旋转转换
为了能够消除旋转顺序和万向节的影响,这里不用欧拉角来表示旋转,而是使用四元数来表示一个唯一的旋转。
参考了这里 的文章,我才发现用四元数表示旋转的话,这两个坐标系的转换也很简单。
四元数的形式可以是 w + x i + y j + z k w+xi+yj+zk w+xi+yj+zk ,其中 i i i, j j j, k k k 为四元数的虚部, w w w 为四元数的实部。
四元数表达的是绕一个旋转轴 ( x ω , y ω , z ω ) (x_\omega,y_\omega,z_\omega) (xω,yω,zω) 旋转了一个角度 ω \omega ω,所以,四元数中的实部和虚部为:
w = cos ( ω / 2 ) x = sin ( ω / 2 ) x ω y = sin ( ω / 2 ) y ω z = sin ( ω / 2 ) z ω w = \cos(\omega/2) \\ x = \sin(\omega/2) x_\omega \\ y = \sin(\omega/2) y_\omega \\ z = \sin(\omega/2) z_\omega w=cos(ω/2)x=sin(ω/2)xωy=sin(ω/2)yωz=sin(ω/2)zω
因此,只要把旋转轴在两个坐标系下找对就行了。
位移和旋转轴的表示都是 ( x , y , z ) (x,y,z) (x,y,z),所以直接用位移的转换公式来转换旋转轴即可。
那么,把右手坐标系的四元数 q r q_r qr 转换到 Unity 中的四元数 q u q_u qu 的方式为:
w u = w r x u = − y r y u = z r z u = x r w_u = w_r \\ x_u = -y_r \\ y_u = z_r \\ z_u = x_r wu=wrxu=−yryu=zrzu=xr
但是还没完,因为左手 Unity 的旋转是左手旋转,跟右手坐标系的旋转刚好相反。有两种方法可以解决这个问题,要么是旋转的角度取反,要么是旋转轴的向量取反。根据上面的公式,其实两种方法的结果都一样,都是对虚部全部取反。
因此最后正确的转换应为:
w u = w r x u = y r y u = − z r z u = − x r w_u = w_r \\ x_u = y_r \\ y_u = -z_r \\ z_u = -x_r wu=wrxu=yryu=−zrzu=−xr
得到的 q u = w r + y r i − z r j − x r k q_u = w_r + y_ri - z_rj - x_rk qu=wr+yri−zrj−xrk。
要把 q u q_u qu 转换为 q r q_r qr 的话,反过来就可以了。
扩展(其他坐标系形式的转换)
假如用到的左手和右手坐标系的对应关系跟前面说的不同,看到这里的话其实也能知道怎么自己推导了,就是换一下坐标轴而已。
更多推荐


所有评论(0)