diff options
author | Colin Okay <colin@cicadas.surf> | 2022-07-17 12:42:42 -0500 |
---|---|---|
committer | Colin Okay <colin@cicadas.surf> | 2022-07-17 12:42:42 -0500 |
commit | 53019e4770d1cf9999201e261fd6d93ab3c0d849 (patch) | |
tree | e3ff351b917577149705271c42aa877b665e6cd3 /src | |
parent | b72153a73875fc0081d072b90ac411c0eaef08a8 (diff) |
[wip]
Diffstat (limited to 'src')
-rw-r--r-- | src/grid-geometry.lisp | 70 | ||||
-rw-r--r-- | src/interactive/canvas.lisp | 1 | ||||
-rw-r--r-- | src/utils.lisp | 27 |
3 files changed, 74 insertions, 24 deletions
diff --git a/src/grid-geometry.lisp b/src/grid-geometry.lisp new file mode 100644 index 0000000..cef69f8 --- /dev/null +++ b/src/grid-geometry.lisp @@ -0,0 +1,70 @@ +;;; grid-geometry.lisp + +(in-package :wheelwork ) + +(defmacro with-grid-line + ((x y) (start-x start-y) (end-x end-y) &body body) + "Execute BODY for X and Y assigned to integer values in a line +connecting the integer point START-X , START-Y and END-X, END-Y. " + (with-gensyms (sx sy ex ey distance step progress xdiff ydiff) + `(loop + with ,sx = ,start-x + with ,sy = ,start-y + with ,ex = ,end-x + with ,ey = ,end-y + with ,xdiff = (- ,ex ,sx) + with ,ydiff = (- ,ey, sy) + with ,distance = (max (abs ,xdiff) (abs ,ydiff)) + for ,step from 0 to ,distance + for ,progress = (if (zerop ,distance) 0.0 (/ ,step ,distance)) + for ,x = (round (+ ,start-x (* ,progress ,xdiff))) + for ,y = (round (+ ,start-y (* ,progress ,ydiff))) + do (progn ,@body)))) + +(defmacro with-grid-path + ((x y) (path &key autoclosep interiorp) &body body) + (with-gensyms (points x1 y1 x2 y2 more) + (let ((autoclose-block + (when autoclosep + `(destructuring-bind (,x2 ,y2) (first ,points) + (with-grid-line (,x2 ,y2) (,x1 ,y1) ,@body))))) + `(let ((,points ,path)) + (loop + for ((,x1 ,y) (,x2 ,y2) . ,more) on ,points + while ,x2 do + (with-grid-line (,x ,y) (,x1 ,y1) (,x2 ,y2) ,@body) + finally (progn ,autoclose-block)))))) + +(defun grid-bbox-for (poly) + "POLY is a list of pairs of xy coordinates. Return a pair of +pairs, ((min-x min-y) (max-x max-y)), representing the bottom left and +top right corners of the bounding box for POLY " + (loop for (x y) in poly + minimizing x into x-min + maximizing x into x-max + minimizing y into y-min + maximizing y into y-max + finally (return (list (list x-min y-min) + (list x-max y-max))))) + +(defmacro with-grid-poly-interior + ((x y) perimeter &body body) + "PERMIETER is expected to evaluate to a list of contiguous points, +representing the permimeter a polygon in 2d space. Execute BODY for +each point interior to this polygon." + (with-gensyms (points bottom left top right) + `(let ((,points ,permieter)) + (destructuring-bind ((,left ,bottom) (,right ,top)) (grid-bbox-for ,points) + (loop ) + ))) + ) + +(defmacro with-grid-circle + ((x y) (cx cy radius &key interiorp) &body body) + (with-gensyms (rad sx sy) + (let ((comparator + (if interiorp '>= '=))) + `(let ((,sx ,cx) (,sy ,cy) (,rad ,radius)) + (with-grid-rect (,x ,y) ((- ,sx ,rad) (- ,sy ,rad) (+ ,sx ,rad) (+ ,sy ,rad)) + (when (,comparator ,rad (round (euclidean-dist ,x ,y ,sx ,sy))) + ,@body)))))) diff --git a/src/interactive/canvas.lisp b/src/interactive/canvas.lisp index e8bdc39..7f24d89 100644 --- a/src/interactive/canvas.lisp +++ b/src/interactive/canvas.lisp @@ -92,7 +92,6 @@ e.g., drawing a line in a particular color." (with-grid-line (,x ,y) (,start-x ,start-y) (,end-x ,end-y) (with-pixel (,r ,g ,b ,a) (pixel ,pxs ,x ,y) ,@body))))) - (defvar *canvas-shader-program* nil) (defvar *canvas-render-vao* nil) (defvar *canvas-count* 0) diff --git a/src/utils.lisp b/src/utils.lisp index 4037b7a..7b68e3d 100644 --- a/src/utils.lisp +++ b/src/utils.lisp @@ -41,7 +41,6 @@ and B intersects the linesegment between C and D, NIL otherwise." while b2 thereis (segments-intersect-p a1 a2 b1 b2)))) - (defun closed-path-p (path) (equalp (first path) (first (last path)))) @@ -63,8 +62,6 @@ and B intersects the linesegment between C and D, NIL otherwise." finally (return (oddp intersection-count))))) - - (defun path-encloses-path-p (path-a path-b) "T if path-b is totally contained in path-a and does not intersect path-a" (assert (closed-path-p path-a) () "Enclosing path must be a closed path.") @@ -115,23 +112,7 @@ the path." `(let ((,value ,value-form)) (setf ,@clauses)))) - -(defmacro with-grid-line - ((x y) (start-x start-y) (end-x end-y) &body body) - "Execute BODY for X and Y assigned to integer values in a line -connecting the integer point START-X , START-Y and END-X, END-Y. " - (with-gensyms (sx sy ex ey distance step progress xdiff ydiff) - `(loop - with ,sx = ,start-x - with ,sy = ,start-y - with ,ex = ,end-x - with ,ey = ,end-y - with ,xdiff = (- ,ex ,sx) - with ,ydiff = (- ,ey, sy) - with ,distance = (max (abs ,xdiff) (abs ,ydiff)) - for ,step from 0 to ,distance - for ,progress = (if (zerop ,distance) 0.0 (/ ,step ,distance)) - for ,x = (round (+ ,start-x (* ,progress ,xdiff))) - for ,y = (round (+ ,start-y (* ,progress ,ydiff))) - do (progn ,@body)))) - +(defun euclidean-dist (x1 y1 x2 y2) + (let ((dx (- x2 x1)) + (dy (- y2 y1))) + (sqrt (+ (* dx dx) (* dy dy))))) |