POV-Ray : Newsgroups : povray.binaries.images : Ripple Tank Sim Server Time
5 Nov 2024 09:24:44 EST (-0500)
  Ripple Tank Sim (Message 1 to 10 of 16)  
Goto Latest 10 Messages Next 6 Messages >>>
From: clipka
Subject: Ripple Tank Sim
Date: 11 Aug 2009 03:44:34
Message: <4a812162@news.povray.org>
a ripple tank simulation, computed with POV-Ray 3.7.0.beta.33; original 
size of render: 300x100 pixels (this is a scaled-up 100x100 excerpt); 
frame 6000 of 9999, total computation time for the whole sequence 30 
minutes on a Core i7 (7 threads).

Green area indicates wave generator shape; red areas indicate barriers.

(An optimized C program could probably do the whole smash in a matter of 
seconds - even a naive attempt does it in about a minute - but that's 
not the point :P)

As an interesting side note, although performing bulk mathematical 
simulation, the SDL script doesn't use a single function (except for 
auxiliary purposes), not a single array, no file #write or #read, and 
only a single control statement (an #if, for special treatment of the 
very first frame). Virtually all it does is render frame after frame of 
the animation.


Post a reply to this message


Attachments:
Download 'wavetank.jpg' (63 KB)

Preview of image 'wavetank.jpg'
wavetank.jpg


 

From: Thomas de Groot
Subject: Re: Ripple Tank Sim
Date: 11 Aug 2009 10:45:03
Message: <4a8183ef$1@news.povray.org>
"clipka" <ano### [at] anonymousorg> schreef in bericht 
news:4a812162@news.povray.org...
>a ripple tank simulation, computed with POV-Ray 3.7.0.beta.33; original
> size of render: 300x100 pixels (this is a scaled-up 100x100 excerpt);
> frame 6000 of 9999, total computation time for the whole sequence 30
> minutes on a Core i7 (7 threads).
>
> Green area indicates wave generator shape; red areas indicate barriers.
>
> (An optimized C program could probably do the whole smash in a matter of
> seconds - even a naive attempt does it in about a minute - but that's
> not the point :P)
>
> As an interesting side note, although performing bulk mathematical
> simulation, the SDL script doesn't use a single function (except for
> auxiliary purposes), not a single array, no file #write or #read, and
> only a single control statement (an #if, for special treatment of the
> very first frame). Virtually all it does is render frame after frame of
> the animation.
>

This is VERY interesting as we all - sooner or later - need HF's for water 
reflecting/refracting from obstacles. I know I did for my TC-RTC 
contribution, but I let it be for the time being.

Thomas


Post a reply to this message

From: triple r
Subject: Re: Ripple Tank Sim
Date: 11 Aug 2009 12:20:00
Message: <web.4a8199b9f3b84fbd958421d50@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:

> (An optimized C program could probably do the whole smash in a matter of
> seconds - even a naive attempt does it in about a minute - but that's
> not the point :P)

It's likely, but they both slow down quickly since, for an n x n grid, the time
increases at a rate of O(n^3).  I'm running a version right now that's 6th
order in space and time, and it takes about four hours or so for about 10000
frames at 1000x1000 resolution.

> As an interesting side note, although performing bulk mathematical
> simulation, the SDL script doesn't use a single function (except for
> auxiliary purposes), not a single array, no file #write or #read, and
> only a single control statement (an #if, for special treatment of the
> very first frame). Virtually all it does is render frame after frame of
> the animation.

Wait a minute--no #while?  No arrays?  Are you using textures or what?  Sounds
like great material for an obfuscated POV contest, but maybe it's really
straightforward.  Let me guess...  Read the last two frames as a texture.  Move
the last frame up, down, left, and right by one pixel.  Add together and
subtract the last frame to get a laplacian.  Then do a simple explicit
iteration in time to get the next frame as a texture.  Render.  Repeat.  (?)

 - Ricky


Just thinking out loud...  er, silently...

Wave equation:
d^2p/dt^2 = c^2 del^2 p

Discretize the time derivative:
(p_n+1 - 2*p_n + p_n-1)/dt^2 = c^2 del^2 p

Rearrange:
p_n+1 = 2*p_n - p_n-1 + (c*dt)^2 del^2 p

Discretize the laplacian:
p_n+1 = 2*p_n - p_n-1 + (c*dt/dx)^2 (p_i+1,j + p_i-1,j + p_i,j+1 + p_i,j-1 -
4*p_i,j)

So to get the next frame, read the last two as a texture.  Add twice the last
frame minus the second-to-last frame.  Then add (c*dt/dx)^2 multiplied by the
sum of the last frame shifted in every direction by a pixel minus 4 times the
last frame.

Render?


Post a reply to this message

From: stbenge
Subject: Re: Ripple Tank Sim
Date: 11 Aug 2009 14:53:22
Message: <4a81be22$1@news.povray.org>
clipka wrote:
> a ripple tank simulation, computed with POV-Ray 3.7.0.beta.33;

It's funny you should come up with this, since yesterday I was thinking 
about how to do this very thing. We have no persistent variables, but 
using images would work.

This reminds me. It would be really sweet if we could have POV output an 
image with an exact name during an animation, such as "water.png" 
instead of "water001.png". This would make iterative image production a 
much neater process. As it is now, whenever I have an iterative imaging 
setup I end up with a ton of images in the directory.

Good job! I think I'll stick to C programming for this effect though. 
It's easy enough to produce a barrier and generator mask using POV, and 
then take it into C to run the sim :/

Sam


Post a reply to this message

From: stbenge
Subject: Re: Ripple Tank Sim
Date: 11 Aug 2009 15:40:10
Message: <4a81c91a@news.povray.org>
stbenge wrote:
> We have no persistent variables, but using images would work.

I guess a person could #write to a file and generate persistent 
variables that way...


Post a reply to this message

From: clipka
Subject: Re: Ripple Tank Sim
Date: 11 Aug 2009 15:45:10
Message: <4a81ca46$1@news.povray.org>
triple_r schrieb:
> It's likely, but they both slow down quickly since, for an n x n grid, the time
> increases at a rate of O(n^3).  I'm running a version right now that's 6th
> order in space and time, and it takes about four hours or so for about 10000
> frames at 1000x1000 resolution.

I guess the O(n^3) applies not to an increased "tank" size, but an 
increased resolution (which then also requires an increased resolution 
of time I guess), right?


> Wait a minute--no #while?  No arrays?  Are you using textures or what?  Sounds
> like great material for an obfuscated POV contest, but maybe it's really
> straightforward.

Indeed. The algorithm should also be perfectly suited for a cellular 
automaton (ah well, in a way that water-tank-alike thing *is* a cellular 
automaton, if only with a very high number of states...). There's only a 
slight bit of obfuscation in it because...

- The math isn't as obvious when you do it with textures

- So far I've used a more naive approach than what you propose, 
explicitly keeping track of both pressure and velocity (2 dimensions) 
separately (yet side-by-side in the same frame - hence the 3:1 aspect 
ratio), not realizing that the velocity can be inferred from the 
difference between previous frames (then again, can it? after all, the 
difference is an overlay of velocity influences in two dimensions... 
except of course if you process only a single dimension per step). This 
of course uses some weird hacks to properly superimpose the various 
dimensions.


> So to get the next frame, read the last two as a texture.  Add twice the last
> frame minus the second-to-last frame.  Then add (c*dt/dx)^2 multiplied by the
> sum of the last frame shifted in every direction by a pixel minus 4 times the
> last frame.
> 
> Render?

Something along these lines, yes. Except that I'm not that deep into 
"official" math to know what a "laplacian" is - I just derived the 
iteration approach from basics (and I should also note that it's not an 
exact simulation of water waves - rather an idealized medium, in which 
waves propagate by straightforward interaction of some scalar 
"potential" field and a 2d-vector "flux" field (or however you want to 
call it), without any other effects to mess up things (except a small 
damping factor I introduced, to prevent quantization noise from building 
up). And, as I mentioned, so far I explicitly store the "flux" field 
instead of referring to older frames. (My first approach actually 
computed each component separately, using a three-frame cycle for 
potential, X-flux and Y-flux, but it was darn ugly to watch ;-) I also 
figured (correctly) that using a combined-frame approach might speed up 
things, especially since parsing time was a significant factor.)


I was wondering indeed whether there would be ways to streamline the 
algorithm. I also wonder whether doing multiple iteration steps per 
frame (by overlaying more copies of the last two frames) might speed up 
things, as parsing (and probably image loading and saving) still eats a 
good deal of the time, and there's possibly other significant overhead 
involved. After all, we're talking about ~40 fps.


Ah, one last note: I guess OpenEXR should be recommended for this 
application of POV-Ray.


Post a reply to this message

From: clipka
Subject: Re: Ripple Tank Sim
Date: 11 Aug 2009 16:00:32
Message: <4a81cde0$1@news.povray.org>
stbenge schrieb:
> Good job! I think I'll stick to C programming for this effect though. 
> It's easy enough to produce a barrier and generator mask using POV, and 
> then take it into C to run the sim :/

I mainly did it because the C(/++) program I had written earlier only 
produced ASCII art output, and it did quite well for starters, but I got 
tired of its limitations, and was too lazy to integrate support for 
proper image reading and writing ;-)

And, of course, misusing POV-Ray in this manner was an interesting 
challenge to do ;-)

Next on the agenda: Game of life. Should be a piece of cake if done 
properly: Read in last frame, apply a color map according to birth/death 
rules, overlay with 8 tuned-down displaced copies to add birth/death 
hints for the next step - render.


Post a reply to this message

From: clipka
Subject: Re: Ripple Tank Sim
Date: 11 Aug 2009 16:31:51
Message: <4a81d537$1@news.povray.org>
stbenge schrieb:
>> We have no persistent variables, but using images would work.
> 
> I guess a person could #write to a file and generate persistent 
> variables that way...

You positively don't want to do that with a ripple tank sim :P


Post a reply to this message

From: triple r
Subject: Re: Ripple Tank Sim
Date: 11 Aug 2009 18:05:01
Message: <web.4a81ead7f3b84fbd805d39df0@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:=
> I guess the O(n^3) applies not to an increased "tank" size, but an
> increased resolution (which then also requires an increased resolution
> of time I guess), right?

Exactly.  It's the CFL (Courant-Friedrichs-Lewy) condition, and it basically
just says that information can't travel more than one grid cell per step.  This
means that if you double the resolution, you also have to cut the time step in
half to preserve stability.  So if you double the resolution, you have a factor
of four, and halving the time step makes 8.

> - So far I've used a more naive approach than what you propose,
> explicitly keeping track of both pressure and velocity (2 dimensions)
> separately (yet side-by-side in the same frame - hence the 3:1 aspect
> ratio), not realizing that the velocity can be inferred from the
> difference between previous frames (then again, can it? after all, the
> difference is an overlay of velocity influences in two dimensions...
> except of course if you process only a single dimension per step). This
> of course uses some weird hacks to properly superimpose the various
> dimensions.

Sorry for all the math.  I just popped my head in and saw something I couldn't
resist responding to.

Mathematically, you can rewrite the wave equation as two first order PDE's:

d^2p/dt^2 = d^2p/dx^2 + d^2p/dy^2 = del^2 p

becomes

dp/dt = div( v )
dv/dt = grad( p )

This is equivalent since differentiating the first, dp/dt, gives

d^2p/dt^2 = d/dt div(v) = div( dv/dt ) = div( grad(p) ) = del^2 p

Then, as you've done, you just store three quantities (i.e. pressure and 2 x
velocity) and compute them separately.  They're mathematically equivalent, but
computationally different.  For my approach, you need two previous frames but
only one quantity.  For your approach you need one previous frame, but three
quantities.

> Something along these lines, yes. Except that I'm not that deep into
> "official" math to know what a "laplacian" is

Sorry for the lingo; it's just the sum of second derivatives (curvature) in all
the different dimensions.  If the overall curvature is downward, it accelerates
downward, and vice versa.

 - Ricky


Post a reply to this message

From: triple r
Subject: Re: Ripple Tank Sim
Date: 11 Aug 2009 19:55:00
Message: <web.4a8203d5f3b84fbd805d39df0@news.povray.org>
clipka <ano### [at] anonymousorg> wrote:
> As an interesting side note, although performing bulk mathematical
> simulation, the SDL script doesn't use a single function (except for
> auxiliary purposes), not a single array, no file #write or #read, and
> only a single control statement (an #if, for special treatment of the
> very first frame). Virtually all it does is render frame after frame of
> the animation.

Sometimes you have to do things the fun way.  That got me thinking.  It's not
POV-Ray, but here's what I came up with.  It should compile on any kind of x11
system.  It's about as short as I could get it with a gui and an interesting
setup.  Not written for clarity (although it's really pretty straightforward).
;-)

 - Ricky

Compile with: 'cc main.c -O3 -L/usr/X11R6/lib -lX11'
Run with: ./a.out

#include <X11/Xlib.h>
#include <math.h>
int main(){int i,j,y=200,p,v;float*a,*b,
*c,*t,f[6*y*y];Display*d=XOpenDisplay(0)
;Window w=RootWindow(d,0);GC g=XCreateGC
(d,w,0,0);w=XCreateSimpleWindow(d,w,0,0,
y*2,y,0,0,0);XMapWindow(d,w);a=f;b=f+2*y
*y;c=f+y*y*4;for(i=0;i<y*y*6;f[i++]=0){}
for(;;++*f){for(i=1;i<y*2-1;i++)for(j=1;
j<y-1;j++){if((fabs(i-y)>1)|(fabs(fabs(j
-y/2)-y/10)<8)){p=i*y+j;p[a]=(b[p-1]+b[p
+1]+b[p-y]+b[p+y])/2-p[c];v=fmin(fmax(a[
p]*500+127,0),255);XSetForeground(d,g,v|
v<<8|v<<16|v<<24);XDrawPoint(d,w,g,i,j);
}}a[y*(1+y)/2]=sin(*f*.4);t=c,c=b,b=a,a=
t;}return 0;}


Post a reply to this message

Goto Latest 10 Messages Next 6 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.