{- Michael Chen CS429 Final Project A "demo" quality 3D renderer implemented in Haskell. Do note that this renderer is limited to drawing a model in a window, and rotating the model. Rotating the model is "painful" because this is running as interpreted Haskell. -} module Vec3d where type Vector2 = (Float, Float) {- Whoa! What's Happening here? This is done because translations in 3d have to be done this way, or you'll mess up the perspective and stuff. Just keep "w" blank -} type Vector3 = (Float, Float, Float) {- Get the length of a vector -} vecLength3 :: Vector3 -> Float vecLength3 (x,y,z) = sqrt (x*x + y*y + z*z) {- Add two vectors -} add3 :: Vector3 -> Vector3 -> Vector3 add3 (aX,aY,aZ) (bX,bY,bZ) = (aX+bX, aY+bY, aZ+bZ) add2 :: Vector2 -> Vector2 -> Vector2 add2 (aX,aY) (bX,bY) = (aX+bX,aY+bY) {- generate the dot product of two vectors -} dot3 :: Vector3 -> Vector3 -> Float dot3 (aX,aY,aZ) (bX,bY,bZ) = aX*bX + aY*bY + aZ*bZ dot2 :: Vector2 -> Vector2 -> Float dot2 (aX,aY) (bX,bY) = aX*bX + aY*bY {- Get the cross product of two vectors -} cross3 :: Vector3 -> Vector3 -> Vector3 cross3 (aX,aY,aZ) (bX,bY,bZ) = (aY*bZ-bY*aZ,bX*aZ-aX*bZ,aX*bY-bX*aY) {- Multiply a float to a vector -} mult3 :: Float -> Vector3 -> Vector3 mult3 f (x,y,z) = (f*x, f*y, f*z) {- transform a vector3 to vector2. IE, transform the point from 3d coord to 2d coord while maintaining perspective, etc. -} protoVec3To2 :: Float -> Vector3 -> Vector2 protoVec3To2 g (aX,aY,aZ) = (aX * scale, aY * scale) where scale = g / aZ deriveVec3To2 :: Float -> (Vector3 -> Vector2) deriveVec3To2 g = protoVec3To2 g {- Calculate the projection of v1 onto v2 -} projectVec3 :: Vector3 -> Vector3 -> Vector3 projectVec3 v1 v2 = (v1 `dot3` v2) `mult3` v2