From ab4544c11d6542203d4c582ec7d6ecda6b470ae6 Mon Sep 17 00:00:00 2001 From: Colin Okay Date: Fri, 15 Jul 2022 12:38:52 -0500 Subject: [add] with-line macro --- src/package.lisp | 4 ++-- src/utils.lisp | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/package.lisp b/src/package.lisp index 57d1aac..73ff610 100644 --- a/src/package.lisp +++ b/src/package.lisp @@ -6,8 +6,8 @@ (:local-nicknames (#:mat #:3d-matrices) (#:vec #:3d-vectors)) (:import-from #:defclass-std #:defclass/std) - (:import-from #:alexandria - #:when-let #:when-let* #:if-let) + (:import-from #:alexandria-2 + #:when-let #:when-let* #:if-let #:with-gensyms) (:export ;; Affine API #:height diff --git a/src/utils.lisp b/src/utils.lisp index bcb4cb2..ed7be38 100644 --- a/src/utils.lisp +++ b/src/utils.lisp @@ -103,3 +103,27 @@ the path." :width (- max-x min-x) :height (- max-y min-y))))) +(defmacro setf-many (places-and-value) + "e.g. (setf-many a b c 10) would set a b and c to 10" + (let ((value-form + (first (last places-and-value)))) + `(setf ,@(butlast places-and-value) ,value-form))) + + +(defmacro with-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) + `(let* ((,sx ,start-x) + (,sy ,start-y) + (,ex ,end-x) + (,ey ,end-y) + (,xdiff (- ,ex ,sx)) + (,ydiff (- ,ey ,sy)) + (,distance (max (abs ,xdiff) (abs ,ydiff)))) + (loop 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))))) -- cgit v1.2.3