AMD FidelityFX™ Parallel Sort
AMD FidelityFX Parallel Sort 使 GPU 上的数据排序更快、更容易。使用我们的 SM6.0 计算着色器来排序您的数据。
本页内容
本文的主要目标是将计算机图形学中的变换知识整合到一个单一的、全面的资源中。
尽管这些概念在线上广泛可用,但它们通常以零散的片段呈现,缺乏对其细微之处的连贯解释。本文旨在弥补这些不足,并提供对该主题的透彻理解。
许多现实世界的问题乍一看似乎很简单,但仔细检查后会发现其潜在的复杂性。为了全面探讨这些挑战,我们将采用著名的**分而治之**技术。通过将这个复杂的问题分解成更小的子问题并逐个解决,我们可以创建一个结构化的参考指南。
这种方法将为计算机图形学中变换中经常遇到的挑战带来清晰和条理。
这些子问题可以从数学(理论)和实现(实践)的角度进行分类,如下所示:
矩阵乘法的顺序:确保操作遵循一致的排序规则。
三维欧几里得空间的手性:确定方向约定,例如右手定则。
笛卡尔坐标系中基向量的顺序:确定定义轴的顺序。
将矩阵存储在内存中作为多维数组:优化内存表示以实现高效计算。
在本文中,我们将深入探讨矩阵及其属性。在深入了解细节之前,让我们简要回顾一些对于理解其细微差别至关重要的基础概念。
在数学中,矩阵本质上是组织成行和列的数字的矩形数组。
例如,下面的矩阵有**3 行**和**5 列**,可以称为一个3×5 矩阵
答案可以总结为以下几点:
它们作为一种出色的代数工具,以结构化的方式表示几何图形。
三维欧几里得空间中的变换,如仿射变换和投影变换,可以使用4×4 矩阵来表示。
变换的连接,或两个变换的组合,可以用矩阵乘法来表示。
行或列只有一个的矩阵(换句话说,行向量或列向量)可以存储网格顶点。
将网格顶点从一个空间变换到另一个空间,再次使用了矩阵乘法。
矩阵本身以及对矩阵进行的操作可以在计算机图形应用程序中高效实现。
矩阵乘法的算法不像矩阵加法那样直接,在矩阵加法中,两个矩阵的对应元素逐个相加。相反,它稍微复杂一些,涉及到通过一系列操作组合行和列。
为了说明这个概念,请考虑以下可视化:

矩阵 C 中每个元素的值是通过将矩阵 A 的第 i 行的每个对应项与矩阵 B 的第 j 列相乘并对这些乘积求和来计算的。本质上,这个操作等同于执行矩阵 A 的第 i 行与矩阵 B 的第 j 列之间的**点积**。
请注意:
矩阵乘法通常**不可交换**——乘法中乘数的顺序很重要。
要使矩阵乘法有效,第一个矩阵(运算符左侧)的**列数**必须等于第二个矩阵(运算符右侧)的**行数**。
在完成了初步的解释之后,我们可以将注意力转移到本文的核心内容。
现在我们理解了矩阵乘法,就可以讨论它的顺序了。计算机图形学中变换的一个关键但常常被忽视的方面是,矩阵乘法通常是不可交换的。
我们已经习惯了实数乘法是可交换的事实。因此,当我们学习矩阵时,矩阵乘法是不可交换的,这会令人惊讶,并且常常导致实践中的错误。
其中 A 和 B 是矩阵。
为了最大程度地减少实践中的挑战,已经出现了两种不同的方法或约定,每种都提供了一种确保矩阵乘法一致且正确应用的方法。
在计算机图形学中,这些约定被称为
前乘变换 (Pre-multiplication Transformation)
后乘变换 (Post-multiplication Transformation)
值得注意的是,前乘和后乘的术语有些作者在使用,但并非普遍。
例如,在线性代数中,在求解方程组时,向量通常被视为列向量,这导致教科书倾向于使用后乘顺序。
在计算机图形学应用中,平移、旋转、缩放和剪切等变换被组合起来创建逼真的虚拟世界。这些变换使用 4×4 矩阵表示,将它们组合起来相当于矩阵相乘。
选择并一致地应用正确的顺序以获得预期结果至关重要。
虽然矩阵乘法是不可交换的,但它仍然是结合的
(A∗B)∗C=A∗(B∗C)在下面的示例中,括号仅用于指示组合变换的顺序。
让我们通过以下示例来描述变换连接的矩阵乘法顺序问题
Z=A∗B∗C∗D其中 A, B, C, D, Z 是矩阵。
括号有助于清晰地指示操作的顺序。在数学中,乘法通常假定从左到右进行。
两种约定的区别总结在下表中
| 后乘 (Post-multiplication) | 前乘 (Pre-multiplication) | |
|---|---|---|
| 操作顺序 (Order of operations) | Z=A⋅B⋅C⋅D=A⋅(B⋅(C⋅D)) | Z=A⋅B⋅C⋅D=((A⋅B)⋅C)⋅D |
| 变换一个向量 (Transforming a vector) | Vw=M⋅Vc | Vw=Vc⋅M |
| 向量表示 | xyzw=m11m21m31m41m12m22m32m42m13m23m33m43m14m24m34m44⋅v1v2v3v4 | [xyzw]=[v1v2v3v4]⋅m11m12m13m14m21m22m23m24m31m32m33m34m41m42m43m44 |
| 最终变换矩阵 | Mf=Mp⋅Mv⋅Mm | Mf=Mm⋅Mv⋅Mp |
| 世界矩阵构成 | Mw=Ma⋅Ml | Mw=Ml⋅Ma |
| 局部变换矩阵 | Ml=Mt⋅Mr⋅Ms | Ml=Ms⋅Mr⋅Mt |
| 局部变换矩阵 | Ml=Mt⋅Mr⋅Mh⋅Ms | Ml=Ms⋅Mh⋅Mr⋅Mt |
| 约定带来的影响 | 变换的组合是从右到左 | 变换的组合是从左到右 |
| 约定带来的影响 | 矩阵在列主序布局中的存储偏好 | 矩阵在行主序布局中的存储偏好 |
| 约定带来的影响 | 网格顶点被视为列向量 | 网格顶点被视为行向量 |
其中
Vw = 另一个空间中的变换后的向量。
Vc = 原始空间中的变换后的向量。
M = 变换矩阵。
Mf = 最终变换矩阵。
Mm = 模型变换矩阵(将模型从局部空间变换到全局世界空间)。
Mv = 视图矩阵(将世界空间变换到相机空间)。
Mp = 投影矩阵(将相机空间变换到裁剪空间)。
Mw = 世界变换矩阵。
Ml = 当前局部变换矩阵。
Ma = 父节点的变换矩阵。
Ms = 缩放矩阵。
Mr = 旋转矩阵。
Mt = 平移矩阵。
Mh = 切变矩阵。
在讨论三维欧几里得空间的方向问题之前,还有一个问题需要提及和描述:即“向上方向”的轴约定。
在数学上,三维欧几里得空间中的任何一个轴本身并没有被指定为向上方向。
然而,在3D应用中,多年来出现了两种约定。
Z轴作为“向上方向”
这种约定在建筑等领域尤其有用。当工作空间是一个表示地表(例如地球表面)的平面时,两个主要工作方向是X轴和Y轴,而Z轴表示高度或“向上方向”。

Y轴作为“向上方向”
在此约定中,工作平面对应于显示器屏幕。X轴和Y轴分别表示屏幕的宽度和高度,而Z轴表示深度。这种设置符合我们对世界的日常感知,例如在第一人称射击(FPS)游戏中,Y轴表示“向上方向”。

在计算机图形学中,特别是在三维欧几里得空间中,叉积是一个非常有用且常见的操作。两个非共线向量的叉积会得到另一个垂直于两个原始向量的向量。
这个操作会引入歧义,因为结果向量的方向没有唯一的解——它可以指向两个同样有效的方向。为了解决这种歧义,我们为三维欧几里得空间选择一个方向(或手性)。通过做出这个选择,我们指定一个叉积方向作为首选解。

为了获得唯一且一致的结果,我们使用右手定则或左手定则。
值得一提的是,在数学和物理学中,右手定向是最常用的。这种定向用于确定磁场、电磁场以及化学中的对映异构体的方向。
| 左手定则 | 右手定则 |
|---|---|
![]() | ![]() |
右手定则和左手定则可以描述如下:
让所选手(右手或左手)伸直的食指指向第一个向量(a的方向,让弯曲的中指指向第二个向量(b)。最后,伸直的拇指将指示叉积向量a×b。
为了确定三维欧几里得空间中X、Y和Z轴的方向,将第一个向量替换为X轴的方向,将第二个向量替换为Y轴的方向。然后拇指将指向Z轴的方向。
使用这种方法,我们可以为三维欧几里得空间指定所需手性(方向)。方向,右手或左手,可以在下表中总结(如果适用)。
| 手性 | 左手定则 | 右手定则 |
|---|---|---|
| Y轴向上 | ![]() | ![]() |
| Z轴向上 | ![]() | ![]() |
选择手性至关重要,因为它不仅决定了叉积向量的方向,还决定了:
表面法向量的方向。
点绕轴旋转的方向。
三角形网格中顶点的顺序。
| 左手定则 | 右手定则 |
|---|---|
![]() | ![]() |
![]() | ![]() |
两个非共线向量叉积的另一个关键性质是反对称性。
a×b=−b×a如果你需要通过反转叉积的结果来修正渲染错误,请记住,你并不是简单地为向量加上一个*负号*。相反,你改变了三维欧几里得空间的“手性”。
| 左手定则 | 右手定则 |
|---|---|
![]() | ![]() |
这个主题应该在引入欧几里得空间的“手性”概念之前介绍,因为两者密切相关。它通常在线性代数课程中较早讲授。然而,现在描述它将更容易理解。
基向量的概念在许多线性代数教科书中常常被隐藏在阴影中,尽管它对线性代数和向量空间至关重要,但其重要性却经常被忽视。
例如,在三维欧几里得空间中,以下基向量
构成欧几里得空间的*基石*。它们允许该空间中的任何向量用这些基向量来描述。
然而,定义基向量只是过程的一部分——还必须确定它们的顺序,明确哪个向量被指定为第一、第二和第三。例如:
| e0,e1,e2 | e0,e2,e1 |
|---|---|
![]() | ![]() |
基向量的顺序很重要,因为由不同顺序定义的坐标系虽然看起来相似,但它们并非相同,并且在细微之处存在差异。
{e0,e1,e2}={e0,e2,e1}当基向量及其顺序确定后,我们就建立了笛卡尔坐标系。这使得我们能够唯一地确定空间中点的位置,并定义正方向——即当角度增加时旋转的方向。
从数学和计算的角度来看,基向量没有普遍更好或更差的排序。然而,物理学家始终使用右手定则,这是一种基于与叉积向量方向相同原理的约定。该规则消除了歧义,促进了协作,并确保了不同贡献者之间计算的一致性。
不幸的是,计算机图形学中缺乏标准化的框架,增加了出错的可能性。本文旨在强调解决这一问题的重要性。
正方向的概念指的是旋转方向,该方向是通过从选定的*第一个*基向量(或坐标系轴)开始,并朝着*第二个*基向量的方向移动而建立的。
从视觉上看,这可以很容易地在二维欧几里得空间中解释,如下表所示:
| 基向量顺序 e0,e1 或 X→Y | 基向量顺序 e1,e0 或 Y→X |
|---|---|
| 逆时针旋转 | 顺时针旋转 |
| 从 X 轴到 Y 轴 | 从 Y 轴到 X 轴 |
![]() | ![]() |
这说明了基向量顺序为何很重要。
为了在二维或三维欧几里得空间中描述旋转,通常会使用旋转矩阵。然后,该矩阵用于将向量(或被视为向量的点)按指定角度旋转。
通过将向量乘以矩阵来实现旋转。如我们所见,矩阵乘法不满足交换律,因此存在两种旋转约定:前乘和后乘。
基向量的顺序在定义旋转时起着微妙的作用。例如,相同的旋转矩阵
R=[cos(ϕ)sin(ϕ)−sin(ϕ)cos(ϕ)]根据其在前乘或后乘中的使用情况,会确定不同基向量顺序下的旋转正方向。
在二维情况下,这与 e0,e1 或 e1,e0
| 后乘约定 v’=R∗v | 前乘约定 v’=v∗R |
|---|---|
| 逆时针旋转 | 顺时针旋转 |
| 基向量顺序 e0,e1 或 X→Y | 基向量顺序 e1,e0 或 Y→X |
![]() | ![]() |
在确定空间中一个点的位置和唯一的旋转正方向时,保持基向量顺序概念的一致性至关重要。
为确保一致性,旋转矩阵的具体形式必须与特定的基向量顺序以及选择的矩阵乘法约定相对应。
所有这些选项都可以在下表中进行总结
| 基向量顺序 e0,e1 或 X→Y | 基向量顺序 e1,e0 或 Y→X | |
|---|---|---|
| 后乘约定 | [cos(ϕ)−sin(ϕ)sin(ϕ)cos(ϕ)] | [cos(ϕ)sin(ϕ)−sin(ϕ)cos(ϕ)] |
| 预乘约定 | [cos(ϕ)sin(ϕ)−sin(ϕ)cos(ϕ)] | [cos(ϕ)−sin(ϕ)sin(ϕ)cos(ϕ)] |
为了确定正向旋转,在三维欧几里得空间中,我们可以使用类似于叉乘的手部规则。
在这种情况下,右手定则和左手定则可以描述如下:
弯曲的手指指向正向,拇指指示旋转轴。
或
将拇指指向旋转轴,弯曲的手指将指示正向。
让我们通过下表来说明这些规则。
| 左手旋转轴 | 右手旋转轴 |
|---|---|
![]() | ![]() |
在三维欧几里得空间中,我们遇到了基向量顺序的几种可能排列。幸运的是,这些排列可以分为两组基向量顺序。
以下表格旨在说明基向量顺序——以及由此产生的旋转正方向——可能显得复杂且难以理解。
| 左手定则 | 右手定则 | |||
|---|---|---|---|---|
| (X,Y,Z) | (X,Z,Y) | (X,Y,Z) | (X,Z,Y) | |
| Y-向上 | ![]() | ![]() | ![]() | ![]() |
| Z-向上 | ![]() | ![]() | ![]() | ![]() |
各种可能的用例增加了犯错的可能性。我们如何总结上面的表格?分析完每种情况后,用于确定基向量顺序(从而确定旋转正方向)以及向量积方向的手会发生变化。在某些情况下需要不同的手,而在其他情况下则使用同一只手。下表提供了这些情况的摘要
| 基向量顺序组: (X,Y,Z) | 基向量顺序组: (X,Z,Y) | |
|---|---|---|
| 右手定则用于计算叉乘 | 叉乘方向和正方向使用相同的定则 | 叉乘方向和正方向使用相反的定则 |
| 左手定则用于计算叉乘 | 叉乘方向和正方向使用相同的定则 | 叉乘方向和正方向使用相反的定则 |
保持基向量顺序的一致性对于确定空间中的点位置和旋转的正方向至关重要。只有基向量顺序来自 (X,Y,Z)组才能满足这些标准。
最后,三维欧几里得空间中的正方向在下表中进行了说明
| 左手定则 | 右手定则 | |
|---|---|---|
| Y-向上 | ![]() | ![]() |
| Z-向上 | ![]() | ![]() |
考虑一下:如果您在一个 Y-向上左手坐标系中创建一个模型,但将其渲染在一个 Z-向上左手坐标系中,交换 Y 和 Z 坐标似乎是一个简单的修复。
然而,这种调整由于正方向和基向量顺序的变化,会隐含地改变平面法向量、三角形网格缠绕顺序以及相关动画数据等元素。
基向量的顺序也会影响四元数。当 W. R. Hamilton 发明四元数来描述三维欧几里得空间中的旋转时,他将其定义为 Q=a+bi+cj+dk,并建立了虚数分量之间的依赖关系:ij=k,jk=i,ki=j,以及ijk=−1。当四元数使用这些规则定义时,旋转的正方向由右手定则确定。然而,在计算机图形学中,存在一些应用程序使用左手定则来确定正方向。这就引发了一个问题:如何处理以这种方式定义的四元数?
M.D. Shuster 提出的约定不改变四元数本身的根本定义,而是修改其对虚数分量的依赖。这种方法与数学教科书中典型的四元数定义略有不同。值得注意的是,Shuster 的定义被 NASA 的喷气推进实验室使用,并在计算机图形学中,被 Microsoft DirectX 数学库使用。
Hamilton 和 Shuster 的四元数定义之间的区别在下表中进行了总结
| Hamilton 的定义 | Shuster 的定义 | |
|---|---|---|
| 虚数分量依赖关系 | ij=k jk=i ki=j ijk=−1 | ij=−k jk=−i ki=−j ijk=1 |
| 正方向 | 由右手定则确定 | 由左手定则确定 |
| 矩阵乘法顺序 | 后乘 (Post-multiplication) | 前乘 (Pre-multiplication) |
| “三明治”乘积顺序 | v’=QvQ−1 | v’=Q−1vQ |
| 旋转矩阵 | R=[1−2(Qy2+Qz2)2(QxQy−QzQw)2(QxQz+QyQw) 2(QxQy+QzQw)1−2(Qx2+Qz2)2(QyQz−QxQw) 2(QxQz−QyQw)2(QyQz+QxQw)1−2(Qx2+Qy2)] | R=[1−2(Qy2+Qz2)2(QxQy+QzQw)2(QxQz−QyQw) 2(QxQy−QzQw)1−2(Qx2+Qz2)2(QyQz+QxQw) 2(QxQz+QyQw)2(QyQz−QxQw)1−2(Qx2+Qy2)] |
为了总结正向概念,这里有一个关于应用程序(用于动画或模型的游戏引擎或软件工具)的表格,它们使用不同的三维空间方向并指定了“向上”轴
| Orientation | 左手定则 | 右手定则 |
|---|---|---|
| Y-Up (Y轴向上) | LightWave ZBrush Cinema 4D Unity | Autodesk Maya Modo Houdini 3D Animation Tool Substance Painter Marmoset Toolbag Godot OGRE |
| Z-Up (Z轴向上) | Unreal Engine* Open 3D Engine | Autodesk 3ds Max Blender SketchUp Autodesk AutoCAD CRYENGINE UNIGINE |
Unreal Engine 根据旋转轴使用两种手性规则。例如:
X 和 Y-轴:右手定则
Z-轴:左手定则

我们现在转向一个严格与实现相关的话题。
从矩阵的定义来看,矩阵是一个二维数学对象(它有行和列的维度),但计算机内存是以一维数组的线性方式运行的。

我们如何才能在计算机内存中表示这个矩阵呢?
一个常见的解决方案是使用多维数组。这些数组可以以不同的方式映射到计算机内存,每种方式都有其独特的优点和缺点。
最简单和最常用的方法是**行优先**(row-major)和**列优先**(column-major)约定,即矩阵按行或按列存储。
| 行优先 | 列优先 | |
|---|---|---|
| 示例 3×5 矩阵 | ![]() | ![]() |
| 示例 4×4 矩阵 | ![]() | ![]() |
我们有两种存储矩阵的方法,每种编程语言都必须决定在多维数组表示中采用哪一种。
下表总结了一些流行编程语言实现这些约定的方式
| 存储顺序 | 编程语言 |
|---|---|
| 行布局顺序 | C C++ Python (NumPy) Java Rust HLSL(默认或使用 GLSL(使用 |
| 列布局顺序 | Fortran Matlab Julia HLSL(使用 GLSL(默认或使用 |
大多数广泛使用的语言倾向于**行优先**顺序,而专注于数值或科学计算的语言则经常优先考虑**列优先**顺序。
数据存储约定不可避免地与变换相关。
例如,在平移矩阵中,平移向量存储在第三行或第三列,具体取决于乘法顺序。
| 前置乘法 | 后置乘法 |
|---|---|
![]() | ![]() |
两种乘法顺序和两种存储约定会产生四种存储平移矩阵的方式
| **前置乘法** | **前置乘法** | **后置乘法** | **后置乘法** |
| 行优先 | 列优先 | 行优先 | 列优先 |
|---|---|---|---|
![]() | ![]() | ![]() | ![]() |
出于性能原因,最好读取或写入相邻的内存元素。
因此,平移向量应使用允许此操作的约定来存储。这或许可以解释为什么那些以**行优先**顺序存储矩阵的应用程序通常偏好**前置乘法**约定,而那些以**列优先**顺序存储矩阵的应用程序则倾向于**后置乘法**约定。
但是,如果由于某种原因,我们需要使用**后置乘法**约定,并且不想以**列优先**顺序存储矩阵,该怎么办?
有一个方法——虽然有点取巧——但它是可行的。
我们可以以不同的顺序重新解释多维数组的索引。
通过这样做,在 C/C++ 中,我们可以假装矩阵是以列优先顺序存储的,而不是行优先顺序。
存储多维数组的两种方法总结在下表中
[行][列] 顺序 | [列][行] 顺序 |
|---|---|
foo[X][Y] 被解释为 X×Y 矩阵 | foo[X][Y] 被解释为 Y×X 矩阵 |
| 要访问矩阵元素, 使用第一个方括号指定所需的**行** 并使用第二个方括号指定所需的**列** | 要访问矩阵元素, 使用第一个方括号指定所需的**列** |
| 矩阵的**行**直接对应于多维数组中的**行** | 矩阵的**列**对应于多维数组中的**行** |
| 对数学家来说更直观,因为它与矩阵定义非常吻合 | 通过这样做,我们可以假装矩阵是以列优先顺序存储的 |
![]() | ![]() |
HLSL 和 GLSL 着色语言在矩阵乘法和矩阵存储方面是独立的。同样,硬件和图形 API,如 DirectX® 和 Vulkan®,也独立于这些约定并支持各种可能性。然而,它们的默认行为是由较早的 API 版本定义的。
这种独立性体现在向量和矩阵的交互方式上。当一个向量乘以一个矩阵时,vp=
v∗m,向量 v 被视为行向量。反之,当矩阵乘以向量时,vp=m∗v,向量 v 被视为列向量。在 3D 图形 API 首次推出时,它们遵循特定的坐标系约定。
OpenGL®:右手坐标系,以及后置矩阵乘法约定。
DirectX®:左手坐标系,以及前置矩阵乘法约定。
随着 GPU 硬件和图形 API 的演进,这些约定变得不那么严格。如今,大多数 API 对坐标系和乘法顺序持中立态度,但有两个显著的例外。在以下情况下,API 必须最终确定(并且不能被用户覆盖)二维和三维欧几里得空间的手性:
| API | 裁剪空间 |
|---|---|
| DirectX® | X 轴指向右侧,Y 轴指向上方,Z 轴指向屏幕内部,Z 范围为 [0,1]。 |
| Vulkan® | X 轴指向右侧,Y 轴指向下方,Z 轴指向屏幕内部,Z 范围为 [0,1]。 |
| OpenGL® | X 轴指向右侧,Y 轴指向上方,Z 轴指向屏幕内部,Z 范围为 [-1,1]。 |
| Metal | X 轴指向右侧,Y 轴指向上方,Z 轴指向屏幕内部,Z 范围为 [0,1]。 |
| WebGPU | X 轴指向右侧,Y 轴指向上方,Z 轴指向屏幕内部,Z 范围为 [-1,1]。 |
| WebGL™ | X 轴指向右侧,Y 轴指向上方,Z 轴指向屏幕内部,Z 范围为 [0,1]。 |
| API | 纹理空间 |
|---|---|
| DirectX® | 原点在左上角,X 轴指向右侧,Y 轴指向下方 |
| Vulkan® | 原点在左上角,X 轴指向右侧,Y 轴指向下方 |
| OpenGL® | 原点在左下角,X 轴指向右侧,Y 轴指向(默认)向上(默认) |
| Metal | 原点在左上角,X 轴指向右侧,Y 轴指向下方 |
| WebGPU | 原点在左上角,X 轴指向右侧,Y 轴指向下方 |
| WebGL™ | 原点在左下角,X 轴指向右侧,Y 轴指向上方 |
上述考虑因素——即矩阵乘法的不可交换性以及向量叉积的反交换性——对构造 3D 变换的四种替代方法(作为 4×4 矩阵)产生了重要影响。下面各节将详细描述这些替代方法。
转置整个4×4 矩阵将仅改变前置和后置乘法顺序(不改变坐标系的“手性”或基向量的顺序)。
仅转置左上角 3×3 矩阵将仅改变基向量的顺序(不影响前置和后置乘法顺序)。
应用程序中使用的具体约定可能并不明显。回答以下问题有助于识别它:
平移矩阵构造:检查平移向量(X,Y,Z)的组件在内存中的存储方式。它们是相邻存储(1a)还是分开存储(1b)?
变换顺序:确定变换(Scale 缩放、Rotation 旋转和 Translation 平移)应用的顺序。组合是执行为 𝑇⋅𝑅⋅𝑆(2a)还是 𝑆⋅𝑅⋅𝑇(2b)?同样,矩阵-向量乘法是如何计算的?是 𝑀⋅𝑉(2a)还是 𝑉⋅𝑀(2b)?
旋转存储:检查围绕 X 轴或 Z 轴的旋转在内存中的表示方式。第一个存储的元素对应于 −sin(3a)还是 sin(3b)?对于围绕 Y 轴的旋转,第一个存储的元素是 sin(3a)还是 −sin(3b)?
坐标系手性:使用“手势规则”来确定坐标系。对于左手,伸直的食指指向 X 轴,弯曲的中指指向 Y 轴,伸直的拇指指向 Z 轴(4a)。对于右手,相应的方向是(4b)。
通过回答这些问题,可以使用下表来确定所使用的约定。
| 问题 1 | 问题 2 | 问题 3 | 问题 4 | → | 约定 |
|---|---|---|---|---|---|
| 1a | 2a | 3a | 4a | → | 后置乘法,列主序,𝑋, 𝑍, 𝑌,左手 |
| 1b | 2a | 3a | 4a | → | 后置乘法,行主序,𝑋, 𝑌, 𝑍,左手 |
| 1a | 2b | 3a | 4a | → | 前置乘法,行主序,𝑋, 𝑌, 𝑍,左手 |
| 1b | 2b | 3a | 4a | → | 前置乘法,列主序,𝑋, 𝑍, 𝑌,左手 |
| 1a | 2a | 3b | 4a | → | 后置乘法,列主序,𝑋, 𝑍, 𝑌,左手 |
| 1b | 2a | 3b | 4a | → | 后置乘法,行主序,𝑋, 𝑌, 𝑍,左手 |
| 1a | 2b | 3b | 4a | → | 前置乘法,行主序,𝑋, 𝑌, 𝑍,左手 |
| 1b | 2b | 3b | 4a | → | 前置乘法,列主序,𝑋, 𝑍, 𝑌,左手 |
| 1a | 2a | 3a | 4b | → | 后置乘法,列主序,𝑋, 𝑍, 𝑌,右手 |
| 1b | 2a | 3a | 4b | → | 后置乘法,行主序,𝑋, 𝑌, 𝑍,右手 |
| 1a | 2b | 3a | 4b | → | 前置乘法,行主序,𝑋, 𝑌, 𝑍,右手 |
| 1b | 2b | 3a | 4b | → | 前置乘法,列主序,𝑋, 𝑍, 𝑌,右手 |
| 1a | 2a | 3b | 4b | → | 后置乘法,列主序,𝑋, 𝑍, 𝑌,右手 |
| 1b | 2a | 3b | 4b | → | 后置乘法,行主序,𝑋, 𝑌, 𝑍,右手 |
| 1a | 2b | 3b | 4b | → | 前置乘法,行主序,𝑋, 𝑌, 𝑍,右手 |
| 1b | 2b | 3b | 4b | → | 前置乘法,列主序,𝑋, 𝑍, 𝑌,右手 |