summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias P. Braendli <matthias.braendli@mpb.li>2013-11-23 15:03:11 +0100
committerMatthias P. Braendli <matthias.braendli@mpb.li>2013-11-23 15:03:11 +0100
commita2787b60231ffd730b8d1b3175a820a07f377fbe (patch)
tree1ae9cf36752039d36dafbad5b26ecd5b5ef99338
parentdb54b4c67b6f75a732b44c1080795c69fd4f6c63 (diff)
downloadhaskell-a2787b60231ffd730b8d1b3175a820a07f377fbe.tar.gz
haskell-a2787b60231ffd730b8d1b3175a820a07f377fbe.tar.bz2
haskell-a2787b60231ffd730b8d1b3175a820a07f377fbe.zip
sphere intersection detection
-rw-r--r--raytracer.hs51
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)