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
将第一列和第三行的值设置为tx
。 let 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)
SCNMatrix4
和 simd_float4x4
都遵循 column major 命名约定。在 Apple 的 2D 示例中,它是包含翻译值的最后一行,而对于 SCNMatrix4
并转换为 simd_float4x4
,它是包含翻译值的最后一列。苹果的例子似乎也对旋转矩阵做了同样的事情。
我错过了什么?
这可能会令人困惑,是的。
您提到的documentation进行以下计算:
let translatedVector = positionVector * translationMatrix
注意矩阵在乘法的右边。
您可能已经习惯了符号 b = M * a
,但是如果您进行转置,您会得到 b' = a' * M'
,这就是示例所做的。
在 SIMD 中,无法区分向量及其转置(b
与 b'
),库允许您以两种方式进行乘法运算:
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); }
不仅使用列优先与行优先有悖常理,苹果关于 "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
将第一列和第三行的值设置为tx
。 let 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)
SCNMatrix4
和 simd_float4x4
都遵循 column major 命名约定。在 Apple 的 2D 示例中,它是包含翻译值的最后一行,而对于 SCNMatrix4
并转换为 simd_float4x4
,它是包含翻译值的最后一列。苹果的例子似乎也对旋转矩阵做了同样的事情。
我错过了什么?
这可能会令人困惑,是的。
您提到的documentation进行以下计算:
let translatedVector = positionVector * translationMatrix
注意矩阵在乘法的右边。
您可能已经习惯了符号 b = M * a
,但是如果您进行转置,您会得到 b' = a' * M'
,这就是示例所做的。
在 SIMD 中,无法区分向量及其转置(b
与 b'
),库允许您以两种方式进行乘法运算:
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); }