refactor normalization and 3d conversion

This commit is contained in:
Paul Zabelin
2018-02-19 03:43:15 -08:00
parent 1f3308381a
commit f2301670ca
3 changed files with 21 additions and 25 deletions

View File

@@ -4,8 +4,8 @@ import Nimble
import simd
import GameKit
func threeValues<S>(_ factory: (()->S)) -> [S] {
return Array(0...2).map{_ in factory()}
func arrayWith<S>(_ factory: (()->S)) -> [S] {
return Array(Vector3Type.indexSlice).map{_ in factory()}
}
extension GKRandomSource {
@@ -13,10 +13,10 @@ extension GKRandomSource {
return Double(nextUniform())
}
func nextVector() -> Vector3Type {
return Vector3Type(threeValues(nextDouble))
return Vector3Type(arrayWith(nextDouble))
}
func nextMatrix() -> Matrix3x3Type {
return Matrix3x3Type(threeValues(nextVector))
return Matrix3x3Type(arrayWith(nextVector))
}
}

View File

@@ -12,48 +12,44 @@ extension Vector3Type {
static let one = Vector3Type(ScalarType.one)
static let zero = Vector3Type(0)
static let lastIndex = Vector3Type().endIndex - 1
static let indexSlice = 0...Vector3Type.lastIndex
static let indexArray = Array(Vector3Type.indexSlice)
}
extension ScalarType {
static let one = ScalarType(1)
}
extension Matrix3x3Type {
internal static let insertBeforeLastColumn : Matrix4x3Type = {
extension Matrix4x3Type {
static let insertColumnBeforeLast : Matrix4x3Type = {
let identity = Matrix3x3Type(diagonal: Vector3Type.one)
var columns = Array(0...Vector3Type.lastIndex).map{identity[$0]}
var columns = Vector3Type.indexArray.map{identity[$0]}
columns.insert(Vector3Type.zero, at: Vector3Type.lastIndex)
return Matrix4x3Type(columns)
}()
}
internal static let insertBeforeLastRow : Matrix3x4Type = {
return insertBeforeLastColumn.transpose
extension Matrix3x4Type {
static let insertRowBeforeLast : Matrix3x4Type = {
return Matrix4x3Type.insertColumnBeforeLast.transpose
}()
}
extension Matrix3x3Type {
func to3d() -> Matrix4x4Type {
var stretch = Matrix3x3Type.insertBeforeLastRow * self * Matrix3x3Type.insertBeforeLastColumn
var stretch = Matrix3x4Type.insertRowBeforeLast * self * Matrix4x3Type.insertColumnBeforeLast
stretch[Vector3Type.lastIndex, Vector3Type.lastIndex] = ScalarType.one
return stretch
}
func zNormalized() -> Matrix3x3Type {
return zNormalizedUnsafe()
return normalizationFactor.isZero ? self : (ScalarType.one / normalizationFactor) * self
}
func homogeneousInverse() -> Matrix3x3Type {
return inverse.zNormalizedSafe()
return inverse.zNormalized()
}
private func zNormalizedUnsafe() -> Matrix3x3Type {
return (ScalarType.one / normalizationFactor()) * self
}
private func normalizationFactor() -> ScalarType {
return self[Vector3Type.lastIndex, Vector3Type.lastIndex]
}
private func zNormalizedSafe() -> Matrix3x3Type {
return normalizationFactor().isZero ? self : zNormalizedUnsafe()
private var normalizationFactor: ScalarType {
get { return self[Vector3Type.lastIndex, Vector3Type.lastIndex] }
}
}

View File

@@ -23,7 +23,7 @@ public final class Perspective {
}
private func calculateBasisVectorsToPointsMap() -> Matrix3x3Type {
let baseVectors = Matrix3x3Type(Array(vectors[0...Vector3Type.lastIndex]))
let baseVectors = Matrix3x3Type(Array(vectors[Vector3Type.indexSlice]))
let solution = baseVectors.homogeneousInverse() * vectors[Vector3Type.lastIndex + 1]
let scale = Matrix3x3Type(diagonal: solution)
let basisToPoints = baseVectors * scale