[Fluxus] please help me with this drawing script...

evan.raskob evan.raskob
Sat Aug 1 13:16:23 PDT 2009


hi fluxus'ers,

i've been working on this example for drawing extruded shape paths  
using the mouse, and there are a few bugs that i just cannot figure  
out, for the life of me.

first, i am creating a list of vectors that represent path of a shape,  
as "drawn" on the screen using the mouse.  somehow, a list of  
#<void>'s that is equal in size to the list of points gets stuck on  
the list of points, and i can't figure out where or why.

second, i am trying to draw a bunch of particles where each particle  
is a point in the path currently being drawn, but they don't show on  
screen.  must have something to do with my camera angle...

i'm sending this out to the list because

a) i think its a pretty neat, useful example
b) i am stumped (for tonight).


Thanks!
Evan

;--------
;-- Begin draw-extruded-shapes.scm
;
;-- somewhat by evan raskob / pixelpusher
;-- http://pixelist.info



(clear)


(define (empty? l) (null? l))


;--- mix two numbers based on percent of first
(define (mix val1 val2 amt)
     (+ (* val2 (- 1 amt)) (* val1 amt))
     )



;----
; gets a line representing a segment of the projection of the mouse  
into 3D space

(define (get-line-from-mouse)
     (let* ((ndcpos (vector (* (- (/ (mouse-x) (vx (get-screen-size)))  
0.5) 2)
                     (* (- (- (/ (mouse-y) (vy (get-screen-size)))  
0.5)) 1.5) -1))
             (scrpos2 (vtransform (vmul ndcpos 50) (minverse (get- 
camera-transform))))
             (scrpos (vtransform ndcpos (minverse (get-camera- 
transform)))))
         (list scrpos scrpos2)))

; we'll just use the end of the projection line here
(define (mouse-pos)
     (cadr (get-line-from-mouse)))

; converts a 2D vector into an angle, with some dodgy dave maths
(define (2dvec->angle x y)
     (let ((q (/ 3.141 2)))
         (when (zero? y) (set! y 0.0001))
         (cond
             [(>= y 0)
                 (fmod (* (+ q q q (- q (atan (/ x y)))) 57.2957795)  
360)]
             [else
                 (fmod (* (+ q (- q (atan (/ x y)))) 57.2957795) 360)]
             )
         )
     )


;-----
;-- extrusion builder funcs

(define profile (build-circle-profile 12 0.5))

(define empty-path '( (vector 0 0 0) (vector 0 0 0) ))

(define (extruder path)
     (define a
         (with-state
             (wire-colour 0)
             (colour (vector 1 1 1))
             (specular (vector 1 1 1))
             (shinyness 20)
             (hint-wire)
             (build-partial-extrusion profile path 1)))
     a)


;------------------------------------------------------
; strokes are collections of points representing mouse movement

(define-struct stroke (points extr tme rot) #:mutable)

(define (build-stroke)
     (make-stroke (list) (extruder empty-path) (time) (vector 0 0 0)))

(define (stroke-clear stroke)
     (set-stroke-extr! (extruder empty-path)))

(define (stroke-add stroke pos)
     ;    (printf "pos: ~s" pos)(newline)
     (set-stroke-points! stroke (cons pos (stroke-points stroke))))

(define (stroke-last-point stroke)
     (cond
         [(not (empty? (stroke-points stroke)))
             (car (stroke-points stroke))]
         [else (vector -999 -999 -999)]
         )
     )


(define (stroke-update stroke)

     ; make a new point when the mouse is suitibly far from the last  
point
     (let [(m (mouse-pos))]
         (cond [(not (equal? (void) m))

                 (when (> (vdist (stroke-last-point stroke) (mouse- 
pos)) 0.5)
                     (stroke-add stroke (mouse-pos))
;                    (printf "added point: ~a / ~a" (mouse-pos)  
(stroke-last-point stroke))(newline)
                     )


                 (destroy (stroke-extr stroke))
                 (set-stroke-extr! stroke (extruder (stroke-points  
stroke)))
                 ])
         )
     )

(define (stroke-rotate stroke r)
     (set-stroke-rot! stroke (vector 0 0 (fmod (+ (vector-ref (stroke- 
rot stroke) 2) r) 360)))
     )


(define (stroke-advance stroke)
     (cond ([not (empty? (stroke-points stroke))]
             (let*
                 ((lst (stroke-points stroke))
                     (1st (car lst))
                     (l (- (length lst) 1))
                     (last (list-ref lst l))
                     (prv (list-ref lst (- l 1)))
                     (diff (vsub prv last))
                     )
                 (set-stroke-points! stroke (append (cdr lst) (list  
diff)))
                 )
             (stroke-update stroke)
             ))
     )


;------------------------------------------------------

; a fluxus mouse pointer!
(define (draw-mouse)
     (with-primitive mp
         (identity)
         (colour (vector 1 1 0))
         (translate (mouse-pos))
         (hint-unlit)
         ))

(define strokes (list))
(define mouseIsDown #f)


(define cstroke '())

(define last-txtr (car txtrs))


(define (draw-stroke s)
     (with-state
         (rotate (stroke-rot s))
         (with-primitive (stroke-extr s)
             (partial-extrude
                 (* (* 0.5 (+ 1 (sin (* 4 (- (time) (stroke-tme s))))))
                     (length (stroke-points s)))
                 profile
                 (stroke-points s)
                 (build-list (length (stroke-points s))
                     (lambda (n) 4))
                 (vector 0 0 1)
                 0.05)))
     )

(define (draw-strokes strokes)
     (cond [(not (empty? strokes))
             (for/list ((s strokes))
                 (draw-stroke s)
                 (stroke-rotate s rotz))
             ]
         )
     )

;--- this will outline the current path
(define p (build-particles 1))

(define b
     (with-state
         (scale 10)
         (build-cube)
         ))


;-- draw stroke path using particles

(define (draw-stroke-path s)
     (when (not (null? s))

         ;--- this next bit is for debugging
         (with-state
             (colour #(1 0 1))
             (identity)
             (translate #(0 0 -3))
             (scale 3)
             (draw-instance b)
             )
         ;--- end debug


         ;--- this is *not* efficient
         (destroy p)
         (set! p (build-particles (length (stroke-points s))))
         (with-primitive p
             (pdata-map! (lambda (c) (vector (flxrnd) 1 0)) "c")
             (pdata-index-map!
                 (lambda (index pos)
                     (list-ref (stroke-points s) index))
                 "p")
             )
         )
     )


;--- for debugging

(define (print-stroke-points s)
     (for/list ((p (stroke-points s)))
             (display p)(newline))
     )


(define speed -20)


;-------- useful state vars

(define rotz 0)
(define txoffset 0)


;--------- where the drawing gets done!!!!

(define (animate)

     (hint-unlit)
     (blur 0)
     ;(texture last-txtr)
     (opacity 0.5)
     ;   (blend-mode 'src-alpha 'dst-alpha)
     ;    (blend-mode 'src-alpha 'one)

     (hint-ignore-depth)
     (colour (vector 1 1 1))


     ;   (draw-mouse)
     (cond [(mouse-button 1)
             ;(display "down")(newline)
             (cond [(not mouseIsDown)
                     (set! mouseIsDown #t)
                     (set! cstroke (build-stroke))
                     (set-stroke-tme! cstroke (time))
                     ]
                 )
             (stroke-update cstroke)]

         [else
             (cond [ mouseIsDown
                     (set! strokes (cons cstroke strokes))
                     ])
             (set! mouseIsDown #f)
             ]
         )


     ;            (audio-distort cstroke)

     (draw-strokes strokes)
     (draw-stroke-path cstroke)
     )

(set-camera-transform (mtranslate (vector 0 0 -10)))
(light-diffuse 0 (vector 0 0 0))
(define l (make-light 'point 'free))
(light-diffuse l (vector 1 1 1))
(light-position l (vector -10 10 0))

(every-frame (animate))




More information about the Fluxus mailing list