mirror of
https://github.com/zhigang1992/PerspectiveTransform.git
synced 2026-01-12 22:49:33 +08:00
refactor normalization and 3d conversion
This commit is contained in:
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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] }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user