
Well, actually testing any of these out seems to eat all the RAM on my
box & I have to kill it...I don't think that I'm 'morally' doing
anything wrong, so I guess I've just been assuming it's related to the
other ticket I filed where the same thing happened. That might not be
a safe assumption though...
As for physics. One person on #haskell (can't remember who...)
suggested making a pure interface to chipmunk similar to FieldTrip's
interface to OpenGL. That seems like a good & pragmatic idea. Being
a bit of a physics nerd, I think it'd be really cool to make an entire
2d or 3d engine to go with Reactive from the ground up. It'd probably
be a lot of fun to work on but it might not be the fastest way to the
finish.
Cheers,
Creighton
On Sat, Dec 6, 2008 at 7:30 AM, Peter Verswyvelen
Nice. I haven't been able yet to test any of these, anyone? What is your opinion about physics in Reactive? Should we try to make an adapter to an optimized imperative physics engine, or should we write one in Haskell?
On Wed, Dec 3, 2008 at 10:38 PM, Creighton Hogg
wrote: So this is a bit of a brainstorming post. I did a little thinking earlier about different simple ODE solving techniques, and tried to translate them fairly directly into Reactive. The result isn't pretty & I'd like to talk about that.
The naive definitions, to me, of the Euler, Euler-Cromer, and Midpoint methods should look like the following. Each takes in an Event (), initial positions & velocities, and a Behavior (v -> v -> v) that is the acceleration as a function of time. We want to be general since the acceleration may be an explicit function of time as well as as position & velocity.
euler tau x0 v0 a = liftA2 (,) x v where x = accumB x0 (fmap (^+^) (liftA2 (^*) (prev vi) deltaTs)) v = accumB v0 (fmap (^+^) (liftA2 (^*) ai deltaTs)) ai = (snapshot_ tau a) <*> (prev xi) <*> (prev vi) xi = (snapshot_ tau x) vi = (snapshot_ tau v) deltaTs = diffE (tau `snapshot_` time)
eulerCromer tau x0 v0 a = liftA2 (,) x v where x = accumB x0 (fmap (^+^) (liftA2 (^*) vi deltaTs)) v = accumB v0 (fmap (^+^) (liftA2 (^*) ai deltaTs)) ai = (snapshot_ tau a) <*> (prev xi) <*> (prev vi) xi = snapshot_ tau x vi = snapshot_ tau v deltaTs = diffE (tau `snapshot_` time)
midpoint tau x0 v0 a = liftA2 (,) x v where x = accumB x0 (fmap (^+^) (liftA2 (^*) vavg deltaTs)) v = accumB v0 (fmap (^+^) (liftA2 (^*) ai deltaTs)) ai = (snapshot_ tau a) <*> (prev xi) <*> (prev vi) xi = snapshot_ tau x vi = snapshot_ tau v deltaTs = diffE (tau `snapshot_` time) vavg = fmap (^/2) $ liftA2 (^+^) vi (prev vi)
prev :: Event a -> Event a prev = fmap snd . withPrevE
this code is fairly verbose, but that's because I'm trying to be very explicit about the ordering of the sampling & how the new values at each time step are created. The problem is that I feel like I'm wrestling very hard against Reactive rather than working with it. I was hoping that I could get some feedback on a way to write these very simple algorithms that is more inline with the spirit of the API.