Not only is using column-major vs row-major counter-intuitive, Apple's documentation on "Working with Matrices" further exacerbates the confusion by their examples of "constructing" a "Translate Matrix" and a "Rotation Matrix" in 2D.
Translate Matrix Per Apple's Documentation ()
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
}
My Issue with it
The line of code matrix[0, 2] = tx
sets the value of the first column and the third row to tx
. let translationMatrix = makeTranslationMatrix(tx: 1, ty: 3)
and printing out the 2nd column print(translationMatrix.columns.2)
will yield float3(0.0, 0.0, 1.0)
. I am very confused regarding why it is the last row that contains the translation values, rather than the column. This convention is not used when using SCNMatrix4MakeTranslation
and creating a simd_float4x4
out of the SCNMatrix4
object.
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)
Both SCNMatrix4
and simd_float4x4
follow the column major naming convention. In the 2D example from Apple, it is the last row that contains the translation values, whereas with SCNMatrix4
and converting to simd_float4x4
, it is the last column that contains the translation values. Apple's example seems to be doing the same with the Rotation Matrices as well.
What am I missing?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…