Replace primitive circles with polygon approximation

This commit is contained in:
Camden Dixie O'Brien 2025-05-29 01:14:30 +01:00
parent 668d369943
commit 08f3ed8411

View File

@ -1,12 +1,18 @@
(defstruct line points)
(defstruct circle radius centre)
(defstruct polygon points)
(defun line (start-x start-y end-x end-y)
(list (make-line :points (vector start-x start-y end-x end-y))))
(defun circle (radius centre-x centre-y)
(list (make-circle :radius radius :centre (vector centre-x centre-y))))
(defun circle (radius centre-x centre-y &optional (segments 32))
(let ((points (make-array (* segments 2))))
(dotimes (i segments)
(let ((angle (* 2 pi (/ i segments))))
(setf (aref points (* i 2))
(+ centre-x (* radius (cos angle))))
(setf (aref points (1+ (* i 2)))
(+ centre-y (* radius (sin angle))))))
(list (make-polygon :points points))))
(defun rectangle (left-x bottom-y width height)
(let ((right-x (+ left-x width))
@ -22,8 +28,7 @@
(bottom-y (- centre-y (/ height 2))))
(rectangle left-x bottom-y width height)))
(defmacro define-transform (name (&rest params)
&key x-transform y-transform scalar-transform)
(defmacro define-transform (name (&rest params) &key x-transform y-transform)
`(defun ,name (,@params drawing)
(labels ((transform-points (points)
(let ((new-points (copy-seq points)))
@ -39,13 +44,6 @@
(line
(make-line
:points (transform-points (line-points primitive))))
(circle
(make-circle
:radius ,(if scalar-transform
`(let ((s (circle-radius primitive)))
,scalar-transform)
'(circle-radius primitive))
:centre (transform-points (circle-centre primitive))))
(polygon
(make-polygon
:points (transform-points
@ -58,8 +56,7 @@
(define-transform scale (scale-factor)
:x-transform (* scale-factor x)
:y-transform (* scale-factor y)
:scalar-transform (* scale-factor s))
:y-transform (* scale-factor y))
(define-transform rotate (theta)
:x-transform (- (* x (cos theta)) (* y (sin theta)))