Matrix.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #if !os(Linux)
  2. import QuartzCore
  3. #endif
  4. public struct Matrix4x4 {
  5. public let m11: Float, m12: Float, m13: Float, m14: Float
  6. public let m21: Float, m22: Float, m23: Float, m24: Float
  7. public let m31: Float, m32: Float, m33: Float, m34: Float
  8. public let m41: Float, m42: Float, m43: Float, m44: Float
  9. public init(rowMajorValues: [Float]) {
  10. guard rowMajorValues.count > 15 else { fatalError("Tried to initialize a 4x4 matrix with fewer than 16 values") }
  11. m11 = rowMajorValues[0]
  12. m12 = rowMajorValues[1]
  13. m13 = rowMajorValues[2]
  14. m14 = rowMajorValues[3]
  15. m21 = rowMajorValues[4]
  16. m22 = rowMajorValues[5]
  17. m23 = rowMajorValues[6]
  18. m24 = rowMajorValues[7]
  19. m31 = rowMajorValues[8]
  20. m32 = rowMajorValues[9]
  21. m33 = rowMajorValues[10]
  22. m34 = rowMajorValues[11]
  23. m41 = rowMajorValues[12]
  24. m42 = rowMajorValues[13]
  25. m43 = rowMajorValues[14]
  26. m44 = rowMajorValues[15]
  27. }
  28. public static let identity = Matrix4x4(rowMajorValues: [1.0, 0.0, 0.0, 0.0,
  29. 0.0, 1.0, 0.0, 0.0,
  30. 0.0, 0.0, 1.0, 0.0,
  31. 0.0, 0.0, 0.0, 1.0])
  32. }
  33. public struct Matrix3x3 {
  34. public let m11: Float, m12: Float, m13: Float
  35. public let m21: Float, m22: Float, m23: Float
  36. public let m31: Float, m32: Float, m33: Float
  37. public init(rowMajorValues: [Float]) {
  38. guard rowMajorValues.count > 8 else { fatalError("Tried to initialize a 3x3 matrix with fewer than 9 values") }
  39. m11 = rowMajorValues[0]
  40. m12 = rowMajorValues[1]
  41. m13 = rowMajorValues[2]
  42. m21 = rowMajorValues[3]
  43. m22 = rowMajorValues[4]
  44. m23 = rowMajorValues[5]
  45. m31 = rowMajorValues[6]
  46. m32 = rowMajorValues[7]
  47. m33 = rowMajorValues[8]
  48. }
  49. public static let identity = Matrix3x3(rowMajorValues: [1.0, 0.0, 0.0,
  50. 0.0, 1.0, 0.0,
  51. 0.0, 0.0, 1.0])
  52. public static let centerOnly = Matrix3x3(rowMajorValues: [0.0, 0.0, 0.0,
  53. 0.0, 1.0, 0.0,
  54. 0.0, 0.0, 0.0])
  55. }
  56. func orthographicMatrix(_ left: Float, right: Float, bottom: Float, top: Float, near: Float, far: Float, anchorTopLeft: Bool = false) -> Matrix4x4 {
  57. let r_l = right - left
  58. let t_b = top - bottom
  59. let f_n = far - near
  60. var tx = -(right + left) / (right - left)
  61. var ty = -(top + bottom) / (top - bottom)
  62. let tz = -(far + near) / (far - near)
  63. let scale: Float
  64. if anchorTopLeft {
  65. scale = 4.0
  66. tx = -1.0
  67. ty = -1.0
  68. } else {
  69. scale = 2.0
  70. }
  71. return Matrix4x4(rowMajorValues: [
  72. scale / r_l, 0.0, 0.0, tx,
  73. 0.0, scale / t_b, 0.0, ty,
  74. 0.0, 0.0, scale / f_n, tz,
  75. 0.0, 0.0, 0.0, 1.0,
  76. ])
  77. }
  78. #if !os(Linux)
  79. public extension Matrix4x4 {
  80. init(_ transform3D: CATransform3D) {
  81. m11 = Float(transform3D.m11)
  82. m12 = Float(transform3D.m12)
  83. m13 = Float(transform3D.m13)
  84. m14 = Float(transform3D.m14)
  85. m21 = Float(transform3D.m21)
  86. m22 = Float(transform3D.m22)
  87. m23 = Float(transform3D.m23)
  88. m24 = Float(transform3D.m24)
  89. m31 = Float(transform3D.m31)
  90. m32 = Float(transform3D.m32)
  91. m33 = Float(transform3D.m33)
  92. m34 = Float(transform3D.m34)
  93. m41 = Float(transform3D.m41)
  94. m42 = Float(transform3D.m42)
  95. m43 = Float(transform3D.m43)
  96. m44 = Float(transform3D.m44)
  97. }
  98. init(_ transform: CGAffineTransform) {
  99. self.init(CATransform3DMakeAffineTransform(transform))
  100. }
  101. }
  102. #endif