Re: [Haskell-cafe] Animated line art
On 06/12/2008, at 6:32 AM, Andrew Coppin wrote: Tim Docker wrote: If you implement your drawing logic as a function from time to the appropriate render actions, ie | import qualified Graphics.Rendering.Cairo as C | | type Animation = Time - C.Render () then you just need to call this function multiple times to generate sucessive frames. That was my initial idea... but I'm not sure how well it would work. I want to do stuff like fade elements in and out, move complex structures around on the screen, etc. I think it might end up being a little tangled if I go with this approach. I might be wrong though... This model of animation as a function of time to a picture is probably described in many places. I first saw it described in Paul Hudaks book The haskell School of Expression: Learning functional programming through multimedia. It shows how primitive animations can be combined in various ways, including overlays and time transformations. You can download the code from the books web-site, which might be of interest even if you can't get hold of a copy of the book. It's intended for pedagogical purposes, rather than a comprehensive animation system, of course. Tim ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
Andrew Coppin wrote: So I want some sort of sequencing primitives. Sequencing generally suggests a monad. something = do { action1; delay 10; action2} I had a go at writing what I thought the interface might look like. (Fortunately, I made no attempt to *implement* it - otherwise I would doubtless have wasted huge amounts of time implementing something that isn't designed right yet!) Unfortunately Haskell doesn't really provide a way to write an interface, and then write the implementation behind it seperately somewhere else. So the code I wrote wasn't actually compilable at all, but it was useful to sketch something out. When I do this I generally write functions like foo = error foo: Not implemented yet My initial idea was that I could have some kind of monad for controlling adding and removing stuff. The monad could provide an add action that adds a visual object to the frame and returns a unique ID. Then you could have a remove action that removes the specified ID again. And a wait action that makes the display stay the same for so many seconds. (But the visual objects may internally be animated.) I'd suggest that each object has its own action to animate it. You will need to write a custom monad to interleave actions. See http://www.cs.chalmers.se/~koen/pubs/jfp99-monad.ps for something along the right lines. Then I hit upon the idea that maybe one thread of control could spawn a second one - so that for example one thread could generate a bunch of snowflakes raining down the screen while a seperate thread rotates a geometric figure in the center. Or something. Sounds right. Of course, these threads have no need (or use) for actually running concurrently - they are only concurrent in the sence that they both affect the same frame, rather than their actions happening one after another on consecutive frames. Next I got to thinking that maybe these threads of control might need to communicate for synchronisation. E.g., when a rotating line reaches 90° with another line, a signal is sent to another thread, which then adds another visual element or stops the animation or something. The parent thread *could* algebraicly _compute_ what time this will happen, but sending a signal is much simpler. (E.g., if you change the speed of an animation, the threads still stay synchronised without you having to remember to adjust parameters in your calculations all over the place...) Yup. I did exactly this, albeit for a very different application. Unfortunately the code belongs to my employer so I can't post it. But if you look at the paper above and also read about the ContT monad you will get the right idea. Its a bit mind-bending, but you suspend a thread by getting its continuation (using callCC) and stuffing it into whatever data structure is being used to hold pending threads (e.g. a semaphore queue). Or you could use the existing concurrent threads mechanism, which is kludgier but less work. There's still one little problem though. The threads of control are for sequencing stuff. They are inherantly discrete; *add* this thing, *remove* this other thing, *send* this signal, *wait* to receive a signal, etc. But something like, say, rotating a line, is inherantly continuous. So there's a discrete system for sequencing stuff - which I seem to have worked out fairly well - and there also needs to be a continuous system for doing all the things with are smooth functions of time. Thats where Reactive stuff comes in. So maybe the continuous stuff should just be a type alias to a regular Haskell function? Ah, but wait... I said I might want to send a signal when an animation reaches a specific stage, right? So these functions need to do more than just map time to some other variable; they need to be able to send signals. And hey, actually, what are the chances of a time sample exactly lining up with the instant that the notable event occurs? How do I want to handle that? Events are part of reactive frameworks. Paul. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
Martijn van Steenbergen wrote: Andrew Coppin wrote: It seems that the correct course of action is to design a DSL for declaratively describing animated line art. Does anybody have ideas about what such a thing might look like? You could take a look at Fran [1] and Yampa [2] which both seem to do animations in Haskell. [1] http://conal.net/Fran/ [2] http://www.haskell.org/yampa/ I don't think either of them will do precisely what I want, but they give me lots of useful stuff to think about. PS. The flying heads were disturbing though. PPS. Yampa is still in active development. [...] This page last updated March 22 2004. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
Tim Docker wrote: Someone else already mentioned FRAN and it's ilk. But perhaps you don't need something that fancy. If you implement your drawing logic as a function from time to the appropriate render actions, ie | import qualified Graphics.Rendering.Cairo as C | | type Animation = Time - C.Render () then you just need to call this function multiple times to generate sucessive frames. That was my initial idea... but I'm not sure how well it would work. I want to do stuff like fade elements in and out, move complex structures around on the screen, etc. I think it might end up being a little tangled if I go with this approach. I might be wrong though... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
Ben Lippmeier wrote: The ANUPlot graphics library I wrote does exactly this. The darcs repo is at http://code.haskell.org/ANUPlot/ANUPlot-HEAD/ It comes with lots of examples that do the sort of things you describe. Does it handle drawing lines and circles (with antialiasing)? Can I save the output as PNG? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
Today I sat down and had a think about this problem. After reading about various FRP systems (Yampa et al) I had a few ideas in my head. The main idea is that I want to be able to draw lines and curves and so forth, and I want to add them to and remove them from the display at various times, and move them around, change their colour and opacity, etc. I also want to be able to run one piece of animation, and then another, and then another. So I want some sort of sequencing primitives. I had a go at writing what I thought the interface might look like. (Fortunately, I made no attempt to *implement* it - otherwise I would doubtless have wasted huge amounts of time implementing something that isn't designed right yet!) Unfortunately Haskell doesn't really provide a way to write an interface, and then write the implementation behind it seperately somewhere else. So the code I wrote wasn't actually compilable at all, but it was useful to sketch something out. My initial idea was that I could have some kind of monad for controlling adding and removing stuff. The monad could provide an add action that adds a visual object to the frame and returns a unique ID. Then you could have a remove action that removes the specified ID again. And a wait action that makes the display stay the same for so many seconds. (But the visual objects may internally be animated.) Then I hit upon the idea that maybe one thread of control could spawn a second one - so that for example one thread could generate a bunch of snowflakes raining down the screen while a seperate thread rotates a geometric figure in the center. Or something. Of course, these threads have no need (or use) for actually running concurrently - they are only concurrent in the sence that they both affect the same frame, rather than their actions happening one after another on consecutive frames. Next I got to thinking that maybe these threads of control might need to communicate for synchronisation. E.g., when a rotating line reaches 90° with another line, a signal is sent to another thread, which then adds another visual element or stops the animation or something. The parent thread *could* algebraicly _compute_ what time this will happen, but sending a signal is much simpler. (E.g., if you change the speed of an animation, the threads still stay synchronised without you having to remember to adjust parameters in your calculations all over the place...) There's still one little problem though. The threads of control are for sequencing stuff. They are inherantly discrete; *add* this thing, *remove* this other thing, *send* this signal, *wait* to receive a signal, etc. But something like, say, rotating a line, is inherantly continuous. So there's a discrete system for sequencing stuff - which I seem to have worked out fairly well - and there also needs to be a continuous system for doing all the things with are smooth functions of time. So maybe the continuous stuff should just be a type alias to a regular Haskell function? Ah, but wait... I said I might want to send a signal when an animation reaches a specific stage, right? So these functions need to do more than just map time to some other variable; they need to be able to send signals. And hey, actually, what are the chances of a time sample exactly lining up with the instant that the notable event occurs? How do I want to handle that? ...and at this point, it was time to go home! :-D ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
On 06/12/2008, at 6:34 AM, Andrew Coppin wrote: Ben Lippmeier wrote: The ANUPlot graphics library I wrote does exactly this. The darcs repo is at http://code.haskell.org/ANUPlot/ANUPlot-HEAD/ It comes with lots of examples that do the sort of things you describe. Does it handle drawing lines and circles (with antialiasing)? Can I save the output as PNG? Lines and circles yes, antialiasing no. It uses OpenGL for rendering, so maybe there's a flag to turn it on. PNG isn't usually required for animations. When I need to make an image I just do a screenshot. Ben. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
You may also want to at least look at RSAGL, in particular I've implemented an arrow transformer that does much of what you describe with threading, although I see that I probably need to go back and work on documentation. The basic idea revolves around giving threads an identity type that implements Eq. The parent thread can cull threads it doesn't want, while the threads themselves can spawn new threads or self-terminate. If a thread spawns a thread ID that already exists, the new duplicate is disregarded (unless you choose to provide a different behaviour). Anonymous threads are implemented using Maybe. Threads have an explicit ultimate input and output type, and can explicitly switch themselves over to another thread with matching input and output types. Both the spawn and switch directives take a continuous input, which is a list or Maybe respectively containing information about what spawn or switch should be dispatched at that moment. Since it's an arrow transformer, you can for example pass messages between threads by layering it on top of a StateArrow. I have also used a StateArrow to accumulate rendering instructions and to manage a transformation matrix context. You talk about adding and removing things, but I don't think that's a good idea. Rather the thing's existence and disposition is a continuous function within a thread. If it assists with understanding, the StatefulArrow is a stripped down arrow transformer version of the YAMPA arrow, and the other arrows build on that functionality until you get to the FRP arrow. The git repo is browsable here: http://roguestar.downstairspeople.org/gitweb?p=rsagl.git;a=summary Relevant modules are ThreadedArrow, SwitchedArrow, StatefulArrow, FRPBase and FRP. I don't have any 2D support in RSAGL at all. Hopefully this helps and I'd also appreciate any feedback. --Lane ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
Andrew Coppin wrote: It seems that the correct course of action is to design a DSL for declaratively describing animated line art. Does anybody have ideas about what such a thing might look like? You could take a look at Fran [1] and Yampa [2] which both seem to do animations in Haskell. [1] http://conal.net/Fran/ [2] http://www.haskell.org/yampa/ Martijn. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Animated line art
It seems that the correct course of action is to design a DSL for declaratively describing animated line art. Does anybody have ideas about what such a thing might look like? Someone else already mentioned FRAN and it's ilk. But perhaps you don't need something that fancy. If you implement your drawing logic as a function from time to the appropriate render actions, ie | import qualified Graphics.Rendering.Cairo as C | | type Animation = Time - C.Render () then you just need to call this function multiple times to generate sucessive frames. Tim ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
Andrew, I can think of several reasons why simple time-indexed animation may be a bad idea. Some important aspects of animation are usually: 1) A main use case is playback, where time change is continuous and monotonic. 2) Differential action is often much cheaper than time jumping (i.e. between adjacent time steps most lines do not move and do not need to be recomputed. It is cheaper to modify the previous animation.) 3) Time is a topological space, with lots of nice properties: change of time is a group, intervals are decomposable, etc. Animation inherits this structure as a G-torsor (e.g. between two close enough times the line art should look very similar, there is no canonical start time). You are throwing this all away if you just treat line art like a point set. 4) Although your Time set may be discrete, you may want to pretend it is smooth to facilitate e.g. motion blur and simulation, which strongly favor a differential approach. There is often a need for run-up or adaptive time interval subdivision. Clip start and stop times are often changed interactively. Instead of defining a calculus (line art indexed by time), you may want to define an algebra (action of time change on line art). You can manipulate the algebra independently for efficiency (e.g. combine adjacent time intervals into one big interval if pointwise evaluation is cheap, or subdivide an interval if differential change is cheap) and then apply the final result to line art defined at some time origin. Take a quick read of http://en.wikipedia.org/wiki/Principal_bundle where the (group) G is time change and the (fiber bundle) P is the line art. At minimum, implement your time argument as a start time + delta time, and consider a State monad (or StateT monad transformer) to hold future optimizations like cached (time,art) pairs in case you change your mind. Dan Tim Docker wrote: It seems that the correct course of action is to design a DSL for declaratively describing animated line art. Does anybody have ideas about what such a thing might look like? Someone else already mentioned FRAN and it's ilk. But perhaps you don't need something that fancy. If you implement your drawing logic as a function from time to the appropriate render actions, ie | import qualified Graphics.Rendering.Cairo as C | | type Animation = Time - C.Render () then you just need to call this function multiple times to generate sucessive frames. Tim ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Animated line art
On 05/12/2008, at 10:46 AM, Tim Docker wrote: Someone else already mentioned FRAN and it's ilk. But perhaps you don't need something that fancy. If you implement your drawing logic as a function from time to the appropriate render actions, ie | import qualified Graphics.Rendering.Cairo as C | | type Animation = Time - C.Render () then you just need to call this function multiple times to generate sucessive frames. The ANUPlot graphics library I wrote does exactly this. The darcs repo is at http://code.haskell.org/ANUPlot/ANUPlot-HEAD/ It comes with lots of examples that do the sort of things you describe. Ben. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe