Working with Matrices - juniverse1103/ARKitStudy GitHub Wiki
Working with Matrices
μ°λ¦½λ°©μ μμ νκ³ , κ³΅κ° λ΄μ μ μ λ³νμν€μΈμ
Overview
νλ ¬(matrix)μ ν(row)κ³Ό μ΄(column)λ‘ μ΄λ£¨μ΄μ§ 2μ°¨μ λ°°μ΄μ λλ€. simd λΌμ΄λΈλ¬λ¦¬λ μ΅λ 4κ°μ νκ³Ό 4κ°μ μ΄μ 16κ°μ μμλ₯Ό ν¬ν¨νλ νλ ¬λ€μ λν μ§μμ μ 곡ν©λλ€. μ΄ λΌμ΄λΈλ¬λ¦¬λ 컬λΌ(μ΄) λ©μ΄μ λ€μ΄λ° 컨벀μ (Column major naming convention)μ μ¬μ©ν©λλ€;
μλ₯Ό λ€μ΄, simd_doublel4x2
λ 4κ°μ 컬λΌ(μ΄)κ³Ό 2κ°μ λ‘μ°(ν)μ ν¬ν¨νλ λ§€νΈλ¦μ€(νλ ¬)μ
λλ€.
simd λΌμ΄λΈλ¬λ¦¬λ μ μ ν ν¬κΈ°κ° μ‘°μ λ 벑ν°λ€λ‘λΆν° νλ ¬μ ν λλ μ΄μ μμ±ν μ μλ μ΅μ μ ν¬ν¨νλ μμ±μ(initializer)λ₯Ό μ 곡ν©λλ€. μλ₯Ό λ€μ΄, λ€μμ μ½λλ λ€ κ°μ μμλ₯Ό κ°μ§λ λ 벑ν°λ₯Ό μ¬μ©νμ¬ 2 x 4 νλ ¬κ³Ό 4 x2 νλ ¬μ μμ±ν©λλ€:
let x = simd_double4(x: 10, y: 20, z: 30, w: 40)
let y = simd_double4(x: 1, y: 2, z: 3, w: 4)
/*
A matrix of two columns and four rows:
10 1
20 2
30 3
40 4
*/
let a = simd_double2x4([x,y])
/*
A matrix of four columns and two rows"
10 20 30 40
1 2 3 4
*/
let b = simd_double4x2(row:[x,y])
λ€μμ μμλ€μ νλ ¬μ 보νΈμ μΈ μ¬μ©λ²μ 보μ¬μ€λλ€.
Solve Simultaneous Equations
AX = B ννμ μ°λ¦½λ°©μ μμ νκΈ° μν΄ νλ ¬μ μ¬μ©ν μ μμ΅λλ€; μλ₯Ό λ€μ΄, λ€μκ³Ό κ°μ λ°©μ μμμ xμ yλ₯Ό μ°Ύλλ° μ¬μ©ν©λλ€:
2x + 4y = 2
-4x + 2y = 14
λ¨Όμ μ’λ³μ κ³μλ₯Ό ν¬ν¨νλ 2x2 νλ ¬μ μμ±ν©λλ€.
let a = simd_2x2(rows: [simd_double2(2,4), simd_double2(-4,2)])
κ·Έλ¦¬κ³ μ°λ³μ κ°μ ν¬ν¨νλ 벑ν°λ₯Ό μμ±ν©λλ€.
let b = simd_double2(2,14)
xμ yμ κ°μ ꡬνκΈ° μν΄μ, a νλ ¬μ μνλ ¬κ³Ό λ²‘ν° bλ₯Ό κ³±ν΄μ€λλ€:
let x = simd_mul(a.inverse, b)
κ²°κ³Ό x λ λκ°μ μμλ₯Ό κ°μ§λ λ²‘ν° (x,y) = (-2.6,1.8) μ λλ€.
Transform Vectors with Matrix Multiplication
νλ ¬μ 2Dλ 3D κ³΅κ° λ΄μ μλ μ λ€μ λ³ν(μ΄λ(translate), νμ (rotate), λ°°μ¨(scale))μν€κΈ° μν νΈλ¦¬ν λ°©λ²μ μ 곡ν©λλ€.
λ€μμ μ΄λ―Έμ§λ μ Aκ° Bλ‘ μ΄λλ κ², Cλ‘ νμ λ κ², κ·Έλ¦¬κ³ Dλ‘ λ°°μ¨λ κ²μ 보μ¬μ€λλ€.
2D μ’νλ€μ 3κ°μ μμλ₯Ό κ°μ§λ 벑ν°λ‘ λνλ΄λ κ²μΌλ‘, νλ ¬ κ³±μ ν΅ν΄ μ λ€μ λ³νν μ μμ΅λλ€. μΌλ°μ μΌλ‘, 곡κ°μμμ μμΉλ₯Ό λνλ΄λ 벑ν°μ 3λ²μ§Έ μμμΈ zλ 1μΌλ‘ κ³ μ λ©λλ€.
μλ₯Ό λ€μ΄, μ κ·Έλ¦Όμμ μ Aλ₯Ό λνλ΄λ 벑ν°λsimd_float3
λ‘ λ€μ μ½λμ κ°μ΄ μ μλ©λλ€.
let positionVector = simd_float3(x: 3, y: 2, z: 1)
2μ°¨μ μ’νκ³μ λν λ³ν νλ ¬μ 3x3 νλ ¬λ‘ λνλ΄μ΄μ§λλ€.
Translate
μ΄λ λ³ν νλ ¬μ λ€μκ³Ό κ°μ ννλ₯Ό κ°μ§λλ€:
1 0 0
0 1 0
tx ty 1
simd λΌμ΄λΈλ¬λ¦¬λ νλ± νλ ¬(λκ°μ μ λ°λΌ 1μ΄ μκ³ , λλ¨Έμ§ λΆλΆμ 0μ΄ μ‘΄μ¬νλ)μ λν μμλ₯Ό μ 곡ν©λλ€. 3x3 Float νλ± νλ ¬μ matrix_identity_float3x3
μ
λλ€.
λ€μμ ν¨μλ νλ± νλ ¬μ μμλ₯Ό μ€μ νλ κ²μΌλ‘ νΉμ ν txμ tyκ°μ λ°λΌ simd_float3x3
νλ ¬μ λ°νν©λλ€.
func makeTranslationMatrix(tx: Float, ty: Float) -> simd_float3x3{
var matrix = matrix_identity_float3x3
matrix[0,2] = tx
matrix[1,2] = ty
return matrix
}
μμΉλ²‘ν°μ μ΄λμ μ μ©νκΈ° μν΄μλ κ° μμ μλ‘ κ³±ν©λλ€.
let translationMatrix = makeTranslationMatrix(tx: 1, ty: 3)
let translatedVector = positionVector * translationMatrix
translatedVector
μ κ²°κ³Όλ μ κ·Έλ¦Όμ λνλ μ Bμ κ°μ΄ (x: 4.0, y: 5.0, z: 1.0) μ κ°μ κ°μ§λλ€.
Rotate
νμ λ³ν νλ ¬μ λ€μκ³Ό κ°μ ννλ₯Ό κ°μ§λλ€.
cos(angle) sin(angle) 0
-sin(angle) cos(angle) 0
0 0 1
λ€μ ν¨μλ νΉμ λ λΌλμμ νμ κ°λμ λ°λΌ simd_float3x3
νλ ¬μ λ°νν©λλ€.
func makeRotationMatrix(angle: Float) -> simd_float3x3{
let rows = [
simd_float3(cos(angle), sin(angle), 0),
simd_float3(-sin(angle), cos(angle), 0),
simd_float3(0, 0, 1)
]
return float3x3(rows: rows)
}
μ΄μ μ μ΄λλ 벑ν°μ νμ λ³νμ μ μ©νκΈ° μν΄μλ, λ μμ μλ‘ κ³±νλ©΄ λλ€.
let rotationMatrix = makeRotationMatrix(angle: GLKMatehDegreesToRadians(30))
let rotatedVector = translatedVector * rotationMatrix
rotatedVector
μ κ²°κ³Όκ°μ (x: 0.964102, y: 6.33013, z: 1.0)μΌλ‘ μ κ·Έλ¦Όμ λνλ μ Cμ κ°λ€.
Scale
λ°°μ¨ λ³ν νλ ¬μ λ€μκ³Ό κ°μ ννλ₯Ό κ°μ§λλ€.
xScale 0 0
0 yscale 0
0 0 1
λ€μ ν¨μλ νΉμ ν xμ y λ°°μ¨κ°μ λ°λΌ simd_float3x3
νλ ¬μ λ°νν©λλ€.
func makeScaleMatrix(xScale: Float, yScale: Float)->sim_float3x3{
let rows = [
simd_float3(xScale, 0, 0),
simd_float3( 0, yScale, 0),
simd_float3( 0, 0, 1)
]
return float3x3(rows: rows)
}
μ΄μ μ νμ λ 벑ν°μ λνμ¬ λ°°μ¨ λ³νμ μ μ©νκΈ° μν΄μλ λ μμ μλ‘ κ³±νλ©΄ λλ€.
let scaleMatrix = makeScaleMatrix(xScale: 8, yScale: 1.25)
let scaledVector = rotateVector * scaleMatrix
scaledVector
μ κ²°κ³Όκ°μ (x: 7.71282, y: 7.91266, z: 1.0) μΌλ‘ μ κ·Έλ¦Όμ λνλ μ 2μ κ°λ€.
μ΄ μΈκ°μ§μ λ³ν νλ ¬μ μ λΆ κ³±ν΄μ§ μ μμΌλ©°, μ΄μ κ³±ν΄μ§ μμΉλ²‘ν° μμ κ°μ κ²°κ³Όλ₯Ό κ°μ§λ€:
let transformMatrix = translationMatrix * rotationMatrix * scaleMatrix
let transformedVector = positionVector * transformMatrix