Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

★ /prog/ Challenge Summer Edition ★

Name: Anonymous 2010-09-22 2:14

THE CHALLENGE:
I) Write three functions, union :: [(Float,Float)] -> [(Float,Float)], difference :: [(Float,Float)] -> [(Float,Float)], intersection :: [(Float,Float)] -> [(Float,Float)]
Which perform the respective set operations on their input, a list of closed intervals of the form (min, max). Your functions need not support sentinel values such as NaN or infinity. The number of intervals returned should be minimized where possible.

II) Use your functions from I to implement a simple CSG raytracer. Your raytracer should support the following features:

• Spheres
• Diffuse surfaces
• Specular surfaces

Upon completion, post your source code here, along with one (1) example rendering, showcasing your raytracer. The example render should include an example of each set operation performed on two spheres, for a total of six spheres. A single directional light source should be used to light the scene.

Submissions close on 2010-10-04 at 00:00. Programs will be marked in three categories: efficiency, conciseness, and quality of implementation.

Each winner is entitled to claim ownership of two (2) /prog/ memes of his choice, with the exception of SICP, HMA, and UMH.

Name: Anonymous 2010-09-22 3:11

DO YOUR OWN HOMEWORK MY ANUS

Name: Anonymous 2010-09-22 4:30

Your functions need not support sentinel values such as NaN or infinity.
What?

Name: Anonymous 2010-09-22 6:18

>>3
For any range tuple (min, max), min and max will be standard floating point values. Namely, this means they will not be any of the following:

• Subnormal numbers
• Infinities
• NaN

Additionally, no distinction needs to be made between positive and negative zero.

Name: Anonymous 2010-09-22 8:02

>>4
Why not subnormals? I demand subnormal numbers to be possibly include in input values!

Name: Anonymous 2010-09-22 15:14

>>5
your subnormal oh lawdy i made joke

Name: Anonymous 2010-09-22 15:42

Do I get anything for completing the first part?

Name: Anonymous 2010-09-23 4:10

>>7
You could potentially win, if nobody else submits (which will probably be the case, old /Prague/ is dead).

Name: Anonymous 2010-09-23 16:45

>>8
We're not all NEET, but since you are so eager here's my work in progress.

Union: http://img52.imageshack.us/img52/9596/uniono.png
Difference: see Union
Intersection: http://img833.imageshack.us/img833/2696/intersection.png

type interval = Interval of float * float

let rec union a b =
  match (a, b) with
      ([], _) -> b
    | (_, []) -> a
    | (Interval(a_l, a_h) :: a_r, Interval(b_l, b_h) :: b_r) ->
      if a_h < b_l then List.hd a :: union a_r b else
      if b_h < a_l then List.hd b :: union a b_r else
      union (Interval(min a_l b_l, max a_h b_h) :: a_r) b_r

let rec difference a b =
  match (a, b) with
      ([], _) -> b
    | (_, []) -> a
    | (Interval(a_l, a_h) :: a_r, Interval(b_l, b_h) :: b_r) ->
      if a_h < b_l then List.hd a :: union a_r b else
      if b_h < a_l then List.hd b :: union a b_r else
      Interval(min a_l b_l, max a_l b_l) ::
        difference (Interval(min a_h b_h, max a_h b_h) :: a_r) b_r

let rec intersection a b =
  match (a, b) with
      ([], _) -> []
    | (_, []) -> []
    | (Interval(a_l, a_h) :: a_r, Interval(b_l, b_h) :: b_r) ->
      if a_h < b_l then union a_r b else
      if b_h < a_l then union a b_r else
      Interval(max a_l b_l, min a_h b_h) ::
        if a_h > b_h then difference a b_r else difference a_r b

type vector = Vector of float * float * float

let vector_sub (Vector(a_x, a_y, a_z)) (Vector(b_x, b_y, b_z)) =
  Vector(a_x -. b_x, a_y -. b_y, a_z -. b_z)

let vector_dot (Vector(a_x, a_y, a_z)) (Vector(b_x, b_y, b_z)) =
  a_x *. b_x +. a_y *. b_y +. a_z *. b_z

type sphere = Sphere of vector * float

let line_sphere o i (Sphere(c, r)) =
  let c' = vector_sub c o in
  let i_c' = vector_dot i c' in
  let det = (i_c' *. i_c') -. (vector_dot c' c') +. (r *. r) in
  if det < 0. then [] else
    let sqrt_det = sqrt det in
    [Interval(i_c' -. sqrt_det, i_c' +. sqrt_det)]

type csg =
    Union of csg * csg
  | Difference of csg * csg
  | Intersection of csg * csg
  | Primitive of sphere

let rec ray o i csg =
  match csg with
      Union(a, b) -> union (ray o i a) (ray o i b)
    | Difference(a, b) -> difference (ray o i a) (ray o i b)
    | Intersection(a, b) -> intersection (ray o i a) (ray o i b)
    | Primitive(s) -> line_sphere o i s

let rec visible l =
  match l with
      [] -> None
    | Interval(l, h) :: r ->
      if h > 0. then Some (max 0. l) else visible r

type color = {r: int; g: int; b: int}

let view x y csg =
  match visible (ray (Vector(x,y,0.)) (Vector(0.,0.,1.)) csg) with
      None -> {r=255;g=0;b=255}
    | Some z ->
      let k = int_of_float (50. +. (1. -. z) *. 155.) in {r=k;g=k;b=k}

let ppm w h csg =
  print_string "P6 ";
  print_int w;
  print_string " ";
  print_int h;
  print_string " 255";
  print_newline ();

  let w' = float_of_int w in
  let h' = float_of_int h in
 
  let rec yloop y =
    let rec xloop x =
      if x >= w' then yloop (y +. 1.) else
        let color = view (x /. w') (y /. h') csg in
        print_char (char_of_int color.r);
        print_char (char_of_int color.g);
        print_char (char_of_int color.b);
        xloop (x +. 1.)
    in if y >= h' then () else xloop 0.
  in yloop 0.

let sphere1 = Sphere(Vector(0.4,0.4,0.5), 0.3)

let sphere2 = Sphere(Vector(0.6,0.6,0.7), 0.4)

let test_csg = Union(Primitive(sphere1), Primitive(sphere2))

let _ = ppm 500 500 test_csg

Name: Anonymous 2010-09-23 16:58

>>9
What language is this?

Name: Anonymous 2010-09-23 17:04

>>10
LAIN

Name: Anonymous 2010-09-23 17:09

>>10
ML

Name: Anonymous 2010-09-24 5:17

Behold my 3D BBCode engine:


Name: Anonymous 2010-09-24 5:18

>>13
As you can see it supports reflection.

Name: Anonymous 2010-09-24 5:49

>>13
Holy shit is that doing realtime raytracing?

Name: Anonymous 2010-09-24 9:26

                                  . . ,.".".'"""..
                                .             ,__\.~~
                               .    ;'``` '``     \!"
                               .   `.              \~"
                                .., '  ____________|'~"
                               `.  .__/     |_|    |\
                                `..'  |  = /  | =  ||
                                    | \___/   |\___|/
                                    |        _|    |
                                     \      __     |
                                      \    /__\  ./
                                      |`'._____.'|
                                      |O)______(O/
                                      \::\    /:/
                                       \::\  /:/     
              ______                    \::\':/
           .'.-----.'.                .--(O)\'
          /.':    (| |               /:.-'\::\
         / | :`-{||| |              /:/   .o):\
   ____.'. [-'-----' |             /:/.-'\.'\::\
 .'    |=| |     <=| |          _./:/ _.-'   `.:|
 |____.'=| [       | |   ____.-' /:/-'_________(o)
 (_.....---'-.__   | |\ |________ _______________|
 [_|   .------. '._| |'-'--------'---- .------. _|_
 [_|__/ .----. \ ___ |[=:=]_:::::::::_/ .----. \___]
[___|/ /  ..  \ \___||___.-----------/ /  ..  \ \--'
      |  (::)  |                      |  (::)  |
       \  ''  /                        \  ''  /
        `----'                          `----'

Name: Anonymous 2010-09-24 17:54

Here's my completed entry.

Image: http://img706.imageshack.us/img706/751/testsl.png

type color = {r: int; g: int; b: int}
type vector = Vector of float * float * float
type solid = Sphere of vector * float * color
type interval = Interval of float * float * solid
type csg =
    Union of csg * csg
  | Difference of csg * csg
  | Intersection of csg * csg
  | Primitive of solid
type scene = Scene of vector * csg

(* boolean operations *)
let rec union a b =
  match (a, b) with
      (None, _) -> b
    | (_, None) -> a
    | (Some (Interval(a_l, a_h, a_s)), Some (Interval(b_l, b_h, b_s))) ->
      if a_l < b_l then a else b

let rec difference a b =
  match (a, b) with
      (None, _) -> b
    | (_, None) -> a
    | (Some (Interval(a_l, a_h, a_s)), (Some (Interval(b_l, b_h, b_s)))) ->
      if a_h < b_l then a else
      if b_h < a_l then b else
      if a_l < b_l then Some (Interval(a_l, b_l, a_s)) else
      if b_l < a_l then Some (Interval(b_l, a_l, b_s)) else
      None

let rec intersection a b =
  match (a, b) with
      (None, _) -> None
    | (_, None) -> None
    | (Some (Interval(a_l, a_h, a_s)), Some (Interval(b_l, b_h, b_s))) ->
      if a_h < b_l or b_h < a_l then None else
      let l = max a_l b_l in
      let h = min a_h b_h in
      if l == h then None else
      Some (Interval(l, h, if a_l <= b_l then b_s else a_s))

(* vectors *)
let vector_sub (Vector(a_x, a_y, a_z)) (Vector(b_x, b_y, b_z)) =
  Vector(a_x -. b_x, a_y -. b_y, a_z -. b_z)

let vector_dot (Vector(a_x, a_y, a_z)) (Vector(b_x, b_y, b_z)) =
  a_x *. b_x +. a_y *. b_y +. a_z *. b_z

let vector_mul (Vector(a_x, a_y, a_z)) k =
  Vector(a_x *. k, a_y *. k, a_z *. k) 

let vector_norm (Vector(a_x, a_y, a_z)) =
  sqrt(a_x *. a_x +. a_y *. a_y +. a_z *. a_z)

let vector_normalize v =
  vector_mul v (1. /. (vector_norm v))

(* line/sphere intersection *)
let line_sphere o i s =
  match s with Sphere(c, r, x) ->
    let c' = vector_sub c o in
    let i_c' = vector_dot i c' in
    let det = i_c' ** 2. -. (vector_dot c' c') +. r ** 2. in
    if det < 0. then None else
      let sqrt_det = sqrt det in
      Some (Interval(i_c' -. sqrt_det, i_c' +. sqrt_det, s))

(* normal calculation *)
let point_normal p (Sphere(c, _, _)) =
  vector_normalize (vector_sub p c)

(* ray / csg intersection *)
let clip i =
  match i with
      None -> None
    | Some (Interval(l, h, s)) ->
      if h < 0. then
        None
      else
        Some (Interval(max 0. l, h, s))

let primitive_ray o i s =
  match s with Sphere _ -> line_sphere o i s

let rec ray o i csg =
  match csg with
      Union(a, b) -> union (ray o i a) (ray o i b)
    | Difference(a, b) -> difference (ray o i a) (ray o i b)
    | Intersection(a, b) -> intersection (ray o i a) (ray o i b)
    | Primitive(s) -> clip (primitive_ray o i s)

(* pixel -> color *)
let view x y (Scene(light, csg)) =
  let o = Vector(x,y,0.) in
  let i = Vector(0.,0.,1.) in
  match ray o i csg with
      None -> {r=0;g=0;b=0}
    | Some Interval(z, _, s) ->
      let p = vector_sub o (vector_mul i (z *. -1.)) in
      let normal = point_normal p s in
      let r = vector_sub i (vector_mul normal (2. *. (vector_dot normal i))) in
      let spec_lum = max 0. (vector_dot light r) in
      let diff_lum = max 0. (vector_dot light normal) in
      let lum = spec_lum ** 4. *. 0.4 +. diff_lum ** 2. *. 0.6 in
      match s with Sphere(_d, _, c) ->
        let k = int_of_float (50. +. lum *. 205.) in
        {
          r = (c.r * k) / 255;
          g = (c.g * k) / 255;
          b = (c.b * k) / 255;
        }

(* csg -> ppm *)
let ppm w h scene =
  print_string "P6 ";
  print_int w;
  print_string " ";
  print_int h;
  print_string " 255";
  print_newline ();

  let w' = float_of_int w in
  let h' = float_of_int h in

  let rec yloop y =
    let rec xloop x =
      if x >= w' then yloop (y +. 1.) else
        let color = view ((x /. w') *. 3.) (y /. h') scene in
        print_char (char_of_int color.r);
        print_char (char_of_int color.g);
        print_char (char_of_int color.b);
        xloop (x +. 1.)
    in if y >= h' then () else xloop 0.
  in yloop 0.

(* Test scene *)
let sphere1 = Sphere(Vector(0.35,0.35,0.5), 0.3, {r = 255; g = 255; b = 0})
let sphere2 = Sphere(Vector(0.55,0.55,0.7), 0.4, {r = 0; g = 0; b = 255})
let sphere3 = Sphere(Vector(1.35,0.35,0.5), 0.3, {r = 255; g = 255; b = 0})
let sphere4 = Sphere(Vector(1.55,0.55,0.7), 0.4, {r = 0; g = 0; b = 255})
let sphere5 = Sphere(Vector(2.35,0.35,0.5), 0.3, {r = 255; g = 255; b = 0})
let sphere6 = Sphere(Vector(2.55,0.55,0.7), 0.4, {r = 0; g = 0; b = 255})
let csg1 = Union(Primitive(sphere1), Primitive(sphere2))
let csg2 = Difference(Primitive(sphere3), Primitive(sphere4))
let csg3 = Intersection(Primitive(sphere5), Primitive(sphere6))
let csg = Union(csg1, Union(csg2, csg3))
let light = vector_normalize (Vector(-1.0,-1.0,-2.0))
let scene = Scene(light, csg)

let _ = ppm 1500 500 scene

Name: Anonymous 2010-09-24 18:29

>>17
I'm pretty certain you can fold all those lets into one.

Name: Anonymous 2010-09-24 18:39

>>18
FOLD MY ANUS

Name: Anonymous 2010-09-25 2:00

Name: Anonymous 2010-09-25 11:18

>>20
Ah, I confused if with http://en.wikipedia.org/wiki/Symmetric_difference

Image: http://img185.imageshack.us/img185/3281/testjs.png

type color = {r: int; g: int; b: int}
type vector = Vector of float * float * float
type solid = Sphere of vector * float * color
type interval = Interval of float * float * solid
type csg =
    Union of csg * csg
  | Difference of csg * csg
  | Intersection of csg * csg
  | Primitive of solid
type scene = Scene of vector * csg

(* set operations *)
let rec union a b =
  match (a, b) with
      ([], _) -> b
    | (_, []) -> a
    | ((Interval(a_l, a_h, _) as a_e) :: a_r,
       (Interval(b_l, b_h, b_s) as b_e) :: b_r) ->
      if a_h < b_l then a_e :: union a_r b else
      if b_h < a_l then b_e :: union a b_r else
      let before = if b_l < a_l then [Interval (b_l, a_l, b_s)] else [] in
      let after = if b_h > a_h then [Interval (a_h, b_h, b_s)] else [] in
      before @ union ([a_e] @ after @ a_r) b_r

let rec difference a b =
  match (a, b) with
      ([], _) -> []
    | (_, []) -> a
    | ((Interval(a_l, a_h, a_s) as a_e) :: a_r,
       (Interval(b_l, b_h, _)) :: b_r) ->
      if a_h <= b_l then a_e :: difference a_r b else
      if b_h <= a_l then difference a b_r else
      let before = if a_l < b_l then [Interval(a_l, b_l, a_s)] else [] in
      let after = if a_h > b_h then [Interval(b_h, a_h, a_s)] else [] in
      before @ difference (after @ a_r) b

let rec intersection a b =
  match (a, b) with
      ([], _) -> []
    | (_, []) -> []
    | (Interval(a_l, a_h, a_s) :: a_r,
       Interval(b_l, b_h, b_s) :: b_r) ->
      if a_h <= b_l then intersection a_r b else
      if b_h <= a_l then intersection a b_r else
      Interval(max a_l b_l, min a_h b_h, if a_l <= b_l then b_s else a_s) ::
        if a_h > b_h then intersection a b_r else intersection a_r b

(* vectors *)
let vector_sub (Vector(a_x, a_y, a_z)) (Vector(b_x, b_y, b_z)) =
  Vector(a_x -. b_x, a_y -. b_y, a_z -. b_z)

let vector_dot (Vector(a_x, a_y, a_z)) (Vector(b_x, b_y, b_z)) =
  a_x *. b_x +. a_y *. b_y +. a_z *. b_z

let vector_mul (Vector(a_x, a_y, a_z)) k =
  Vector(a_x *. k, a_y *. k, a_z *. k) 

let vector_norm (Vector(a_x, a_y, a_z)) =
  sqrt(a_x *. a_x +. a_y *. a_y +. a_z *. a_z)

let vector_normalize v =
  vector_mul v (1. /. (vector_norm v))

(* line/sphere intersection *)
let line_sphere o i (Sphere(c, r, _) as s) =
  let c' = vector_sub c o in
  let i_c' = vector_dot i c' in
  let det = i_c' ** 2. -. (vector_dot c' c') +. r ** 2. in
  if det <= 0. then [] else
    let sqrt_det = sqrt det in
    [Interval(i_c' -. sqrt_det, i_c' +. sqrt_det, s)]

(* normal calculation *)
let point_normal p (Sphere(c, _, _)) =
  vector_normalize (vector_sub p c)

(* ray / csg intersection *)
let primitive_ray o i s =
  match s with Sphere _ -> line_sphere o i s

let rec ray o i csg =
  match csg with
      Union(a, b) -> union (ray o i a) (ray o i b)
    | Difference(a, b) -> difference (ray o i a) (ray o i b)
    | Intersection(a, b) -> intersection (ray o i a) (ray o i b)
    | Primitive(s) -> primitive_ray o i s

(* pixel -> color *)
let rec visible l =
  match l with
      [] -> None
    | (Interval(_, h, _) as i) :: r ->
      if h > 0. then Some i else visible r

let view x y (Scene(light, csg)) =
  let o = Vector(x,y,0.) in
  let i = Vector(0.,0.,1.) in
  match visible (ray o i csg) with
      None -> {r=0;g=0;b=0}
    | Some Interval(z, _, s) ->
      let z' = max 0. z in
      let p = vector_sub o (vector_mul i (z' *. -1.)) in
      let normal = point_normal p s in
      let r = vector_sub i (vector_mul normal (2. *. (vector_dot normal i))) in
      let spec_lum = max 0. (vector_dot light r) in
      let diff_lum = max 0. (vector_dot light normal) in
      let lum = spec_lum ** 4. *. 0.4 +. diff_lum ** 2. *. 0.6 in
      match s with Sphere(_d, _, c) ->
        let k = int_of_float (50. +. lum *. 205.) in
        {
          r = (c.r * k) / 255;
          g = (c.g * k) / 255;
          b = (c.b * k) / 255;
        }

(* csg -> ppm *)
let ppm w h scene =
  print_string "P6 ";
  print_int w;
  print_string " ";
  print_int h;
  print_string " 255";
  print_newline ();

  let w' = float_of_int w in
  let h' = float_of_int h in

  let rec yloop y =
    let rec xloop x =
      if x >= w' then yloop (y +. 1.) else
        let color = view ((x /. w') *. 3.) (y /. h') scene in
        print_char (char_of_int color.r);
        print_char (char_of_int color.g);
        print_char (char_of_int color.b);
        xloop (x +. 1.)
    in if y >= h' then () else xloop 0.
  in yloop 0.

(* Test scene *)
let sphere1 = Sphere(Vector(0.35,0.35,0.5), 0.3, {r = 255; g = 255; b = 0})
let sphere2 = Sphere(Vector(0.55,0.55,0.7), 0.4, {r = 0; g = 0; b = 255})
let sphere3 = Sphere(Vector(1.35,0.35,0.5), 0.3, {r = 255; g = 255; b = 0})
let sphere4 = Sphere(Vector(1.55,0.55,0.7), 0.4, {r = 0; g = 0; b = 255})
let sphere5 = Sphere(Vector(2.35,0.35,0.5), 0.3, {r = 255; g = 255; b = 0})
let sphere6 = Sphere(Vector(2.55,0.55,0.7), 0.4, {r = 0; g = 0; b = 255})
let csg1 = Union(Primitive(sphere2), Primitive(sphere1))
let csg2 = Difference(Primitive(sphere4), Primitive(sphere3))
let csg3 = Intersection(Primitive(sphere6), Primitive(sphere5))
let csg = Union(csg1, Union(csg2, csg3))
let light = vector_normalize (Vector(-1.0,-1.0,-2.0))
let scene = Scene(light, csg)

let _ = ppm 1500 500 scene

Name: Anonymous 2010-09-26 20:36

RAYTRACE MY ANUS

Name: Anonymous 2010-09-30 2:27

5 days remaining!

Name: Anonymous 2010-09-30 11:24

penis

Name: Anonymous 2010-09-30 16:41

Haskell is a medium-sized penis

Name: Anonymous 2010-09-30 16:50

>>25
YUO MENA HASKAL

Name: Anonymous 2010-09-30 17:42

>>25-26
Stop bumping your thread.

Name: Anonymous 2010-09-30 17:50

>>27
it's not my thread faggot.

Bumping is a legitimate form of trolling. YHBT YHL HAND

Name: Anonymous 2010-09-30 17:54

Failing is not the same as trolling.

Name: Anonymous 2010-09-30 18:03

I BUMP ALL DAY

Name: Anonymous 2010-09-30 18:11

I BUMP ALL NIGHT

Name: Anonymous 2010-09-30 19:31

>>29
YHBT ;D

Name: Anonymous 2010-09-30 19:38

I bump in a crepuscular manner

Name: Anonymous 2010-12-23 17:23

Name: Anonymous 2010-12-25 23:33

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List