Xcode simd - проблема с примером матрицы перевода и вращения - PullRequest
0 голосов
/ 22 ноября 2018

Не только использование контр-интуитивно понятного по сравнению с мажором столбца и мажором строки, документация Apple по «Работе с матрицами» еще больше усугубляет путаницу из-за примеров «построения» «матрицы преобразования» и «матрицы вращения» в 2D,

Матрица перевода в документации Apple ()

Матрица перевода принимает следующую форму:

1  0  0
0  1  0 
tx ty 1

Библиотека simd предоставляетконстанты для единичных матриц (матрицы с единицами по диагонали и нулями в других местах).Тождественная матрица с плавающей запятой 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) и распечатка 2-го столбца 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 следуют соглашению об именовании Major .В 2D-примере от Apple это последняя строка, содержащая значения перевода, тогда как с SCNMatrix4 и преобразованием в simd_float4x4 это последний столбец, содержащий значения перевода.Пример Apple, похоже, делает то же самое с матрицами вращения.

Чего мне не хватает?

1 Ответ

0 голосов
/ 22 ноября 2018

Это может сбить с толку, да.

Документация , которую вы упоминаете, делает следующие вычисления:

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); }
...