-- Matrix.hs; Hugh Rayner (hnra275@cse.unsw.edu.au) 2004 -- This module performs several linear algebra functions which are necessary for the game. -- The are used for functions such as rotation of the player and collision detection. module Matrix where import Graphics.UI.GLUT --type Vec3 = (GLdouble,GLdouble,GLdouble) type Vec3 = (Double,Double,Double) type Mat3 = (Vec3,Vec3,Vec3) mapTup::(a->b)->(a,a,a)->(b,b,b) mapTup f (a,b,c) = (f a, f b, f c) -- Finds the dot product of two vectors dotProd :: Vec3->Vec3->Double dotProd (a,b,c) (aa,bb,cc) = a*aa + b*bb + c*cc -- Finds the cross product of two 3-vectors crossProd::Vec3->Vec3->Vec3 crossProd (a,b,c) (aa,bb,cc) = (b*cc-c*bb,c*aa-a*cc,a*bb-b*aa) -- Finds the transpose of a 3*3 matrix transpose3 :: Mat3->Mat3 transpose3 ((a1,a2,a3),(b1,b2,b3),(c1,c2,c3)) = ((a1,b1,c1),(a2,b2,c2),(a3,b3,c3)) -- Multiplies a 3*3 matrix with a 3-vector matrixVectorMult ::Mat3->Vec3->Vec3 matrixVectorMult m v = mapTup (dotProd v) m -- As above, but arguments swapped matrixVectorMult2 ::Vec3->Mat3->Vec3 matrixVectorMult2 v m = mapTup (dotProd v) m -- Multiplies two 3*3 matrices matrixMult :: Mat3->Mat3->Mat3 matrixMult m1 m2 = (mapTup (matrixVectorMult (transpose3 m1)) m2) -- As above, but arguments swapped matrixMult2 :: Mat3->Mat3->Mat3 matrixMult2 m2 m1 = (mapTup (matrixVectorMult (transpose3 m1)) m2) -- Adds two vectors vectorAdd :: Vec3->Vec3->Vec3 vectorAdd (a1,a2,a3) (b1,b2,b3) = (a1+b1,a2+b2,a3+b3) -- Subtracts two vectors vectorSub :: Vec3->Vec3->Vec3 vectorSub (a1,a2,a3) (b1,b2,b3) = (a1-b1,a2-b2,a3-b3) -- As above, but arguments swapped vectorSub2 :: Vec3->Vec3->Vec3 vectorSub2 a b = vectorSub b a -- Multiplies a vecotor by a scalar vectorMult :: Vec3->Double->Vec3 vectorMult v s = mapTup (s*) v -- finds the normal of a flat polygon findNormal :: [Vec3] -> Vec3 findNormal (a:(b:(c:_))) = normalise (crossProd (vectorSub a b) (vectorSub c b)) findNormal _ = (0,0,0) -- Normalises a vector normalise :: Vec3 -> Vec3 normalise a = vectorMult a (sqrt (1/len a)) where len (va,vb,vc) = va*va+vb*vb+vc*vc -- Makes a Vertex3 (GLdouble) from a Vec3 vert::Vec3->Vertex3(GLdouble) vert (x,y,z) = Vertex3 x y z -- Makes a TexCoord2 (GLdouble) from a Vec3 coord::(Double,Double)->TexCoord2(GLdouble) coord (x,y) = TexCoord2 x y -- Makes a Vector3 (GLdouble) from a Vec3 vect::Vec3->Vector3(GLdouble) vect (x,y,z) = Vector3 x y z -- Makes a Normal3 (GLdouble) from a Vec3 norm3::Vec3->Normal3(GLdouble) norm3 (x,y,z) = Normal3 x y z