区块链技术博客
www.b2bchain.cn

第二章(1)、数学基础极简介绍:向量、矩阵、四元数求职学习资料

本文介绍了第二章(1)、数学基础极简介绍:向量、矩阵、四元数求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

3D 数学基础

3D 数学基础,本质就是线性代数和立体几何,在 SceneKit 中,我们只需要知道向量和三维坐标就能应付很多场景了,但是对于 Shader 来说,这是远远不够的。我们必须要掌握向量乘法(叉乘、点乘),矩阵含义与运算(乘法、求逆),还有四元数的简单了解。

不过,不用害怕,本章没有复杂的数学公式,而用到的运算也已经在 SIMD 框架中被封装好了,我们只需要了解它们是什么含义,如何使用就可以了。

需要说明的是,在 SceneKit 中使用的矩阵是右手系,列主序的,所以下面我们讲到的矩阵都是一样的。
示例代码见Chapter2/Chapter2_1文件夹。

本章中我们用到的都是 CPU 端的 Swift 代码,与 SceneKit 结合使用。在 GPU 端的 shader 代码(C++代码)中,不管是函数名还是使用方法,也是类似的。

向量

表示运动(位移):向 xx 方向移动 xx 距离,一般用方括号
表示位置(点的坐标):在原点的(x,y)位置处,一般用圆括号
使用时可以不区分,一般不会矛盾
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

向量加法:一般看做是连续运动;
也可以看做是相对位置,即以 A 点为原点,重新摆放 B 点的位置。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

向量点乘: w 在 v 方向的投影(分量)与 v 的长度相乘;
v 在 w 方向的投影,与 w 的长度相乘;
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
向量叉乘:得到新的向量,长度是平行四边形的面积,
方向垂直于 v,w 构成的平面。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

在实际应用中,点乘一般用来求夹角,或者判断朝向是不是一致。而叉乘一般用来求平面的法线,或者求旋转轴

苹果SIMD框架中自带了很多好用的函数:

// 向量规范化 public func simd_normalize(_ __x: simd_float2) -> simd_float2  // 点乘 public func simd_dot(_ __x: simd_float2, _ __y: simd_float2) -> Float  // 叉乘 public func simd_cross(_ __x: simd_float2, _ __y: simd_float2) -> simd_float3   // 向量长度 public func simd_length(_ __x: simd_float2) -> Float  // 向量长度平方 public func simd_length_squared(_ __x: simd_float2) -> Float  // 计算两个点的距离 public func simd_distance(_ __x: simd_float2, _ __y: simd_float2) -> Float  // 计算两个点的距离平方 public func simd_distance_squared(_ __x: simd_float2, _ __y: simd_float2) -> Float

矩阵

在 3D 中,我们一般使用的是 4×4 的矩阵,叫齐次矩阵。对于初学者来说,下图可以通俗地理解矩阵里面的一堆数,是干什么的:
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
矩阵在 3D 中可以从两方面理解:
表示运动:将物体从原点处初始姿态,旋转、缩放、平移到另一个位置,另一种姿态。从运动角度理解,矩阵乘法相当于连续运动的叠加。
表示姿态:相对于原点与 xyz 轴,处于什么姿态位置。从姿态角度理解,矩阵乘法相当于盒子的嵌套。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
矩阵乘法:矩阵乘法相当于连续运动的叠加,或者盒子的嵌套。也可以将后一个矩阵拆解为很多个向量,逐一进行矩阵变换。
矩阵的逆:从运动角度,可以理解为逆向运动;从盒子模型角度,可以理解为以自身姿态为基准,看坐标原点的姿态,即反转盒子的嵌套关系。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

简单的理解:SceneKit 中的 Node 可以想像成一个盒子,而矩阵就是这个盒子中真正决定盒子大小、朝向、位置的标准。如下图中,三个 Node 嵌套在一起,如果我们想用矩阵方法来求最里面 box3 的worldTransform,该怎么办呢?(当然,实际开发中 SCNNode 自带了worldTransform属性,可以直接使用;也可以使用convert方法来计算)

第二章(1)、数学基础极简介绍:向量、矩阵、四元数
实际上就是三个 box 的矩阵相乘就可以了,这里要注意顺序:左边的矩阵代表最外层的 box,右边的矩阵代表内层的 box。

let box3_worldTransform = box1.simdTransform * box2.simdTransform * box3.simdTransform print(box3_worldTransform) print(box3.simdWorldTransform)//与自带的simdWorldTransform比较  //输出 //simd_float4x4([[0.99999994, 0.0, 0.0, 0.0], [0.0, 0.99999994, 0.0, 0.0], [0.0, 0.0, 0.99999994, 0.0], [2.5, 3.5, 2.5, 1.0]]) //simd_float4x4([[0.99999994, 0.0, 0.0, 0.0], [0.0, 0.99999994, 0.0, 0.0], [0.0, 0.0, 0.99999994, 0.0], [2.5, 3.5, 2.5, 1.0]])

如果我想反过来,求 box2 在 box3 中的姿态( 即保持相对位置不变从 box3 的角度,看 box2 的姿态),应该是什么呢?没错,就是box3矩阵的逆(inverse):inverse(box3.transform)。 同理,box1在 box2中的姿态是:inverse(box2.transform),rootNode 在 box1 中的姿态是:inverse(box1.transform)。由此可得,rootNode 在 box3 中的姿态是:

// 注意顺序倒过来了,即最外层 `box3 中看 box2`,中间层`box2 中看 box1`,最内层`box1 中看 rootNode` let inverseBox3_worldTransform = simd_inverse(box3.simdTransform) * simd_inverse(box2.simdTransform) * simd_inverse(box1.simdTransform) print(inverseBox3_worldTransform) print(simd_inverse(box3_worldTransform))  //输出,因为浮点数误差,看上去不相等。实际是一样的 //simd_float4x4([[0.99999994, 0.0, 0.0, 0.0], [0.0, 0.99999994, 0.0, 0.0], [0.0, 0.0, 0.99999994, 0.0], [-2.4999998, -3.4999998, -2.4999998, 0.9999999]]) //simd_float4x4([[1.0000001, 0.0, 0.0, 0.0], [0.0, 1.0000001, 0.0, 0.0], [0.0, 0.0, 1.0000001, 0.0], [-2.5, -3.5000002, -2.5, 1.0]])

SIMD框架中自带了很多好用的矩阵相关函数:
“`swift
// 矩阵缩放
public func matrix_scale(_ __a: Float, _ __x: simd_float2x2) -> simd_float2x2

// 矩阵与实数乘法(全部缩放)
public func simd_mul(_ __a: Float, _ __x: simd_float2x2) -> simd_float2x2

// 矩阵与向量乘法
public func simd_mul(_ __x: simd_float2x2, _ __y: simd_float2) -> simd_float2
public func matrix_multiply(_ __x: simd_float2x2, _ __y: simd_float2) -> simd_float2

// 矩阵与矩阵乘法
public func simd_mul(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2
public func matrix_multiply(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2

// 两个矩阵线性插值
public func simd_linear_combination(_ __a: Float, _ __x: simd_float2x2, _ __b: Float, _ __y: simd_float2x2) -> simd_float2x2

// 矩阵相加
public func simd_add(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2

3D 数学基础

3D 数学基础,本质就是线性代数和立体几何,在 SceneKit 中,我们只需要知道向量和三维坐标就能应付很多场景了,但是对于 Shader 来说,这是远远不够的。我们必须要掌握向量乘法(叉乘、点乘),矩阵含义与运算(乘法、求逆),还有四元数的简单了解。

不过,不用害怕,本章没有复杂的数学公式,而用到的运算也已经在 SIMD 框架中被封装好了,我们只需要了解它们是什么含义,如何使用就可以了。

需要说明的是,在 SceneKit 中使用的矩阵是右手系,列主序的,所以下面我们讲到的矩阵都是一样的。
示例代码见Chapter2/Chapter2_1文件夹。

本章中我们用到的都是 CPU 端的 Swift 代码,与 SceneKit 结合使用。在 GPU 端的 shader 代码(C++代码)中,不管是函数名还是使用方法,也是类似的。

向量

表示运动(位移):向 xx 方向移动 xx 距离,一般用方括号
表示位置(点的坐标):在原点的(x,y)位置处,一般用圆括号
使用时可以不区分,一般不会矛盾
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

向量加法:一般看做是连续运动;
也可以看做是相对位置,即以 A 点为原点,重新摆放 B 点的位置。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

向量点乘: w 在 v 方向的投影(分量)与 v 的长度相乘;
v 在 w 方向的投影,与 w 的长度相乘;
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
向量叉乘:得到新的向量,长度是平行四边形的面积,
方向垂直于 v,w 构成的平面。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

在实际应用中,点乘一般用来求夹角,或者判断朝向是不是一致。而叉乘一般用来求平面的法线,或者求旋转轴

苹果SIMD框架中自带了很多好用的函数:

// 向量规范化 public func simd_normalize(_ __x: simd_float2) -> simd_float2  // 点乘 public func simd_dot(_ __x: simd_float2, _ __y: simd_float2) -> Float  // 叉乘 public func simd_cross(_ __x: simd_float2, _ __y: simd_float2) -> simd_float3   // 向量长度 public func simd_length(_ __x: simd_float2) -> Float  // 向量长度平方 public func simd_length_squared(_ __x: simd_float2) -> Float  // 计算两个点的距离 public func simd_distance(_ __x: simd_float2, _ __y: simd_float2) -> Float  // 计算两个点的距离平方 public func simd_distance_squared(_ __x: simd_float2, _ __y: simd_float2) -> Float

矩阵

在 3D 中,我们一般使用的是 4×4 的矩阵,叫齐次矩阵。对于初学者来说,下图可以通俗地理解矩阵里面的一堆数,是干什么的:
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
矩阵在 3D 中可以从两方面理解:
表示运动:将物体从原点处初始姿态,旋转、缩放、平移到另一个位置,另一种姿态。从运动角度理解,矩阵乘法相当于连续运动的叠加。
表示姿态:相对于原点与 xyz 轴,处于什么姿态位置。从姿态角度理解,矩阵乘法相当于盒子的嵌套。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
矩阵乘法:矩阵乘法相当于连续运动的叠加,或者盒子的嵌套。也可以将后一个矩阵拆解为很多个向量,逐一进行矩阵变换。
矩阵的逆:从运动角度,可以理解为逆向运动;从盒子模型角度,可以理解为以自身姿态为基准,看坐标原点的姿态,即反转盒子的嵌套关系。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

简单的理解:SceneKit 中的 Node 可以想像成一个盒子,而矩阵就是这个盒子中真正决定盒子大小、朝向、位置的标准。如下图中,三个 Node 嵌套在一起,如果我们想用矩阵方法来求最里面 box3 的worldTransform,该怎么办呢?(当然,实际开发中 SCNNode 自带了worldTransform属性,可以直接使用;也可以使用convert方法来计算)

第二章(1)、数学基础极简介绍:向量、矩阵、四元数
实际上就是三个 box 的矩阵相乘就可以了,这里要注意顺序:左边的矩阵代表最外层的 box,右边的矩阵代表内层的 box。

let box3_worldTransform = box1.simdTransform * box2.simdTransform * box3.simdTransform print(box3_worldTransform) print(box3.simdWorldTransform)//与自带的simdWorldTransform比较  //输出 //simd_float4x4([[0.99999994, 0.0, 0.0, 0.0], [0.0, 0.99999994, 0.0, 0.0], [0.0, 0.0, 0.99999994, 0.0], [2.5, 3.5, 2.5, 1.0]]) //simd_float4x4([[0.99999994, 0.0, 0.0, 0.0], [0.0, 0.99999994, 0.0, 0.0], [0.0, 0.0, 0.99999994, 0.0], [2.5, 3.5, 2.5, 1.0]])

如果我想反过来,求 box2 在 box3 中的姿态( 即保持相对位置不变从 box3 的角度,看 box2 的姿态),应该是什么呢?没错,就是box3矩阵的逆(inverse):inverse(box3.transform)。 同理,box1在 box2中的姿态是:inverse(box2.transform),rootNode 在 box1 中的姿态是:inverse(box1.transform)。由此可得,rootNode 在 box3 中的姿态是:

// 注意顺序倒过来了,即最外层 `box3 中看 box2`,中间层`box2 中看 box1`,最内层`box1 中看 rootNode` let inverseBox3_worldTransform = simd_inverse(box3.simdTransform) * simd_inverse(box2.simdTransform) * simd_inverse(box1.simdTransform) print(inverseBox3_worldTransform) print(simd_inverse(box3_worldTransform))  //输出,因为浮点数误差,看上去不相等。实际是一样的 //simd_float4x4([[0.99999994, 0.0, 0.0, 0.0], [0.0, 0.99999994, 0.0, 0.0], [0.0, 0.0, 0.99999994, 0.0], [-2.4999998, -3.4999998, -2.4999998, 0.9999999]]) //simd_float4x4([[1.0000001, 0.0, 0.0, 0.0], [0.0, 1.0000001, 0.0, 0.0], [0.0, 0.0, 1.0000001, 0.0], [-2.5, -3.5000002, -2.5, 1.0]])

SIMD框架中自带了很多好用的矩阵相关函数:
“`swift
// 矩阵缩放
public func matrix_scale(_ __a: Float, _ __x: simd_float2x2) -> simd_float2x2

// 矩阵与实数乘法(全部缩放)
public func simd_mul(_ __a: Float, _ __x: simd_float2x2) -> simd_float2x2

// 矩阵与向量乘法
public func simd_mul(_ __x: simd_float2x2, _ __y: simd_float2) -> simd_float2
public func matrix_multiply(_ __x: simd_float2x2, _ __y: simd_float2) -> simd_float2

// 矩阵与矩阵乘法
public func simd_mul(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2
public func matrix_multiply(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2

// 两个矩阵线性插值
public func simd_linear_combination(_ __a: Float, _ __x: simd_float2x2, _ __b: Float, _ __y: simd_float2x2) -> simd_float2x2

// 矩阵相加
public func simd_add(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2

3D 数学基础

3D 数学基础,本质就是线性代数和立体几何,在 SceneKit 中,我们只需要知道向量和三维坐标就能应付很多场景了,但是对于 Shader 来说,这是远远不够的。我们必须要掌握向量乘法(叉乘、点乘),矩阵含义与运算(乘法、求逆),还有四元数的简单了解。

不过,不用害怕,本章没有复杂的数学公式,而用到的运算也已经在 SIMD 框架中被封装好了,我们只需要了解它们是什么含义,如何使用就可以了。

需要说明的是,在 SceneKit 中使用的矩阵是右手系,列主序的,所以下面我们讲到的矩阵都是一样的。
示例代码见Chapter2/Chapter2_1文件夹。

本章中我们用到的都是 CPU 端的 Swift 代码,与 SceneKit 结合使用。在 GPU 端的 shader 代码(C++代码)中,不管是函数名还是使用方法,也是类似的。

向量

表示运动(位移):向 xx 方向移动 xx 距离,一般用方括号
表示位置(点的坐标):在原点的(x,y)位置处,一般用圆括号
使用时可以不区分,一般不会矛盾
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

向量加法:一般看做是连续运动;
也可以看做是相对位置,即以 A 点为原点,重新摆放 B 点的位置。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

向量点乘: w 在 v 方向的投影(分量)与 v 的长度相乘;
v 在 w 方向的投影,与 w 的长度相乘;
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
向量叉乘:得到新的向量,长度是平行四边形的面积,
方向垂直于 v,w 构成的平面。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

在实际应用中,点乘一般用来求夹角,或者判断朝向是不是一致。而叉乘一般用来求平面的法线,或者求旋转轴

苹果SIMD框架中自带了很多好用的函数:

// 向量规范化 public func simd_normalize(_ __x: simd_float2) -> simd_float2  // 点乘 public func simd_dot(_ __x: simd_float2, _ __y: simd_float2) -> Float  // 叉乘 public func simd_cross(_ __x: simd_float2, _ __y: simd_float2) -> simd_float3   // 向量长度 public func simd_length(_ __x: simd_float2) -> Float  // 向量长度平方 public func simd_length_squared(_ __x: simd_float2) -> Float  // 计算两个点的距离 public func simd_distance(_ __x: simd_float2, _ __y: simd_float2) -> Float  // 计算两个点的距离平方 public func simd_distance_squared(_ __x: simd_float2, _ __y: simd_float2) -> Float

矩阵

在 3D 中,我们一般使用的是 4×4 的矩阵,叫齐次矩阵。对于初学者来说,下图可以通俗地理解矩阵里面的一堆数,是干什么的:
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
矩阵在 3D 中可以从两方面理解:
表示运动:将物体从原点处初始姿态,旋转、缩放、平移到另一个位置,另一种姿态。从运动角度理解,矩阵乘法相当于连续运动的叠加。
表示姿态:相对于原点与 xyz 轴,处于什么姿态位置。从姿态角度理解,矩阵乘法相当于盒子的嵌套。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数
矩阵乘法:矩阵乘法相当于连续运动的叠加,或者盒子的嵌套。也可以将后一个矩阵拆解为很多个向量,逐一进行矩阵变换。
矩阵的逆:从运动角度,可以理解为逆向运动;从盒子模型角度,可以理解为以自身姿态为基准,看坐标原点的姿态,即反转盒子的嵌套关系。
第二章(1)、数学基础极简介绍:向量、矩阵、四元数

简单的理解:SceneKit 中的 Node 可以想像成一个盒子,而矩阵就是这个盒子中真正决定盒子大小、朝向、位置的标准。如下图中,三个 Node 嵌套在一起,如果我们想用矩阵方法来求最里面 box3 的worldTransform,该怎么办呢?(当然,实际开发中 SCNNode 自带了worldTransform属性,可以直接使用;也可以使用convert方法来计算)

第二章(1)、数学基础极简介绍:向量、矩阵、四元数
实际上就是三个 box 的矩阵相乘就可以了,这里要注意顺序:左边的矩阵代表最外层的 box,右边的矩阵代表内层的 box。

let box3_worldTransform = box1.simdTransform * box2.simdTransform * box3.simdTransform print(box3_worldTransform) print(box3.simdWorldTransform)//与自带的simdWorldTransform比较  //输出 //simd_float4x4([[0.99999994, 0.0, 0.0, 0.0], [0.0, 0.99999994, 0.0, 0.0], [0.0, 0.0, 0.99999994, 0.0], [2.5, 3.5, 2.5, 1.0]]) //simd_float4x4([[0.99999994, 0.0, 0.0, 0.0], [0.0, 0.99999994, 0.0, 0.0], [0.0, 0.0, 0.99999994, 0.0], [2.5, 3.5, 2.5, 1.0]])

如果我想反过来,求 box2 在 box3 中的姿态( 即保持相对位置不变从 box3 的角度,看 box2 的姿态),应该是什么呢?没错,就是box3矩阵的逆(inverse):inverse(box3.transform)。 同理,box1在 box2中的姿态是:inverse(box2.transform),rootNode 在 box1 中的姿态是:inverse(box1.transform)。由此可得,rootNode 在 box3 中的姿态是:

// 注意顺序倒过来了,即最外层 `box3 中看 box2`,中间层`box2 中看 box1`,最内层`box1 中看 rootNode` let inverseBox3_worldTransform = simd_inverse(box3.simdTransform) * simd_inverse(box2.simdTransform) * simd_inverse(box1.simdTransform) print(inverseBox3_worldTransform) print(simd_inverse(box3_worldTransform))  //输出,因为浮点数误差,看上去不相等。实际是一样的 //simd_float4x4([[0.99999994, 0.0, 0.0, 0.0], [0.0, 0.99999994, 0.0, 0.0], [0.0, 0.0, 0.99999994, 0.0], [-2.4999998, -3.4999998, -2.4999998, 0.9999999]]) //simd_float4x4([[1.0000001, 0.0, 0.0, 0.0], [0.0, 1.0000001, 0.0, 0.0], [0.0, 0.0, 1.0000001, 0.0], [-2.5, -3.5000002, -2.5, 1.0]])

SIMD框架中自带了很多好用的矩阵相关函数:
“`swift
// 矩阵缩放
public func matrix_scale(_ __a: Float, _ __x: simd_float2x2) -> simd_float2x2

// 矩阵与实数乘法(全部缩放)
public func simd_mul(_ __a: Float, _ __x: simd_float2x2) -> simd_float2x2

// 矩阵与向量乘法
public func simd_mul(_ __x: simd_float2x2, _ __y: simd_float2) -> simd_float2
public func matrix_multiply(_ __x: simd_float2x2, _ __y: simd_float2) -> simd_float2

// 矩阵与矩阵乘法
public func simd_mul(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2
public func matrix_multiply(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2

// 两个矩阵线性插值
public func simd_linear_combination(_ __a: Float, _ __x: simd_float2x2, _ __b: Float, _ __y: simd_float2x2) -> simd_float2x2

// 矩阵相加
public func simd_add(_ __x: simd_float2x2, _ __y: simd_float2x2) -> simd_float2x2

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 第二章(1)、数学基础极简介绍:向量、矩阵、四元数求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们