[svn] r5985: nemerle/trunk/snippets/raytracer: Makefile ray2.ml
ray2.n ray3.ml
malekith
svnadmin at nemerle.org
Tue Nov 29 22:38:43 CET 2005
Log:
Add second version.
Author: malekith
Date: Tue Nov 29 22:38:42 2005
New Revision: 5985
Added:
nemerle/trunk/snippets/raytracer/ray2.ml
nemerle/trunk/snippets/raytracer/ray2.n
- copied, changed from rev 5984, nemerle/trunk/snippets/raytracer/ray-compressed.n
nemerle/trunk/snippets/raytracer/ray3.ml
Modified:
nemerle/trunk/snippets/raytracer/Makefile
Modified: nemerle/trunk/snippets/raytracer/Makefile
==============================================================================
--- nemerle/trunk/snippets/raytracer/Makefile (original)
+++ nemerle/trunk/snippets/raytracer/Makefile Tue Nov 29 22:38:42 2005
@@ -48,8 +48,9 @@
%.exe: %.cs
gmcs $<
-run: ray.exe ray-hand-opt.exe ray-cs.exe ray-compressed.exe
+run: ray.exe ray-hand-opt.exe ray-cs.exe ray-compressed.exe ray2.exe
time $(EXECUTE) ./ray.exe 9 128 > out1.ppm
+ time $(EXECUTE) ./ray2.exe 9 128 > out5.ppm
time $(EXECUTE) ./ray-compressed.exe 9 128 > out4.ppm
time $(EXECUTE) ./ray-hand-opt.exe 9 128 > out2.ppm
time $(EXECUTE) ./ray-cs.exe 9 128 > out3.ppm
Added: nemerle/trunk/snippets/raytracer/ray2.ml
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/raytracer/ray2.ml Tue Nov 29 22:38:42 2005
@@ -0,0 +1,64 @@
+let delta = sqrt epsilon_float
+type vec = {x:float; y:float; z:float}
+let ( *| ) s r = {x = s *. r.x; y = s *. r.y; z = s *. r.z}
+let ( +| ) a b = {x = a.x +. b.x; y = a.y +. b.y; z = a.z +. b.z}
+let ( -| ) a b = {x = a.x -. b.x; y = a.y -. b.y; z = a.z -. b.z}
+let dot a b = a.x *. b.x +. a.y *. b.y +. a.z *. b.z
+let unitise r = (1. /. sqrt (dot r r)) *| r and length r = sqrt(dot r r)
+type scene = Sphere of vec * float | Group of vec * float * scene list
+let ray_sphere orig dir center radius =
+ let v = center -| orig in
+ let b = dot v dir in
+ let disc = b *. b -. dot v v +. radius *. radius in
+ if disc < 0. then infinity else
+ let disc = sqrt disc in
+ (fun t2 -> if t2 < 0. then infinity else
+ ((fun t1 -> if t1 > 0. then t1 else t2) (b -. disc))) (b +. disc)
+let intersect orig dir =
+ let rec aux ((l, _) as first) = function
+ Sphere (center, radius) ->
+ let l' = ray_sphere orig dir center radius in
+ if l' >= l then first else l', unitise (orig +| l' *| dir -| center)
+ | Group (center, radius, scenes) ->
+ let l' = ray_sphere orig dir center radius in
+ if l' >= l then first else List.fold_left aux first scenes in
+ aux (infinity, {x=0.; y=0.; z=0.})
+let rec ray_trace light orig dir scene =
+ let lambda, normal = intersect orig dir scene in
+ if lambda = infinity then 0. else
+ let g = dot normal light in
+ if g >= 0. then 0. else
+ let p = orig +| lambda *| dir +| delta *| normal in
+ if fst (intersect p (-1. *| light) scene) < infinity then 0. else -. g
+let rec create level c r =
+ let obj = Sphere (c, r) in
+ if level = 1 then obj else
+ let a = 3. *. r /. sqrt 12. in
+ let rec bound (c, r) = function
+ Sphere (c', r') -> (c, max r (length (c -| c') +. r'))
+ | Group (_, _, l) -> List.fold_left bound (c, r) l in
+ let aux x' z' = create (level - 1) (c +| {x=x'; y=a; z=z'}) (0.5 *. r) in
+ let l = [obj; aux (-.a) (-.a); aux a (-.a); aux (-.a) a; aux a a] in
+ let c, r = List.fold_left bound (c +| {x=0.; y=r; z=0.}, 0.) l in
+ Group (c, r, l)
+let main level n =
+ let scene = create level { x = 0.; y = -1.; z = 0. } 1. in
+ let light = unitise {x= -1.; y= -3.; z=2.} and ss = 4 in
+ Printf.printf "P5\n%d %d\n255\n" n n;
+ for y = n - 1 downto 0 do
+ for x = 0 to n - 1 do
+ let g = ref 0. in
+ for dx = 0 to ss - 1 do
+ for dy = 0 to ss - 1 do
+ let aux x d = float x -. float n /. 2. +. float d /. float ss in
+ let dir = unitise {x = aux x dx; y = aux y dy; z = float n } in
+ g := !g +. ray_trace light {x=0.; y=0.; z= -4.} dir scene
+ done
+ done;
+ let g = 0.5 +. 255. *. !g /. float (ss*ss) in
+ Printf.printf "%c" (char_of_int (int_of_float g))
+ done
+ done
+let () = match Sys.argv with
+ [| _; level; n|] -> main (int_of_string level) (int_of_string n)
+ | _ -> main 9 512
Copied: nemerle/trunk/snippets/raytracer/ray2.n (from rev 5984, nemerle/trunk/snippets/raytracer/ray-compressed.n)
==============================================================================
--- nemerle/trunk/snippets/raytracer/ray-compressed.n (original)
+++ nemerle/trunk/snippets/raytracer/ray2.n Tue Nov 29 22:38:42 2005
@@ -1,11 +1,13 @@
#pragma indent
+using System.Math
[Record] struct Vec
x : double; y : double; z : double
public static @*(s:double, r:Vec) :Vec { Vec(s*r.x, s*r.y, s*r.z) }
public static @+(s:Vec, r:Vec) :Vec { Vec(s.x+r.x, s.y+r.y, s.z+r.z) }
public static @-(s:Vec, r:Vec) :Vec { Vec (s.x-r.x, s.y-r.y, s.z-r.z) }
public static @**(s:Vec, r:Vec) :double { s.x*r.x + s.y*r.y + s.z*r.z }
- public Unitise () : Vec { (1 / System.Math.Sqrt (this ** this)) * this }
+ public Unitise () : Vec { (1 / Length) * this }
+ public Length : double { get { Sqrt (this ** this) } }
variant Scene
| Sphere { m : Vec; r : double; }
| Group { m : Vec; r : double; l : list [Scene]; }
@@ -38,9 +40,16 @@
def create (level, c, r)
def obj = Scene.Sphere (c, r)
if (level == 1) obj else
- def a = 3 * r / System.Math.Sqrt (12)
+ def a = 3 * r / Sqrt (12)
+ def bound (s, acc)
+ def (c, r) = acc
+ match (s : Scene)
+ | Sphere (c', r') => (c, Max (r, (c - c').Length + r'))
+ | Group (_, _, l) => l.FoldLeft (acc, bound)
def aux (x', z') { create (level - 1, c + Vec (x', a, z'), 0.5 * r) }
- Scene.Group (c, 3*r, [obj, aux (-a,-a), aux (a,-a), aux (-a,a), aux (a,a)])
+ def l = [obj, aux (-a,-a), aux (a,-a), aux (-a,a), aux (a,a)]
+ def (c, r) = l.FoldLeft ((c + Vec (0, r, 0), 0.0), bound)
+ Scene.Group (c, r, l)
def main (level, n)
def scene = create (level, Vec (0, -1, 0), 1)
def light = Vec (-1, -3, 2).Unitise (); def ss = 4
Added: nemerle/trunk/snippets/raytracer/ray3.ml
==============================================================================
--- (empty file)
+++ nemerle/trunk/snippets/raytracer/ray3.ml Tue Nov 29 22:38:42 2005
@@ -0,0 +1,71 @@
+let delta = sqrt epsilon_float
+type vec = {x:float; y:float; z:float}
+let ( *| ) s r = {x = s *. r.x; y = s *. r.y; z = s *. r.z}
+let ( +| ) a b = {x = a.x +. b.x; y = a.y +. b.y; z = a.z +. b.z}
+let ( -| ) a b = {x = a.x -. b.x; y = a.y -. b.y; z = a.z -. b.z}
+let dot a b = a.x *. b.x +. a.y *. b.y +. a.z *. b.z
+let unitise r = (1. /. sqrt (dot r r)) *| r and length r = sqrt(dot r r)
+type scene = Sphere of vec * float | Group of vec * float * scene list
+let ray_sphere orig dir center radius =
+ let v = center -| orig in
+ let b = dot v dir in
+ let disc = b *. b -. dot v v +. radius *. radius in
+ if disc < 0. then infinity else
+ let disc = sqrt disc in
+ (fun t2 -> if t2 < 0. then infinity else
+ ((fun t1 -> if t1 > 0. then t1 else t2) (b -. disc))) (b +. disc)
+let intersect orig dir =
+ let rec aux ((l, _) as first) = function
+ Sphere (center, radius) ->
+ let l' = ray_sphere orig dir center radius in
+ if l' >= l then first else l', unitise (orig +| l' *| dir -| center)
+ | Group (center, radius, scenes) ->
+ let l' = ray_sphere orig dir center radius in
+ if l' >= l then first else List.fold_left aux first scenes in
+ aux (infinity, {x=0.; y=0.; z=0.})
+let intersect' orig dir =
+ let rec aux = function
+ Sphere (center, radius) -> ray_sphere orig dir center radius < infinity
+ | Group (center, radius, scenes) ->
+ ray_sphere orig dir center radius < infinity &&
+ List.exists aux scenes in
+ aux
+let rec ray_trace light orig dir scene =
+ let lambda, normal = intersect orig dir scene in
+ if lambda = infinity then 0. else
+ let g = dot normal light in
+ if g >= 0. then 0. else
+ let p = orig +| lambda *| dir +| delta *| normal in
+ if intersect' p (-1. *| light) scene then 0. else -. g
+let rec create level c r =
+ let obj = Sphere (c, r) in
+ if level = 1 then obj else
+ let a = 3. *. r /. sqrt 12. in
+ let rec bound (c, r) = function
+ Sphere (c', r') -> (c, max r (length (c -| c') +. r'))
+ | Group (_, _, l) -> List.fold_left bound (c, r) l in
+ let aux x' z' = create (level - 1) (c +| {x=x'; y=a; z=z'}) (0.5 *. r) in
+ let l = [obj; aux (-.a) (-.a); aux a (-.a); aux (-.a) a; aux a a] in
+ let c, r = List.fold_left bound (c +| {x=0.; y=r; z=0.}, 0.) l in
+ Group (c, r, l)
+let main level n =
+ let scene = create level { x = 0.; y = -1.; z = 0. } 1. in
+ let light = unitise {x= -1.; y= -3.; z=2.} and ss = 4 in
+ Printf.printf "P5\n%d %d\n255\n" n n;
+ for y = n - 1 downto 0 do
+ for x = 0 to n - 1 do
+ let g = ref 0. in
+ for dx = 0 to ss - 1 do
+ for dy = 0 to ss - 1 do
+ let aux x d = float x -. float n /. 2. +. float d /. float ss in
+ let dir = unitise {x = aux x dx; y = aux y dy; z = float n } in
+ g := !g +. ray_trace light {x=0.; y=0.; z= -4.} dir scene
+ done
+ done;
+ let g = 0.5 +. 255. *. !g /. float (ss*ss) in
+ Printf.printf "%c" (char_of_int (int_of_float g))
+ done
+ done
+let () = match Sys.argv with
+ [| _; level; n|] -> main (int_of_string level) (int_of_string n)
+ | _ -> main 9 512
More information about the svn
mailing list