POV-Ray : Newsgroups : povray.binaries.images : Ripple Tank Sim Server Time
31 Jul 2024 20:25:11 EDT (-0400)
  Ripple Tank Sim (Message 7 to 16 of 16)  
<<< Previous 6 Messages Goto Initial 10 Messages
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

From: stbenge
Subject: Re: Ripple Tank Sim
Date: 12 Aug 2009 05:34:18
Message: <4a828c9a$1@news.povray.org>
clipka wrote:
> 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 ;-)

I'm all for misusing programs and languages in this way. Heck, I'd go as 
far as to say that the more unique ways you can find to accomplish a 
singular goal, the better! "Unique ways" being the key of course ;)

> 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.

  Ah, with the #if statement right near the apex of that calculation? 
And with an average pattern instead of a function? Any way, I'd like to 
see it :)


Post a reply to this message

From: clipka
Subject: Re: Ripple Tank Sim
Date: 12 Aug 2009 14:25:18
Message: <4a83090e$1@news.povray.org>
stbenge schrieb:
> I'm all for misusing programs and languages in this way. Heck, I'd go as 
> far as to say that the more unique ways you can find to accomplish a 
> singular goal, the better! "Unique ways" being the key of course ;)

Yeah, I'm in for such stuff, too.


>> 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.
> 
>  Ah, with the #if statement right near the apex of that calculation? And 
> with an average pattern instead of a function? Any way, I'd like to see 
> it :)

What #if statement? The code won't need any #if :-) (the color map will 
serve as a kind of #switch statement).


Post a reply to this message

From: stbenge
Subject: Re: Ripple Tank Sim
Date: 12 Aug 2009 16:55:45
Message: <4a832c51$1@news.povray.org>
clipka wrote:
> stbenge schrieb:
>>  Ah, with the #if statement right near the apex of that calculation? 
>> And with an average pattern instead of a function? Any way, I'd like 
>> to see it :)
> 
> What #if statement? The code won't need any #if :-) (the color map will 
> serve as a kind of #switch statement).

Oh, I guess I was surmising based on your previous statements...


Post a reply to this message

From: scott
Subject: Re: Ripple Tank Sim
Date: 18 Aug 2009 05:22:45
Message: <4a8a72e5$1@news.povray.org>
>> 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.

What you are doing here is actually very similar to how you write such 
things for the GPU.  I wrote a wave simulator for the GPU a while back and 
it works almost identically, never thought of the GoL on a GPU, should be 
easy to implement.


Post a reply to this message

From: Verm
Subject: Re: Ripple Tank Sim
Date: 18 Aug 2009 12:07:28
Message: <4a8ad1c0$1@news.povray.org>
clipka wrote:
> ...., and was too lazy to integrate support for 
> proper image reading and writing ;-)

I'm sure you already know this but ascii PPM images are the way forward 
here - a nice easy human readable/writable HDRI image format.

Obviously I admire your abuse of PovRay.


Post a reply to this message

From: clipka
Subject: Re: Ripple Tank Sim
Date: 18 Aug 2009 12:49:39
Message: <4a8adba3$1@news.povray.org>
scott schrieb:
> never thought of the GoL on a GPU, should be easy to implement.

I bet. If it can be done in POV-Ray with textures only...

Here's the full POV-Ray SDL code for a GoL sim starting with a random 
pattern - the only non-linearity in control flow is the #if to care for 
first-frame initialization.

The world is toroidal, though this can be chaned by enabling the "once" 
keyword in the definition of PgNext.

As an interesting side note, the sim does /not/ store the end result of 
each generation, but interim results: The status of the cell itself, 
combined with a count of the surrounding live cells. This allows easy 
use of a color_map for the conditionals.

(The code could be made shorter by using macros, but I reckon this would 
be counter-productive for parsing speed.)

--------------------------------------

// +W100 +H100 +KFI1 +KFF9999 +FE

#version 3.6;

global_settings {
   assumed_gamma 1.0
   ambient_light 1.0
   max_trace_level 15
}

camera {
   orthographic
   location <0,0,100>
   look_at  <0,0,0>
   right   -1*x
   up       1*y
}



default {
   finish { ambient 1.0 diffuse 0.0 }
}

// ----------------------------------------

#local FrameDigits  = int(log(final_frame)) + 1;
#local NumLayers    = 9;
#local Delta        = 1/max(image_width,image_height);

#local NeighborFactor   = 0.05;
#local CellFactor       = 0.50;

#local EPSILON          = 1e-6;

#if (frame_number = 1)
   #local PgNext = pigment { bozo color_map { [ 0.499 rgb 0 ] [ 0.501 
rgb 1 ] } scale Delta }
#else
   #local PgNext = pigment {
     image_pattern { concat("Life", str(frame_number-1,-FrameDigits,0)) 
/*once*/ }
     color_map {
       // dead cell
       [ 0*CellFactor + 2.5*NeighborFactor -EPSILON  rgb 0 ]
       [ 0*CellFactor + 2.5*NeighborFactor +EPSILON  rgb 1 ]
       [ 0*CellFactor + 3.5*NeighborFactor -EPSILON  rgb 1 ]
       [ 0*CellFactor + 3.5*NeighborFactor +EPSILON  rgb 0 ]
       // live cell
       [ 1*CellFactor + 1.5*NeighborFactor -EPSILON  rgb 0 ]
       [ 1*CellFactor + 1.5*NeighborFactor +EPSILON  rgb 1 ]
       [ 1*CellFactor + 3.5*NeighborFactor -EPSILON  rgb 1 ]
       [ 1*CellFactor + 3.5*NeighborFactor +EPSILON  rgb 0 ]
     }
     translate -<0.5,0.5,0>
   }
#end

#local Tx1 = texture { pigment { PgNext translate <-1,-1, 0>*Delta } 
finish { ambient NumLayers * NeighborFactor } }
#local Tx2 = texture { pigment { PgNext translate <-1, 0, 0>*Delta } 
finish { ambient NumLayers * NeighborFactor } }
#local Tx3 = texture { pigment { PgNext translate <-1, 1, 0>*Delta } 
finish { ambient NumLayers * NeighborFactor } }
#local Tx4 = texture { pigment { PgNext translate < 0,-1, 0>*Delta } 
finish { ambient NumLayers * NeighborFactor } }
#local Tx5 = texture { pigment { PgNext translate < 0, 0, 0>*Delta } 
finish { ambient NumLayers * CellFactor } }
#local Tx6 = texture { pigment { PgNext translate < 0, 1, 0>*Delta } 
finish { ambient NumLayers * NeighborFactor } }
#local Tx7 = texture { pigment { PgNext translate < 1,-1, 0>*Delta } 
finish { ambient NumLayers * NeighborFactor } }
#local Tx8 = texture { pigment { PgNext translate < 1, 0, 0>*Delta } 
finish { ambient NumLayers * NeighborFactor } }
#local Tx9 = texture { pigment { PgNext translate < 1, 1, 0>*Delta } 
finish { ambient NumLayers * NeighborFactor } }

#local TxOutput = texture {
   average
   texture_map {
     [1 Tx1 ]
     [1 Tx2 ]
     [1 Tx3 ]
     [1 Tx4 ]
     [1 Tx5 ]
     [1 Tx6 ]
     [1 Tx7 ]
     [1 Tx8 ]
     [1 Tx9 ]
   }
}

box { <-1.5, -0.5, 0.0>, <1.5, 0.5, 0.0> texture { TxOutput } }

--------------------------------------


Post a reply to this message

<<< Previous 6 Messages Goto Initial 10 Messages

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