只需三板斧!带你入门 visionOS 空间计算的数学与几何基础

说明

本文来自于我在 Let's VisionOS 2024 大会上的演讲,原演讲内容分为两个方面:向量与矩阵基础知识手势匹配框架 HandVector。为了便于阅读,我对原演讲内容进行了调整与简化,改写为了两篇文章《只需三板斧!带你入门 visionOS 空间计算的数学与几何基础》和《我开源了个手势匹配框架,让你在模拟器调试 visionOS 手部追踪功能!》。

可在 此处 获得 Keynotes 的 PDF 版本。

正文

看不懂苹果 visionOS Demo 中的数学与几何运算?这是很多 iOS 开发者试图学习 visionOS 开发时遇到的最大困难。我周围也有很多人也试图去学习计算几何相关知识,但是却被相关书籍和视频教程陡峭的入门曲线吓退。

本质上,这是因为普通开发者缺少"敲门砖"与"三板斧",导致难以入门。我自己作为一名 iOS 开发者,也曾面临这样的问题,所以我将 3D/AR 中基础的数学与几何运算做了整理,选出了向量与矩阵最常见的三种运算,做为入门学习的 "敲门砖""三板斧",带领大家顺利入门。为了形象说明运算的作用,我们将各种运算用图形化方式来呈现准确说明它们的几何意义,并对苹果 Demo 中的运算作用进行讲解,帮助大家更好入门。

坐标系,点与向量

在 RealityKit 中,我们使用的是右手系,也就是与右手的三根手指完美对应。

点与向量的定义

在这样一个坐标系中,一个变量 let a = simd_float3(1, 2, 3) ,它可以看作是一个点的位置,也可以当做一个向量,但是一但按规则进行运算后不可随意更改几何含义。

运算规定: 点与向量的运算规律如下:

  • vector + vector = vector
  • point - point = vector
  • point + vector = point
  • point + point = ?? => (point + point)/2 = middle point

从数学运算角度,为了统一进行运算会将其补成 4 维,点后面补 1,向量后面补 0:

ini 复制代码
3D point  = (x, y, z, 1)
3D vector = (x, y, z, 0)

同样,在 RealityKit 中,点与向量的转换函数也是不同的:

常用向量运算

常见向量运算三板斧:

  • 向量点乘:dot(a, b) => a · b
  • 向量叉乘:cross(a, b) => a × b
  • 向量归一化:normalize(a) => a/||a||

点乘的几何意义

  • 一个向量在另一个向量上的投影长
  • 点乘的大小也反映了两个向量有多"平行",一般配合归一化(normalize)
  • 交换律:a · b = b · a
  • 分配律:a · (b + c) = a · b + a · c

比如,在苹果的 Demo SwiftSplash 中的吸附对齐功能,就是用点乘和归一化实现的: 具体的代码如下,先用位置坐标相减得到两个向量,然后将它们归一化之后再点乘,如果大于 0.95 或小于 -0.95 就会自动吸附。

叉乘的几何意义

  • 结果是一个新的向量,方向垂直于运算的两个向量,右手螺旋法则
  • 叉乘的大小也反映了两个向量有多"垂直", 长度等于围成的平行四边形的面积
  • 反交换律:a × b = - b × a
  • 分配律:a × (b + c) = a × b + a × c

叉乘在实际开发中一般有两个用途:1.用来求平面的法线,2.求向量围成的面积。比如在苹果 Demo Happy Beam 中,手势比心后,光柱的方向就是用叉乘来确定的。 其中,将大拇指根部连线作为 x 轴方向,将大拇指指尖到食指指尖方向作为 y 轴,叉乘后的负方向就是光柱的方向。

矩阵

  • 包含了坐标系的位置、朝向和大小信息
  • 具体有 xyz 轴的向量,及原点坐标
  • RealityKit 中 Entity 包含了矩阵信息

开发中一般使用 4x4 矩阵,它其实就是将坐标系的位置和坐标轴依次写下来:前三列分别是 XYZ 轴的向量,最后一列是原点的位置。其中向量后面补 0,而位置后面补 1,这样可以统一运算。 在苹果 Demo Happy Beam 中,也用到了从手部矩阵中获取位置的方法:matrix.colunms.3.xyz 就得到了矩阵的位置信息。
在对位置信息进行一系列运算后,重新得到了新的 XYZ 轴向量,以及中心点坐标,就可以重新合成得到比心的手势的矩阵。

常用矩阵运算

  • 矩阵乘法:m1 * m2
  • 矩阵的逆:m.inverse
  • 矩阵的反转(镜像):entity.scale *= .init(x: -1, y: 1, z: 1)

矩阵乘法 multiply

  • 类似盒子的嵌套
  • 用在不同层级物体之间,将子级坐标转换为父级坐标

假如在 Cube_1 中有一个点 a: (1, 2, 3) 那么它在 Cube_0 中的坐标为:matrix_cube_1 * (1, 2, 3, 1) 在 Root 中的坐标为:matrix_cube_0 * matrix_cube_1* (1, 2, 3, 1)

矩阵的逆 inverse

  • 一般用在同层级的物体之间
  • 将兄弟关系变成父子关系

比如,下面的例子,将橙色盒子中的坐标转换到紫色盒子中,就需要用到矩阵的逆: 假如在 Cube_1 中有一个点 a: (1, 2, 3) 那么它在 Cube_0 中的坐标为:matrix_cube_1 * (1, 2, 3, 1) 在 Cube_2 中的坐标为:matrix_cube_2.inverse * matrix_cube_1* (1, 2, 3, 1)

矩阵反转/镜像 reflection/mirror

  • 会将右手系变成左手系,同时造成内外表面反转
  • 除非明确了解矩阵反转的含义,否则不要轻易进行反转操作
  • 反转任意两根坐标轴,等同于绕不变的轴旋转 180 度
swift 复制代码
//左侧 Enity,反转 x 轴,造成了内外表面反转
entityLeft.scale *= .init(x: -1, y: 1, z: 1)
//右侧 Enity,反转 x 轴 和 y 轴,等同于绕 z 轴旋转 180 度
entityRight.scale *= .init(x: -1, y: -1, z: 1)

在苹果 Demo Hello World 中,星空背景就是用这种方式实现的。 相关代码如下,关键之处在于倒数第二行:

总结

掌握了向量运算三板斧+矩阵运算三板斧,无需再害怕空间计算中的数学公式。 更多关于 HandVector 的效果演示与计算讲解,请查看《我开源了个手势匹配框架,让你在模拟器调试 visionOS 手部追踪功能!》文章。

感谢主办方的精心组织,希望 Let's VisionOS 活动未来更上一层楼。

相关推荐
学步_技术4 天前
利用AI增强现实开发:基于CoreML的深度学习图像场景识别实战教程
人工智能·深度学习·ar·增强现实·coreml
斯裕科技5 天前
新升级|优化航拍/倾斜模型好消息,支持处理多套贴图模型!
unity·ue5·3dsmax·虚拟现实·maya·增强现实
Successssss~11 天前
【高校主办,EI稳定检索】2024年人机交互与虚拟现实国际会议(HCIVR 2024)
计算机视觉·人机交互·vr·虚拟现实·增强现实
学步_技术1 个月前
增强现实系列—深入探索ARKit:平面检测、三维模型放置与增强现实交互
机器学习·计算机视觉·交互·增强现实·虚拟现实技术·平面检测·vr/ar
Uncertainty!!1 个月前
初识增强现实(AR)
ar·增强现实
VRARvrnew3d2 个月前
轨道交通AR交互教学定制公司优选深圳华锐视点
ar·增强现实·轨道交通·ar公司·ar教学
VRARvrnew3d2 个月前
AR增强现实汽车装配仿真培训系统开发降低投入费用
ar·增强现实·汽车导航·ar仿真培训
苹果API搬运工2 个月前
试玩 RealityComposerPro 中的 Shader Graph:不同噪声图像 Noise 可视化
增强现实
苹果API搬运工3 个月前
试玩 visionOS 2 上的 LowLevelMesh 与 Compute Shader:模拟布料旗子
增强现实
苹果API搬运工3 个月前
36-AR 中的人物
增强现实