Apple不仅使用列优先与行优先的反直观,而且苹果公司有关“使用矩阵”的文档还通过在2D中“构造”“翻译矩阵”和“旋转矩阵”的示例进一步加剧了混淆。 。
根据Apple的文档()转换矩阵
翻译翻译矩阵采用以下形式:
1 0 0 0 1 0 tx ty 1
simd库为身份矩阵(矩阵)提供常量 沿对角线为1,在其他位置为0)。 3 x 3浮动 单位矩阵是matrix_identity_float3x3。
以下函数使用以下命令返回simd_float3x3矩阵 通过设置元素中指定的tx和ty转换值 身份矩阵:
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)
并打印出第二列print(translationMatrix.columns.2)
将产生float3(0.0, 0.0, 1.0)
。我对为什么它是包含转换值而不是列的最后一行感到非常困惑。使用SCNMatrix4MakeTranslation
并从simd_float4x4
对象创建SCNMatrix4
时不使用此约定。
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
都遵循专业列的命名约定。在Apple的2D示例中,它是包含转换值的最后一行,而使用SCNMatrix4
并转换为simd_float4x4
时,它是包含转换值的最后一列。苹果公司的例子似乎在旋转矩阵方面也是如此。
我想念什么?
答案 0 :(得分:1)
这可能会令人困惑,是的。
您提到的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); }