Ray Tracer: Vector Module

The is going to be some of the most used code and it’s going to be a hot spot for bugs. A nice thing that Haskell does is make it very easy to define your own infix operators this should help a lot to keep things readable. Here’s the code:

module Vector (Vec3f, Color, (<+>), (<->), (<*>), (</>), (<.>), x, len, normed, Ray(Ray), at) where
 
--general purpose 3 field vector
type Vec3 a = (a, a, a)
 
(<+>) :: (Num a) => Vec3 a -> Vec3 a -> Vec3 a
(<+>) (x1,y1,z1) (x2,y2,z2) = (x1 + x2, y1 + y2, z1 + z2) 
 
(<->) :: (Num a) => Vec3 a -> Vec3 a -> Vec3 a
(<->) (x1,y1,z1) (x2,y2,z2) = (x1 - x2, y1 - y2, z1 - z2) 
 
(<*>) :: (Num a) => a -> Vec3 a -> Vec3 a
(<*>) r (x,y,z) = (r * x, r * y, r * z)
 
(</>) :: (Fractional a) => Vec3 a -> a -> Vec3 a
(</>) (x,y,z) r = (x / r, y / r, z / r)
 
(<.>) :: (Num a) => Vec3 a -> Vec3 a -> a
(<.>) (x1,y1,z1) (x2,y2,z2) = (x1 * x2) + (y1 * y2) + (z1 * z2) 
 
--cross product
x :: (Num a) => Vec3 a -> Vec3 a -> Vec3 a
x (x1,y1,z1) (x2,y2,z2) = ((y1 * z2 - y2 * z1), (x1*z2 - x2*z1), (x1 * y2 - y1 * x2))
 
len :: (Floating a) => Vec3 a -> a
len v = sqrt (v <.> v)
 
normed :: (Floating a) => Vec3 a -> Vec3 a
normed v = v </> len v
 
type Vec3f = (Vec3 Float)
type Color = (Vec3 Int)
 
--Rays
data Ray = Ray {orig :: Vec3f,
                  dir  :: Vec3f
                 } deriving (Show)
 
at::Ray -> Float -> Vec3 Float
at (Ray orig dir) t = orig <+> (t <*> dir)

Pretty basic so far, but this should be enough to get me started. Haskell wasn’t happy when I tried to make the infix operators without the “<>“s so I guess I’m stuck with them (unless someone can tell me how to fix it.) However this does still look pretty nice:

*Vector> (1,1,1) <+> (5,5,5)
(6,6,6)
*Vector> (1,1,1) <-> (5,5,5)
(-4,-4,-4)
*Vector> 5 <*> (1,2,3)
(5,10,15)
*Vector> (1,2,3) </> 5
(0.2,0.4,0.6)
*Vector> (1,2,3) <.> (3,2,1)
10
*Vector> (1,0,0) `x` (0,1,0)
(0,0,1)
*Vector> len (1,1,0)
1.4142135623730951
*Vector> sqrt 2
1.4142135623730951
*Vector> normed (1,2,3)
(0.2672612419124244,0.5345224838248488,0.8017837257372732)
*Vector> len (normed (1,2,3))
1.0
*Vector> (Ray (0,0,0) (4,3,2)) `at` 100
(400.0,300.0,200.0)

Comments are closed.