7ff2e796df892ac8cffcbaa1cf995ee3
3D 布局小练习:如何在 AR 中给地球贴瓷砖?

说明

本文完成一个球形布局,借此说明 Xcode 中 3D 编辑器用法,及坐标转换 API 的使用。最终效果如图,将 48 个方形平面贴在球体表面:

3D 编辑器

首先,创建一个球体,半径为 2 米,供我们参考。(其实不创建也没关系)

然后添加第一块平面,修改它的大小和位置,将它放置在赤道位置,与 z 轴交点 2 米处,这样就完成了第一块平面的布局。

接下来的倾斜平面的放置有两种方式:模型坐标拖动平移借助子结点坐标转换

方案一:模型坐标拖动平移

思路是:

  • 先计算好下一块要放置的角度,设置好角度;
  • 然后直接拖动模型坐标轴,将其平移到与球面相切的位置。

水平角度,可以根据一圈要放置的数量来计算,这里我们选择 16 个,即 360 / 16 = 22.5,即每个小平面相差 22.5 度。竖直角度也是类似,这里演示第一块暂定为 0,即也放在赤道上。

非赤道位置,可以调整 x 轴欧拉角,如图:

这种方式简单快捷,但缺点也如图所示,手动拖动难以控制位置,想要精准放置在赤道处非常困难。除非提前计算好该角度下,(x,y,z)坐标的位置:当角度确定时,(x,y,z) 相互之间的比例是确定的,再配合三维距离 x*x + y*y + z*z = 2*2,可以精确求解出。

但这样又太过于复杂了,所以在 3D 编辑器中,还可以用第二种方案,借助子结点进行转换。

方案二:借助子结点坐标转换

思路是:

  • 先计算好下一块要放置的角度,设置好角度;
  • 然后借助子结点,调整其位置到与球面相交的位置上(沿平面坐标系 z 轴平移 2 米);
  • 记录子结点的 WorldPosition ,即子结点相对整个场景根结点坐标系的位置,也是子结点相对于平面坐标系的位置;
  • 将平面的 LocalPositon 移动到这个位置上(子结点原来的位置)。

这个方案,可以实现将平面移动到与球体相切的位置,缺点是借助了子结点(图中黑色立方体),有多余步骤。

代码编写

理解了上面的两种思路,我们完成可以通过代码调用 API 的方式,来避免 3D 编辑器中的弊端。

方案一:模型坐标API平移

思路是:

  • 先计算好下一块要放置的角度,设置好角度;
  • 然后 API 移动模型坐标轴,将平面沿自己 z 轴,平移到与球面相切的位置。
    核心代码:
    ```objc
    for (int i = 0; i < 48; i++) {
    // 计算行号和列号,类似 9 宫格布局
    CGFloat size = 0.7;//默认尺寸
    NSUInteger num = i % 16;//第几个
    NSUInteger line = i / 16;//第几行
    if (line == 0 || line == 2) {//最上面一行,最下面一行缩小一些
    size = 0.6;
    }
top Created with Sketch.