[racket] Making animations in racket (or, why racket is hard to transition to from scratch)

From: Robby Findler (robby at eecs.northwestern.edu)
Date: Tue Feb 1 21:35:05 EST 2011

I'll leave the pedagogy questions to others, but for the performance
questions, can you tell me what version you were using and the size of
the png images (wxh)?


On Tue, Feb 1, 2011 at 8:27 PM, Yaron Minsky <yminsky at gmail.com> wrote:
> I am trying to teach my scratch-addicted son a bit about racket, and I'm
> finding it to be rather tough going, mostly because a lot of things that are
> really easy in scratch seem surprisingly hard in racket.  Also, even when I
> can get things done, the performance of the graphics leaves something to be
> desired.  I'm wondering if this is just the way the world is right now, or
> if somehow I'm approaching this the wrong way.
> I was trying to put together a simple animation using the universe and image
> teachpacks where:
> - there is a "sprite" which switches between two images periodically
> - the sprite is always pointing at the mouse
> I wrote some code for doing this.  One problem is that getting this to work
> required some actual trigonometry, which my 9 year old isn't quite ready
> for.  But that I could fix by writing a simple helper function.  But the
> other problem is that the resulting code is horribly slow.  As soon as you
> rotate the image, the rendering performance falls through the floor, and you
> see a ton of flickering.
> I've attached the code below.  I can imagine some ways of optimizing this
> (for example, doing the rotations only on mouse moves, and storing the
> resulting rotated images in the world-struct), but I want to keep the coding
> style pretty simple, and I think these kinds of optimizations get in the way
> of comprehensibility.
> Another thing I'd be interested in suggestions with is how to deal with
> updating a struct in a clean way.  Right now, you need to explicitly wrote
> set-world-X functions for each field in your struct, which is pretty ugly.
>  Also, the fact that structs don't have field names makes them more error
> prone.  None of this is well suited towards building complex worlds with
> lots of components.  I'm wondering if there is a better way of approaching
> this that doesn't require quadratic boilerplate, and that is suitable for
> teaching to a kid.
> Anyway, here's the code.  Thanks in advance!
> ;; the images here are actual PNG images, which don't show up nicely in
> ascii...
> (define pic1 .)
> (define pic2 .)
> (define (posn-diff a b)
>   (make-posn
>    (- (posn-x a) (posn-x b))
>    (- (posn-y a) (posn-y b))))
> (define (posn-mag p)
>   (sqrt (+ (sqr (posn-x p)) (sqr (posn-y p)))))
> (define (angle-between pos1 pos2)
>   (let*
>       ((delta (posn-diff pos2 pos1))
>        (hyp (posn-mag delta))
>        (angle-in-radians (if (= hyp 0) 0 (asin (/ (posn-y delta) hyp))))
>        )
>     (-(* angle-in-radians (/ 180 pi)))))
> (define-struct world (pos mouse-pos time))
> (define initial-world (make-world (make-posn 200 200) (make-posn 200 200)
> 0))
> (define (draw w)
>   (place-image
>    (rotate (angle-between (world-pos w) (world-mouse-pos w))
>            (if (is-even (round (world-time w))) pic1 pic2))
>    (posn-x (world-pos w))
>    (posn-y (world-pos w))
>    (empty-scene 400 400)))
> (define (tick w)
>   (make-world
>    (world-pos w)
>    (world-mouse-pos w)
>    (+ 0.1 (world-time w))))
> (define (mouse w x y event)
>   (make-world
>    (world-pos w)
>    (make-posn x y)
>    (world-time w)
>    ))
> (big-bang
>  initial-world
>  (on-draw draw)
>  (on-tick tick)
>  (on-mouse mouse)
>  )
> _________________________________________________
>  For list-related administrative tasks:
>  http://lists.racket-lang.org/listinfo/users

Posted on the users mailing list.