;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;;  EXAMPLE USING PATH GROUPS AND VECTORS

;;

;; To draw more complex images effiecently a number of

;; graphics paths can be drawn in a single operation.

;; It is also possible to move a group of paths in a single

;; operation.

;;

;; This example makes use of several vector functions for

;; more efficient vector operation:

;; vector= vector-rand vector- vector*

;; for really fast vector and matrix processing you should

;; investigate the veclib:, vdsp: and vimage: libraries

;;

;; There are a number of further efficiencies that we

;; could add to this code:

;; firstly, xpoints and ypoints could be declared globally

;; and reused instead of reallocating new vectors every time

;; loop is applied.

;;

;; vectors also allow for recycling of

;; elements (using vector-recycle), which can substantially reduce

;; garbage collection, although be careful that each vector element

;; contains a unique scheme object reference or you will get unexpected

;; results. you should be safe if you always allocate new vectors using

;; make-vector-with-proc and (random).

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; set up graphics including vectors for paths, points, colours, styes etc.

(define canvas (gfx:make-canvas))

(gfx:clear-canvas (now) canvas '(0 0 0 1)) ; black background

(define nodes 200) ; number of squares to animate

(define size 5) ; square size

; setup paths at random coordinates between 100,100 and 200,200

(define paths (make-vector-with-proc nodes

(lambda (i)

(gfx:make-square (random 100 200)

(random 100 200)

size))))

; defaults for drawing path group

(define widths (make-vector nodes 1.0))

(define styles (make-vector nodes *gfx:stroke-path*)) ; stroke only

; setup default colours

(define fills (make-vector (* nodes 4))) ; we are not going to fill

(define strokes (make-vector (* nodes 4)))

(math:vector= strokes 1.0 (list 0 nodes 4)) ; set red to 1.0

(math:vector-rand strokes (list 1 nodes 4)) ; randomize green

(math:vector= strokes 0.0 (list 2 nodes 4)) ; set blue to 0.0

(math:vector= strokes 0.3 (list 3 nodes 4)) ; set alpha to 0.3

; main animation loop

; NOTE: we could declare xpoints and ypoints globally and

; resuse these each time through loop in order to avoid

; constantly reallocating vector memory

(define loop

(lambda (time)

(let ((xpoints (make-vector nodes))

(ypoints (make-vector nodes)))

(math:vector-rand xpoints)

(math:vector- xpoints 0.5)

(math:vector* xpoints 20.0)

(math:vector-rand ypoints)

(math:vector- ypoints 0.5)

(math:vector* ypoints 20.0)

(gfx:move-group time paths xpoints ypoints)

(gfx:draw-group (+ time 5) canvas paths strokes fills widths styles)

(callback (+ time 500) 'loop (+ time 2000)))))

; start

(loop (now))