Quantcast
Channel: Hacker News
Viewing all articles
Browse latest Browse all 25817

Raytracer.el: a raytracer in Emacs Lisp

$
0
0
(require 'cl)(defunsq (x) (* x x))(defunmag (xyz) (sqrt (+ (sq x) (sq y) (sq z))))(defununit-vector (xyz) (let ((d (mag x y z))) (values (/ x d) (/ y d) (/ z d))))(defstruct (point (:conc-namenil)) x y z)(defundistance (p1p2) (mag (- (x p1) (x p2)) (- (y p1) (y p2)) (- (z p1) (z p2))))(defunminroot (abc) (if (zerop a) (/ (- c) b) (let ((disc (- (sq b) (*4 a c)))) (unless (minusp disc) (let ((discrt (sqrt disc))) (min (/ (+ (- b) discrt) (*2 a)) (/ (- (- b) discrt) (*2 a))))))))(defstructsurface color)(defvar*world*nil)(defvar*eye*nil)(defvar*xres*256)(defvar*yres*256)(defuntracer (buffer-nameres) (save-excursion (ignore-errors (kill-buffer buffer-name)) (switch-to-buffer buffer-name) (fundamental-mode) (insert (format"P2 %s%s 255" (* res *xres*) (* res *xres*))) (newline) (let ((inc (/1.0 res))) (do ((y (- (/ *yres* 2)) (+ y inc))) ((< (- (/ *yres* 2) y) inc)) (do ((x (- (/ *xres* 2)) (+ x inc))) ((< (- (/ *xres* 2) x) inc)) (insert (format"%s" (color-at x y)))))) (set-visited-file-name buffer-name) (save-buffer)))(defuncolor-at (xy) (multiple-value-bind (xr yr zr) (unit-vector (- x (x *eye*)) (- y (y *eye*)) (-0 (z *eye*))) (round (* (send-ray *eye* xr yr zr) 255))))(defunsend-ray (ptxryrzr) (multiple-value-bind (s int) (first-hit pt xr yr zr) (if s (* (lambert s int xr yr zr) (surface-color s))0)))(defunfirst-hit (ptxryrzr) (let (surface hit dist) (dolist (s *world*) (let ((h (intersect s pt xr yr zr))) (when h (let ((d (distance h pt))) (when (or (null dist) (< d dist)) (setf surface s hit h dist d)))))) (values surface hit)))(defunlambert (sintxryrzr) (multiple-value-bind (xn yn zn) (normal s int) (max0 (+ (* xr xn) (* yr yn) (* zr zn)))))(defstruct (sphere (:include surface)) radius center)(defundefsphere (xyzrc) (let ((s (make-sphere:radius r:center (make-point :x x :y y :z z):color c))) (push s *world*)))(defunintersect (sptxryrzr) (funcall (typecase s (sphere #'sphere-intersect)) s pt xr yr zr))(defunsphere-intersect (sptxryrzr) (let* ((c (sphere-center s)) (n (minroot (+ (sq xr) (sq yr) (sq zr)) (*2 (+ (* (- (x pt) (x c)) xr) (* (- (y pt) (y c)) yr) (* (- (z pt) (z c)) zr))) (+ (sq (- (x pt) (x c))) (sq (- (y pt) (y c))) (sq (- (z pt) (z c))) (- (sq (sphere-radius s))))))) (if n (make-point :x (+ (x pt) (* n xr)):y (+ (y pt) (* n yr)):z (+ (z pt) (* n zr))))))(defunnormal (spt) (funcall (typecase s (sphere #'sphere-normal)) s pt))(defunsphere-normal (spt) (let ((c (sphere-center s))) (unit-vector (- (x c) (x pt)) (- (y c) (y pt)) (- (z c) (z pt)))))(defunray-test (res) (setf *world* nil) (setf *eye* (make-point :x0.0:y0.0:z200.0)) (defsphere 0-300-1200200.8) (defsphere -80-150-1200200.7) (defsphere 70-100-1200200.9) (do ((x -3 (1+ x))) ((> x 3)) (do ((z 2 (1+ z))) ((> z 9)) (defsphere (* x 200) 300 (* z -400) 40.75))) (tracer "image.pbm" res));(byte-compile 'distance);(message (format "%s" (length (aref (symbol-function 'distance) 1))));(save-excursion; (switch-to-buffer "x"); (disassemble 'distance "x"); (insert (format "%s" (aref (aref (symbol-function 'distance) 1) 29))); (set-visited-file-name "d"); (save-buffer))(defunf (x) (if x (* x x) nil))(if (fboundp 'jit-compile) (defmacrojit (f) `(progn;; (jit-compile ,f);; (trace-function ,f) )) (defmacrojit (f)))(jit 'f)(jit 'minroot)(jit 'sq)(jit 'mag)(jit 'unit-vector)(jit 'distance)(jit 'tracer)(jit 'color-at)(jit 'send-ray)(jit 'first-hit)(jit 'lambert)(jit 'defsphere)(jit 'intersect)(jit 'sphere-intersect)(jit 'normal)(jit 'sphere-normal)(jit 'ray-test)

Viewing all articles
Browse latest Browse all 25817

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>