frag-1.1: src/Matrix.hs
-- 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