判断 AR 中坐标系的姿态和位置的简单方法

2,299

AR 开发中经常遇到的问题是:我已经打开了 Debug 选项或者使用了 Debug 工具,但是如何看出坐标系的姿态和位置?怎么看出来哪个是 x 轴,哪个是 y 轴?

// Debug 选项,显示世界坐标的原点
var debugOptions: SCNDebugOptions = []
debugOptions.insert(ARSCNDebugOptions.showWorldOrigin)
sceneView.debugOptions = debugOptions

还有的问题是:我在 .scn/.dae 文件中调整 3D 模型时,x/y/z 位置怎么对应?欧拉角 x/y/z 又怎么区分正负?

坐标对应关系

先说明一下坐标的对应关系: 坐标轴一般是用颜色来区分的,(x,y,z) 轴对应 RGB 三种颜色。因为苹果在 AR/3D 中使用右手系,也可以用手指来表示:大拇指,食指,中指 分别对应 (x,y,z) 轴:

至于欧拉角的正负,也是用右手螺旋法则来判断:将右手大拇指对准转轴,其余手指的弯曲方向就是正方向:

World 与 Local

但是前面所讲的 Position 和 Euler 角度是相对于谁的呢?一般调整的是 Local ,即相对于父结点(parentNode)的,如果没有父结点,那就是相对于 scene.rootNode 的。

如下图,这个 .scn 文件内部的 camera,plane 等结点都是放在 scene.rootNode 下面的,由于 camera 的 Position 和 Euler 角度都是 0,所以相机和 scene.rootNode 坐标完全重合。

这里 plane 的 Position 为 (0,0,-10),即相对于父结点 scene.rootNode 在 z 轴负方向移动 10 米。这也意味着 plane 的 worldPosition 其实也是 (0,0,-10)。

又如下图中,plane 的父结点是 ship,ship 的父结点是 scene.rootNode。那么,当调整 plane 的 Position 和 Euler 都是相对于 ship 坐标系的。

无法目视检测的情况

当出现无法通过目视来检查坐标轴的情况时,我们也可以打印直接输出 Position 和 Euler 来判断位置。

那么如果只拿到了矩阵,如何通过用右手三根手指比划出 x,y,z 坐标轴的位置和方向来判断物体的位置与姿态?又要请出这幅图了:

由于 AR 中都是列主序的,那么矩阵的第一列前三个就是 x 轴的位置。最后一列则是位置信息。

对于 SCNMatrix 类型来说:m11,m12,m13 就是 x 轴在父坐标系中的方向;m21,m22,m23 就是 y 轴在父坐标系中的方向;m31,m32,m33就是 z 轴在父坐标系中的方向;m41,m42,m43就是坐标原点在父坐标系中的位置。

同理可知,simdfloat4x4 类型也是如此,column[0] 的前三个分量代表 x 轴在父坐标系中的方向......

知道了坐标轴的方向和位置,只需要再用右手比划一下,就能知道物体的位置和方向了。