Write define-transform macro for common transform logic

This commit is contained in:
Camden Dixie O'Brien 2025-05-29 01:14:30 +01:00
parent 5ce814867d
commit 8738229053

View File

@ -22,44 +22,44 @@
(bottom-y (- centre-y (/ height 2)))) (bottom-y (- centre-y (/ height 2))))
(rectangle left-x bottom-y width height))) (rectangle left-x bottom-y width height)))
(defun translate (delta-x delta-y drawing) (defmacro define-transform (name (&rest params)
(defun translate-points (points) &key x-transform y-transform scalar-transform)
`(defun ,name (,@params drawing)
(labels ((transform-points (points)
(let ((new-points (copy-seq points))) (let ((new-points (copy-seq points)))
(do ((i 0 (+ i 2))) (do ((i 0 (+ i 2)))
((>= i (length points))) ((>= i (length points)))
(incf (aref new-points i) delta-x) (let ((x (aref new-points i))
(incf (aref new-points (1+ i)) delta-y)) (y (aref new-points (1+ i))))
(setf (aref new-points i) ,x-transform)
(setf (aref new-points (1+ i)) ,y-transform)))
new-points)) new-points))
(defun translate-primitive (primitive) (transform-primitive (primitive)
(typecase primitive (typecase primitive
(line (make-line :points (translate-points (line-points primitive)))) (line
(make-line
:points (transform-points (line-points primitive))))
(circle (circle
(make-circle (make-circle
:radius (circle-radius primitive) :radius ,(if scalar-transform
:centre (translate-points (circle-centre primitive)))) `(let ((s (circle-radius primitive)))
,scalar-transform)
'(circle-radius primitive))
:centre (transform-points (circle-centre primitive))))
(polygon (polygon
(make-polygon (make-polygon
:points (translate-points (polygon-points primitive)))))) :points (transform-points
(mapcar #'translate-primitive drawing)) (polygon-points primitive)))))))
(mapcar #'transform-primitive drawing))))
(defun scale (scale-factor drawing) (define-transform translate (delta-x delta-y)
(defun scale-points (points) :x-transform (+ delta-x x)
(let ((new-points (copy-seq points))) :y-transform (+ delta-y y))
(dotimes (i (length points))
(setf (aref new-points i) (define-transform scale (scale-factor)
(* scale-factor (aref new-points i)))) :x-transform (* scale-factor x)
new-points)) :y-transform (* scale-factor y)
(defun scale-primitive (primitive) :scalar-transform (* scale-factor s))
(typecase primitive
(line (make-line :points (scale-points (line-points primitive))))
(circle
(make-circle
:radius (* scale-factor (circle-radius primitive))
:centre (scale-points (circle-centre primitive))))
(polygon
(make-polygon
:points (scale-points (polygon-points primitive))))))
(mapcar #'scale-primitive drawing))
(defun overlay (&rest drawings) (defun overlay (&rest drawings)
(apply #'append drawings)) (apply #'append drawings))