Created
May 20, 2011 22:00
-
-
Save scan/983906 to your computer and use it in GitHub Desktop.
Scala Matrices
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
case class Matrix(_1: (Double, Double, Double, Double), _2: (Double, Double, Double, Double), | |
_3: (Double, Double, Double, Double), _4: (Double, Double, Double, Double)) extends Immutable { | |
def transpose = Matrix( | |
(_1._1, _2._1, _3._1, _4._1), | |
(_1._2, _2._2, _3._2, _4._2), | |
(_1._3, _2._3, _3._3, _4._3), | |
(_1._4, _2._4, _3._4, _4._4) | |
) | |
def invert = { | |
val _11 = _2._2 * _3._3 * _4._4 - _2._2 * _3._4 * _4._3 - _3._2 * _2._3 * _4._4 | |
+_3._2 * _2._4 * _4._3 + _4._2 * _2._3 * _3._4 - _4._2 * _2._4 * _3._3; | |
val _21 = -_2._1 * _3._3 * _4._4 + _2._1 * _3._4 * _4._3 + _3._1 * _2._3 * _4._4 | |
-_3._1 * _2._4 * _4._3 - _4._1 * _2._3 * _3._4 + _4._1 * _2._4 * _3._3; | |
val _31 = _2._1 * _3._2 * _4._4 - _2._1 * _3._4 * _4._2 - _3._1 * _2._2 * _4._4 | |
+_3._1 * _2._4 * _4._2 + _4._1 * _2._2 * _3._4 - _4._1 * _2._4 * _3._2; | |
val _41 = -_2._1 * _3._2 * _4._3 + _2._1 * _3._3 * _4._2 + _3._1 * _2._2 * _4._3 | |
-_3._1 * _2._3 * _4._2 - _4._1 * _2._2 * _3._3 + _4._1 * _2._3 * _3._2; | |
val _12 = -_1._2 * _3._3 * _4._4 + _1._2 * _3._4 * _4._3 + _3._2 * _1._3 * _4._4 | |
-_3._2 * _1._4 * _4._3 - _4._2 * _1._3 * _3._4 + _4._2 * _1._4 * _3._3; | |
val _22 = _1._1 * _3._3 * _4._4 - _1._1 * _3._4 * _4._3 - _3._1 * _1._3 * _4._4 | |
+_3._1 * _1._4 * _4._3 + _4._1 * _1._3 * _3._4 - _4._1 * _1._4 * _3._3; | |
val _32 = -_1._1 * _3._2 * _4._4 + _1._1 * _3._4 * _4._2 + _3._1 * _1._2 * _4._4 | |
-_3._1 * _1._4 * _4._2 - _4._1 * _1._2 * _3._4 + _4._1 * _1._4 * _3._2; | |
val _42 = _1._1 * _3._2 * _4._3 - _1._1 * _3._3 * _4._2 - _3._1 * _1._2 * _4._3 | |
+_3._1 * _1._3 * _4._2 + _4._1 * _1._2 * _3._3 - _4._1 * _1._3 * _3._2; | |
val _13 = _1._2 * _2._3 * _4._4 - _1._2 * _2._4 * _4._3 - _2._2 * _1._3 * _4._4 | |
+_2._2 * _1._4 * _4._3 + _4._2 * _1._3 * _2._4 - _4._2 * _1._4 * _2._3; | |
val _23 = -_1._1 * _2._3 * _4._4 + _1._1 * _2._4 * _4._3 + _2._1 * _1._3 * _4._4 | |
-_2._1 * _1._4 * _4._3 - _4._1 * _1._3 * _2._4 + _4._1 * _1._4 * _2._3; | |
val _33 = _1._1 * _2._2 * _4._4 - _1._1 * _2._4 * _4._2 - _2._1 * _1._2 * _4._4 | |
+_2._1 * _1._4 * _4._2 + _4._1 * _1._2 * _2._4 - _4._1 * _1._4 * _2._2; | |
val _43 = -_1._1 * _2._2 * _4._3 + _1._1 * _2._3 * _4._2 + _2._1 * _1._2 * _4._3 | |
-_2._1 * _1._3 * _4._2 - _4._1 * _1._2 * _2._3 + _4._1 * _1._3 * _2._2; | |
val _14 = -_1._2 * _2._3 * _3._4 + _1._2 * _2._4 * _3._3 + _2._2 * _1._3 * _3._4 | |
-_2._2 * _1._4 * _3._3 - _3._2 * _1._3 * _2._4 + _3._2 * _1._4 * _2._3; | |
val _24 = _1._1 * _2._3 * _3._4 - _1._1 * _2._4 * _3._3 - _2._1 * _1._3 * _3._4 | |
+_2._1 * _1._4 * _3._3 + _3._1 * _1._3 * _2._4 - _3._1 * _1._4 * _2._3; | |
val _34 = -_1._1 * _2._2 * _3._4 + _1._1 * _2._4 * _3._2 + _2._1 * _1._2 * _3._4 | |
-_2._1 * _1._4 * _3._2 - _3._1 * _1._2 * _2._4 + _3._1 * _1._4 * _2._2; | |
val _44 = _1._1 * _2._2 * _3._3 - _1._1 * _2._3 * _3._2 - _2._1 * _1._2 * _3._3 | |
+_2._1 * _1._3 * _3._2 + _3._1 * _1._2 * _2._3 - _3._1 * _1._3 * _2._2; | |
val det = _1._1 * _11 + _1._2 * _21 + _1._3 * _31 + _1._4 * _41 | |
if (det == 0) this | |
else Matrix( | |
(_11, _12, _13, _14), | |
(_21, _22, _23, _24), | |
(_31, _32, _33, _34), | |
(_41, _42, _43, _44) | |
) * (1 / det) | |
} | |
def *(m: Matrix) = { | |
val _11 = (_1._1 * m._1._1) + (_1._2 * m._2._1) + (_1._3 * m._3._1) + (_1._4 * m._4._1) | |
val _12 = (_1._1 * m._1._2) + (_1._2 * m._2._2) + (_1._3 * m._3._2) + (_1._4 * m._4._2) | |
val _13 = (_1._1 * m._1._3) + (_1._2 * m._2._3) + (_1._3 * m._3._3) + (_1._4 * m._4._3) | |
val _14 = (_1._1 * m._1._4) + (_1._2 * m._2._4) + (_1._3 * m._3._4) + (_1._4 * m._4._4) | |
val _21 = (_2._1 * m._1._1) + (_2._2 * m._2._1) + (_2._3 * m._3._1) + (_2._4 * m._4._1) | |
val _22 = (_2._1 * m._1._2) + (_2._2 * m._2._2) + (_2._3 * m._3._2) + (_2._4 * m._4._2) | |
val _23 = (_2._1 * m._1._3) + (_2._2 * m._2._3) + (_2._3 * m._3._3) + (_2._4 * m._4._3) | |
val _24 = (_2._1 * m._1._4) + (_2._2 * m._2._4) + (_2._3 * m._3._4) + (_2._4 * m._4._4) | |
val _31 = (_3._1 * m._1._1) + (_3._2 * m._2._1) + (_3._3 * m._3._1) + (_3._4 * m._4._1) | |
val _32 = (_3._1 * m._1._2) + (_3._2 * m._2._2) + (_3._3 * m._3._2) + (_3._4 * m._4._2) | |
val _33 = (_3._1 * m._1._3) + (_3._2 * m._2._3) + (_3._3 * m._3._3) + (_3._4 * m._4._3) | |
val _34 = (_3._1 * m._1._4) + (_3._2 * m._2._4) + (_3._3 * m._3._4) + (_3._4 * m._4._4) | |
val _41 = (_4._1 * m._1._1) + (_4._2 * m._2._1) + (_4._3 * m._3._1) + (_4._4 * m._4._1) | |
val _42 = (_4._1 * m._1._2) + (_4._2 * m._2._2) + (_4._3 * m._3._2) + (_4._4 * m._4._2) | |
val _43 = (_4._1 * m._1._3) + (_4._2 * m._2._3) + (_4._3 * m._3._3) + (_4._4 * m._4._3) | |
val _44 = (_4._1 * m._1._4) + (_4._2 * m._2._4) + (_4._3 * m._3._4) + (_4._4 * m._4._4) | |
Matrix( | |
(_11, _12, _13, _14), | |
(_21, _22, _23, _24), | |
(_31, _32, _33, _34), | |
(_41, _42, _43, _44) | |
) | |
} | |
def *(v: Vector) = { | |
val x = v.x * _1._1 + v.y * _2._1 + v.z * _3._1 + v.w * _4._1 | |
val y = v.x * _1._2 + v.y * _2._2 + v.z * _3._2 + v.w * _4._2 | |
val z = v.x * _1._3 + v.y * _2._3 + v.z * _3._3 + v.w * _4._3 | |
val w = v.x * _1._4 + v.y * _2._4 + v.z * _3._4 + v.w * _4._4 | |
if (w != 1) Vector(x / w, y / w, z / w, 1) | |
else Vector(x, y, z, w) | |
} | |
def *(f: Double) = Matrix( | |
(_1._1 * f, _1._2 * f, _1._3 * f, _1._4 * f), | |
(_2._1 * f, _2._2 * f, _2._3 * f, _2._4 * f), | |
(_3._1 * f, _3._2 * f, _3._3 * f, _3._4 * f), | |
(_4._1 * f, _4._2 * f, _4._3 * f, _4._4 * f) | |
) | |
} | |
object Matrix { | |
implicit def asTuple(m: Matrix): | |
((Double, Double, Double, Double), | |
(Double, Double, Double, Double), | |
(Double, Double, Double, Double), | |
(Double, Double, Double, Double)) = (m._1, m._2, m._3, m._4) | |
implicit def asArray(m: Matrix): Array[Double] = Array(m._1._1, m._1._2, m._1._3, m._1._4, | |
m._2._1, m._2._2, m._2._3, m._2._4, | |
m._3._1, m._3._2, m._3._3, m._3._4, | |
m._4._1, m._4._2, m._4._3, m._4._4) | |
object identity extends Matrix((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)) | |
def projection(fov: Double, aspect: Double, near: Double, far: Double) = Matrix( | |
(1 / math.tan(fov / 2), 0, 0, 0), | |
(0, (1 / math.tan(fov / 2)) / aspect, 0, 0), | |
(0, 0, far / (near - far), -1), | |
(0, 0, near * far / (near - far), 0) | |
) | |
def ortho(w: Double, h: Double, near: Double, far: Double) = Matrix( | |
(2 / w, 0, 0, 0), | |
(0, 2 / h, 0, 0), | |
(0, 0, 1 / (near - far), 0), | |
(0, 0, near / (near - far), 1) | |
) | |
def translation(x: Double, y: Double, z: Double) = Matrix( | |
(1, 0, 0, 0), | |
(0, 1, 0, 0), | |
(0, 0, 1, 0), | |
(x, y, z, 1) | |
) | |
def scale(sx: Double, sy: Double, sz: Double) = Matrix( | |
(sx, 0, 0, 0), | |
(0, sy, 0, 0), | |
(0, 0, sz, 0), | |
(0, 0, 0, 1) | |
) | |
def rotateX(a: Double) = { | |
val c = math.cos(a) | |
val s = math.sin(a) | |
Matrix( | |
(1, 0, 0, 0), | |
(0, c, s, 0), | |
(0, -c, s, 0), | |
(0, 0, 0, 1) | |
) | |
} | |
def rotateY(a: Double) = { | |
val c = math.cos(a) | |
val s = math.sin(a) | |
Matrix( | |
(c, 0, -s, 0), | |
(0, 1, 0, 0), | |
(s, 0, c, 0), | |
(0, 0, 0, 1) | |
) | |
} | |
def rotateZ(a: Double) = { | |
val c = math.cos(a) | |
val s = math.sin(a) | |
Matrix( | |
(c, s, 0, 0), | |
(-s, c, 0, 0), | |
(0, 0, 1, 0), | |
(0, 0, 0, 1) | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment