3 (asdf:oos
'asdf
:load-op
'cl-gd
)
5 (defpackage #:rectangles
8 (in-package #:rectangles
)
11 ;; an abstract named rectangle thing
12 (defclass rectangle
()
13 ((x :accessor x-of
:iniform
0 :initarg
:x
)
14 (y :accessor y-of
:initform
0 :initarg
:y
)
15 (w :accessor width-of
:initform
1 :initarg
:width
)
16 (h :accessor height-of
:initform
1 :initarg
:height
)
17 (name :accessof name-of
:initform
"Unknown"))
19 ;; split one rectangle into two. Returns two rectangles,
20 ;; the first of which is the given fraction of the original,
21 ;; the second the remaining area of the original
22 (defmethod split ((self rectangle
) fraction
&key direction
)
26 ((h-top (* (height-of rectangle
) fraction
))
27 (h-bot (- (height-of rectangle
) h-top
))
28 (split-y (+ h-top
(y-of rectangle
))))
30 (make-instance 'rectangle
33 :width
(width-of rectangle
)
35 (make-instance 'rectangle
38 :width
(width-of rectangle
)
42 ((w-top (* (width-of rectangle
) fraction
))
43 (w-bot (- (width-of rectangle
) w-top
))
44 (split-x (+ w-top
(x-of rectangle
))))
46 (make-instance 'rectangle
50 :height
(height-of rectangle
))
51 (make-instance 'rectangle
55 :height
(height-of rectangle
)))))))
57 ;; Represents a chart of rectangles
59 ((rectangles :initform nil
)
60 (free-rectangle :initform
(make-instance 'rectangle
) :accessor free-rectangle-of
)))
63 ;; create a chart of rectangles from a property list of data
64 ;; ( ( "Name" . value ) ...)
66 (defmethod make-instance ((self chart
) &key data
)
69 "Return the sum od the data"
70 (reduce #'(lambda (t x
) (+ t
(cdr x
))) data
))
71 (normalise-data (sum data
)
75 collect
(cons (car element
) (/ (cdr element
) sum
))))
78 (normalise-data (sum-data data
) data
))
79 (split-for-datum (datum &key direction
)
82 (split (free-rectangle-of self
) (cdr datum
) :direction direction
)
84 (setf (free-rectangle-of self
) free
)
85 (setf (name-of taken
) (car data
))
86 (push (rectangles-of self
) taken
))))
89 ((split-for-datum (car data
) :horizontal
)
90 (consume-data (normalise (rest data
))))))
91 (consume-data data
))))
97 (asdf:oos
'asdf
:load-op
'cl-gd
)
102 (defun discretize (data range
)
107 ((result (make-array (array-total-size data
))))
108 (map-into result
#'(lambda (x) (round (* (/ x
(sum-data data
))))) range
)))
111 (defun region-sample (sample-count region sample-size sample-resolution sample-fn sample-score-fn
)
113 ((randomly-place main-region
&key within
)
114 (make-instance 'rectangle
115 :x
(+ (x-of region
) (random (- (width-of region
) (width-of within
))))
116 :y
(+ (y-of region
) (random (- (height-of region
) (height-of within
))))
117 :width
(width-of within
)
118 :height
(height-of within
))
119 (create-sample (region sample-resolution
)
121 ((result (make-array (* sample-resolution sample-resolution
)
125 for x
= (x-of region
) then
(+ x
(/ (width-of region
) sample-resolution
))
128 for y
= (y-of region
) then
(+ y
(/ (height-of region
) sample-resolution
))
129 (vector-push (funcall sample-fn x y
))))
132 ((sample-region-rectangle
133 (make-instance 'rectangle
134 :width
(* (width-of region
) sample-size
)
135 :height
(* (width-of region
) sample-size
)))
138 for sample-index from
0 below sample-count
142 (randomly-place sample-region-rectangle
:within region
)
143 sample-resolution
))))
147 for sample in samples
148 for sample-index
= 0 then
(1+ sample-index
)
151 (funcall sample-score-fun sample
)
155 for score in sample-scores
157 (cons (car score
) (nth (car score
) samples
))))))))