【问题标题】:Xcode simd - issue with Translation and Rotation Matrix ExampleXcode simd - 平移和旋转矩阵示例的问题
【发布时间】:2019-04-25 10:06:03
【问题描述】:

不仅使用列优先和行优先违反直觉,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将第一列和第三行的值设置为txlet translationMatrix = makeTranslationMatrix(tx: 1, ty: 3) 并打印出第二列 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,它是包含转换值的最后一列。苹果的例子似乎也对旋转矩阵做同样的事情。

我错过了什么?

【问题讨论】:

  • “并打印出第二列 print(translationMatrix.columns.2) 您不是在此处打印第二列,而是在打印第三列。这些是基于 0 的索引(在编程中很常见),所以 0 是第一个; 1 是第二个,2 是第三个。结果得到的float3(0.0, 0.0, 1.0) 与您设置的矩阵值(在第 1 列和第 2 列中)无关——它是第 3 列,仍然具有标识值。
  • (一个 3x3 恒等矩阵在 [0,0][1,1][2,2] 点的对角线上有 1.0,在其他任何地方都有 0.0。)

标签: matrix scenekit arkit simd


【解决方案1】:

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

您提到的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); }

【讨论】:

  • 这解释了很多 - 但是,我不确定我是否理解“在 SIMD 中无法区分向量与其转置(b 和 b')”这句话 - 你到底是什么意思?我希望 SIMD 将乘以您指定的任何矩阵,只要尺寸一致。你是在告诉我,如果最初的尺寸不像4x4 times 1x4 矩阵那样一致,它会尝试自动转置第二个并将其变成4x4 times 4x1 = 4x1
  • 在 SIMD 中,mat4x1mat1x4 没有区别,它们都是 vec4。因此,可以在乘法的两边使用相同的 vec4 变量,因此您必须格外小心使用的约定。
  • 另一种看法是,在第一种形式simd_mul(«matrix», «vector») 中,向量被解释为列向量,而在后一种形式simd_mul(«vector», «matrix») 中,向量被解释为行向量。 来源: 顶部的 Apple 文档 cmets。
猜你喜欢
  • 2014-08-24
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-14
相关资源
最近更新 更多