SchemeによるRaytracer
July 15, 2004
ANSI Common Lispの簡易レイトレーサをScheme (DrScheme)へ移植してみました。
dolistとpushのマクロを定義しています。
(define sq
(lambda (x)
(* x x)))
(define mag
(lambda (x y z)
(sqrt (+ (sq x) (sq y) (sq z)))))
(define unit-vector
(lambda (x y z)
(let ((d (mag x y z)))
(values (/ x d) (/ y d) (/ z d)))))
(define-struct point (x y z))
(define distance
(lambda (p1 p2)
(mag (- (point-x p1) (point-x p2))
(- (point-y p1) (point-y p2))
(- (point-z p1) (point-z p2)))))
(define minroot
(lambda (a b c)
(if (zero? a)
(/ (- c) b)
(let ((disc (- (sq b) (* 4 a c))))
(if (negative? disc)
#f
(let ((discrt (sqrt disc)))
(min (/ (+ (- b) discrt) (* 2 a))
(/ (- (- b) discrt) (* 2 a)))))))))
(define-struct surface (color))
(define *world* null)
(define eye (make-point 0 0 200))
(define tracer
(lambda (pathname res)
(let ((p (open-output-file pathname 'replace)))
(fprintf p "P2 ~A ~A 255 ~n" (* res 100) (* res 100))
(let ((inc (/ res)))
(do ((y -50 (+ y inc)))
((< (- 50 y) inc))
(do ((x -50 (+ x inc)))
((< (- 50 x) inc))
(fprintf p "~A ~n" (color-at x y)))))
(close-output-port p))))
(define color-at
(lambda (x y)
(call-with-values
(lambda ()
(unit-vector (- x (point-x eye))
(- y (point-y eye))
(- 0 (point-z eye))))
(lambda (xr yr zr)
(inexact->exact
(round (* (sendray eye xr yr zr) 255)))))))
(define sendray
(lambda (pt xr yr zr)
(call-with-values
(lambda () (first-hit pt xr yr zr))
(lambda (s int)
(if (null? s)
0
(* (lambert s int xr yr zr) (surface-color s)))))))
(define-syntax dolist
(syntax-rules ()
((dolist (el list) body1 body2 ...)
(do ((to-do list (cdr to-do)))
((null? to-do))
(let ((el (car to-do)))
body1
body2
...)))
((dolist (el list res) body1 body2 ...)
(do ((to-do list (cdr to-do)))
((null? to-do) res)
(let ((el (car to-do)))
body1
body2
...)))))
(define first-hit
(lambda (pt xr yr zr)
(let ((surface null) (hit null) (dist null))
(dolist (s *world*)
(let ((h (intersect s pt xr yr zr)))
(when h
(let ((d (distance h pt)))
(when (or (null? dist) (< d dist))
(set! surface s)
(set! hit h)
(set! dist d))))))
(values surface hit))))
(define lambert
(lambda (s int xr yr zr)
(call-with-values
(lambda () (normal s int))
(lambda (xn yn zn)
(max 0 (+ (* xr xn) (* yr yn) (* zr zn)))))))
(define-struct (sphere surface) (radius center))
(define-syntax push
(syntax-rules ()
((push item list)
(set! list (cons item list)))))
(define defsphere
(lambda (x y z r c)
(let ((s (make-sphere c r (make-point x y z))))
(push s *world*)
s)))
(define intersect
(lambda (s pt xr yr zr)
(cond
((sphere? s) (sphere-intersect s pt xr yr zr)))))
(define sphere-intersect
(lambda (s pt xr yr zr)
(let* ((c (sphere-center s))
(n (minroot
(+ (sq xr) (sq yr) (sq zr))
(* 2 (+ (* (- (point-x pt) (point-x c)) xr)
(* (- (point-y pt) (point-y c)) yr)
(* (- (point-z pt) (point-z c)) zr)))
(+ (sq (- (point-x pt) (point-x c)))
(sq (- (point-y pt) (point-y c)))
(sq (- (point-z pt) (point-z c)))
(- (sq (sphere-radius s)))))))
(if n
(make-point
(+ (point-x pt) (* n xr))
(+ (point-y pt) (* n yr))
(+ (point-z pt) (* n zr)))
#f))))
(define normal
(lambda (s pt)
(cond
((sphere? s) (sphere-normal s pt)))))
(define sphere-normal
(lambda (s pt)
(let ((c (sphere-center s)))
(unit-vector (- (point-x c) (point-x pt))
(- (point-y c) (point-y pt))
(- (point-z c) (point-z pt))))))
(define ray-test
(lambda (res)
(set! *world* null)
(defsphere 0 -300 -1200 200 .8)
(defsphere -80 -150 -1200 200 .7)
(defsphere 70 -100 -1200 200 .9)
(do ((x -2 (add1 x)))
((> x 2))
(do ((z 2 (add1 z)))
((> z 7))
(defsphere (* x 200) 300 (* z -400) 40 .75)))
(tracer "spheres.pgm" res)))
実行は、(ray-test 1)。生成されるファイルはpgm形式なので、Win/Mac系ではビューワが必要。
Common LispとSchemeのベンチマークはおもしろそうなので次回。実装に依存しまくりだろうけど。
TrackBack
TrackBack URL for this entry:
http://www.robios.org/x/mt/mt-tb.cgi/19
http://www.robios.org/x/mt/mt-tb.cgi/19
morgage morgage
Posted by: morgage at February 6, 2007 07:18 PMweb cam girls
Posted by: webcam girls at January 21, 2007 02:10 AMwebcam girls webcam girls
Posted by: webcam girls at January 20, 2007 06:39 AMGood job!
Posted by: Markus at December 12, 2006 02:53 AMThe face is the index of the mind... Isaac
Posted by: Isaac at November 30, 2006 05:13 PMMuch will have more... Cesar
Posted by: Cesar at November 30, 2006 05:48 AMMuch will have more... Cesar
Posted by: Cesar at November 30, 2006 05:47 AManimal sex pictures butt fuck straight male porn stars brunette models celebrity upskirts pantyhose pics hard cock horse sex women hardcore teen sex hentai babes free sex video clips free blonde galleries latin pussy male masturbation techniques interracial stories teen cum adult add leupold tactical models make it a hit cheerleader sex bikini and thong girls shemale clips exploited black teens girl cartoon spring break girls flashing incest fucking wet shaved pussy upskirt galleries hot tits gay guys black teen reality porn sites redheads naked piss webcam girls celebrity nudes scat fetish women forced to give oral sex chubby mature amanda bynes naked movies showtimes anal movies elisha cuthbert nude gay ass lesbian movie clips asian lesbians latin to english translator fat tits closeup mariah carey free gang bang lesbian bondage tenchi hentai video clips of tsunamis nude little girls brutal rape amateur pictures free anal sex pictures
Posted by: sex video at November 25, 2006 10:10 AMAll are not merry that dance lightly... Gabriel
Posted by: Gabriel at November 25, 2006 05:37 AMHe who likes borrowing dislikes paying... Gillam
Posted by: Gillam at November 25, 2006 05:02 AMGet a name to rise early, and you may lie all day... Stephen
Posted by: Stephen at November 22, 2006 06:50 PMThe heart that once truly loves never forgets... Fulk
Posted by: Fulk at November 22, 2006 06:18 PMhttp://stories.anzwers.net/gaymen/923982/directory.html complimentwhosewondered
Posted by: grip at February 28, 2006 11:32 AMhttp://www.simonhome.net/wwwboard/messages/2592.html billydriverseducing
Posted by: existence at February 13, 2006 05:34 AMhttp://www.femmesdenudees.com/lesbienne/hosenda/nudecelebs/live.html complimentwhosewondered
Posted by: except at January 18, 2006 06:52 PMすごっ!!(^3^)
Posted by: ToA at July 20, 2004 11:04 AM