diff options
Diffstat (limited to 'raytracer.hs')
-rw-r--r-- | raytracer.hs | 51 |
1 files changed, 45 insertions, 6 deletions
diff --git a/raytracer.hs b/raytracer.hs index 8b78ae8..80fa348 100644 --- a/raytracer.hs +++ b/raytracer.hs @@ -9,23 +9,29 @@ type Angle = Double type ScreenCoord = (Angle, Angle) type Color = (Int, Int, Int) type Coord = (Double, Double, Double) +type Sphere = (Coord, Double) degrees = pi / 180 -eye = (0, 0, 2) +eye = (100, 100, 2) x_of (x, _, _) = x y_of (_, y, _) = y z_of (_, _, z) = z +sphere1 = ((10, 85, 0), 4) +sphere2 = ((-10, 45, 0), 4) + alpha1 = 80 * degrees alpha2 = -40 * degrees -beta1 = 15 * degrees -beta2 = -30 * degrees +beta1 = 25 * degrees +beta2 = -20 * degrees + +floorscale = 1 -w = 1000 -h = 500 +w = 800 +h = 400 oversampling = 1 -- each pixel is 2x2 rays ov_alphaoffset = ((alpha2 - alpha1) / (w-1)) / oversampling @@ -39,6 +45,35 @@ imgheader = "P3 " ++ (show w) ++ " " ++ (show h) ++ " 255\n" alphas = take (round w) [alpha1,(alpha1 + ((alpha2 - alpha1) / (w-1)))..] betas = take (round h) [beta1,(beta1 + ((beta2 - beta1) / (h-1)))..] + + + +-- intersect sphere + +-- discr = 4(( A u + B v + C w )^2 - (A^2 + B^2 + C^2)(u^2 + v^2 + w^2)) +-- where u = source_x - sphere_x (v and w analogous) +-- where A = cos alpha + cos beta +-- B = sin alpha +-- C = sin beta + +discr :: Coord -> ScreenCoord -> Sphere -> Double +discr source (alpha, beta) (centre, radius) = 4*(( aa * u + bb * v + cc * w )^2 - + (aa*aa + bb*bb + cc*cc)*(u*u + v*v + w*w - radius^2)) + where u = (x_of source) - (x_of centre) + v = (y_of source) - (y_of centre) + w = (z_of source) - (z_of centre) + aa = cos alpha + cos beta + bb = sin alpha + cc = sin beta + +intersect_sphere :: Coord -> ScreenCoord -> Sphere -> Bool +intersect_sphere source (alpha, beta) (centre, radius) + | discr source (alpha, beta) (centre, radius) > 0 = True + | otherwise = False + + + + -- intersect at (x , y , depth ) intersect_floor :: Coord -> ScreenCoord -> (Double, Double, Double) intersect_floor source (alpha, beta) @@ -49,7 +84,9 @@ intersect_floor source (alpha, beta) floorcolor :: Coord -> ScreenCoord -> Color floorcolor source (alpha, beta) - | (round (x/8) `mod` 2) == (round (y/8) `mod` 2) = (attn, 0, 0) + | x > 0.5 && x < 0.5 = (0, attn, attn) + | y > (-0.5) && y < 0.5 = (attn, attn, 0) + | (round (x/floorscale) `mod` 2) == (round (y/floorscale) `mod` 2) = (attn, 0, 0) | otherwise = (attn, attn, attn) where attn = max 0 (round (255 - 8*(sqrt t))) (x, y, t) = intersect_floor source (alpha, beta) @@ -62,6 +99,8 @@ skycolor source (alpha, beta) = (60, pixel_color :: Coord -> ScreenCoord -> Color pixel_color source (alpha, beta) + | intersect_sphere source (alpha, beta) sphere1 = (200, 0, 0) + | intersect_sphere source (alpha, beta) sphere2 = (0, 200, 0) | beta > 0 = skycolor source (alpha, beta) | beta == 0 = (0, 255, 0) | otherwise = floorcolor source (alpha, beta) |