[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 22:54:23 EST 2011

Looks like the new underlying gui toolkit in the upcoming release
(http://blog.racket-lang.org/2010/12/racket-version-5.html) has the
right tools to make this fast, but unfortunately I didn't get time to
employ them for 5.1, so this will still be slow in the next release
(due out soon), but hopefully for the one after that it'll be zippy.

Robby

On Tue, Feb 1, 2011 at 8:52 PM, Yaron Minsky <yminsky at gmail.com> wrote:
> 133x126.  The PNG itself is 3K.  Running racket 5.0.2.
> As an irrelevant side-note, I noticed that I had a broken trig function in
> there.  I fixed it, but that actually had nothing to do with the
> performance.  I also went ahead and implemented caching of the rotated
> images, and the performance still isn't that great, although it's far
> better, at least when I don't move the mouse.
> y
>
> On Tue, Feb 1, 2011 at 9:35 PM, Robby Findler <robby at eecs.northwestern.edu>
> wrote:
>>
>> 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)?
>>
>> Robby
>>
>> 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.