Xcode simd - 平移和旋转矩阵示例的问题

Xcode simd - issue with Translation and Rotation Matrix Example

不仅使用列优先与行优先有悖常理,苹果关于 "Working with Matrices" 的文档通过 "constructing" a "Translate Matrix" 和 "Rotation Matrix" 在二维中。

根据 Apple 文档翻译矩阵 ()

Translate A translate matrix takes the following form:

1  0  0
0  1  0 
tx ty 1

The simd library provides constants for identity matrices (matrices with ones along the diagonal, and zeros elsewhere). The 3 x 3 Float identity matrix is matrix_identity_float3x3.

The following function returns a simd_float3x3 matrix using the specified tx and ty translate values by setting the elements in an identity matrix:

func makeTranslationMatrix(tx: Float, ty: Float) -> simd_float3x3 {
    var matrix = matrix_identity_float3x3

    matrix[0, 2] = tx
    matrix[1, 2] = ty

    return matrix 
}

我的问题

代码行matrix[0, 2] = tx将第一列和第三行的值设置为txlet translationMatrix = makeTranslationMatrix(tx: 1, ty: 3) 并打印出第 2 列 print(translationMatrix.columns.2) 将产生 float3(0.0, 0.0, 1.0)。我很困惑为什么最后一行包含翻译值,而不是列。使用 SCNMatrix4MakeTranslation 并从 SCNMatrix4 对象创建 simd_float4x4 时不使用此约定。

var A = SCNMatrix4MakeTranslation(1,2,3)
var Asimd = simd_float4x4(A)

A.m41 // 1
A.m42 // 2
A.m43 // 3
A.m44 // 1

Asimd.columns.3 // float4(1.0, 2.0, 3.0, 1.0)

SCNMatrix4simd_float4x4 都遵循 column major 命名约定。在 Apple 的 2D 示例中,它是包含翻译值的最后一行,而对于 SCNMatrix4 并转换为 simd_float4x4,它是包含翻译值的最后一列。苹果的例子似乎也对旋转矩阵做了同样的事情。

我错过了什么?

这可能会令人困惑,是的。

您提到的documentation进行以下计算:

let translatedVector = positionVector * translationMatrix

注意矩阵在乘法的右边。 您可能已经习惯了符号 b = M * a,但是如果您进行转置,您会得到 b' = a' * M',这就是示例所做的。

在 SIMD 中,无法区分向量及其转置(bb'),库允许您以两种方式进行乘法运算:

static simd_float3 SIMD_CFUNC simd_mul(simd_float3x3 __x, simd_float3 __y);
static simd_float3 SIMD_CFUNC simd_mul(simd_float3 __x,  simd_float3x3 __y) { return simd_mul(simd_transpose(__y), __x); }