Re: [Haskell-cafe] Animated line art

2008-12-08 Thread Tim Docker


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

2008-12-06 Thread Paul Johnson

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

2008-12-05 Thread Andrew Coppin

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

2008-12-05 Thread Andrew Coppin

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

2008-12-05 Thread Andrew Coppin

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

2008-12-05 Thread Andrew Coppin
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

2008-12-05 Thread Ben Lippmeier


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

2008-12-05 Thread Christopher Lane Hinson


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

2008-12-04 Thread Martijn van Steenbergen

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

2008-12-04 Thread Tim Docker
 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

2008-12-04 Thread Dan Weston

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

2008-12-04 Thread Ben Lippmeier




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