efficient animationOf for animations where the next image depends on the current image

11 views
Skip to first unread message

Brandon Barker

unread,
Aug 31, 2018, 9:08:59 PM8/31/18
to codeworld-discuss
Or, how can we write an animation of a recursively generated list?

I have something like:

collatzF :: Integer -> Integer
collatzF n
  | n `mod` 2 == 0 = n `quot` 2
  | otherwise      = 3 * n + 1


collatz :: Integer -> [Integer]
collatz nn
  | nn == 1 = [1]  
  | otherwise = nn : collatz(collatzF(nn))

Now I would like to write collatzAnimation :: Double -> Picture

But it seems like animationOf, as written, would have to call collatz from for every time interval of interest afresh, which would not be very efficient.

Another alternative might be to use Memoizable, but this would use unnecessary memory. Maybe, it is time to wrap my head around the State monad, but I thought I'd check if there was a better, more functional way with the current API.

Chris Smith

unread,
Aug 31, 2018, 10:11:37 PM8/31/18
to codeworl...@googlegroups.com
This is precisely what activityOf (or the older simulationOf, which will soon be deprecated) are for.  You provide an initial state, a function describing how the state changes as the program runs, and a function from state to a Picture.

main = activityOf initial change picture
initial = [1]
change (KeyPress _) (n:ns) = collatzF n : n : ns
change _ state = state
picture ns = ...

I used the KeyPress event here to take a step in each key press.  You can also use Time passing to do it once per second.  But in this case, your state will need to include not only the list of numbers, but also the time until the next change.  You can even do both!

initial = (1, [1])

change (TimePassing dt) (t, ns)
  | dt < t = (t - dt, ns)
  | otherwise = (1, step ns)
change (KeyPress _) (_, ns) = (1, step ns)
change _ state = state

step (n:ns) = collatzF n : n : ns

Does that make sense?

Thanks for trying this.  Hope you're having fun!

--
You received this message because you are subscribed to the Google Groups "codeworld-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to codeworld-disc...@googlegroups.com.
To post to this group, send email to codeworl...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/codeworld-discuss/24c01302-597b-4d0f-bdce-3572bac59123%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Brandon Barker

unread,
Sep 1, 2018, 5:15:13 PM9/1/18
to codeworld-discuss
Thanks! We are having fun. This makes sense and works well! 
Reply all
Reply to author
Forward
0 new messages