Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Water Fluid Dynamics - Gurus plz Advise!

2 views
Skip to first unread message

Kris Collins

unread,
Dec 9, 1997, 3:00:00 AM12/9/97
to

Hey,
I want to do a little program which loads a pcx,
and from there you can control a 'boat' (represented
by a single pixel), which leaves a little wake behind,
distorting the picture below. I saw something in a demo
(by Iguana?) a couple years ago that was pretty close to
what I want. Havent taken fluid dynamics in school yet,
but I'm guessing that this program will not really need it.

I have some ideas, but nothing solid enough to get me started.
Any resources you could direct me to would be appreciated mucho! Or,
if you can explain it yourselves, thats even better.

Thanks in advance to any super cool guys (or gals) who can
assist me on my little project!

See ya!

Kris Collins
ITS, University of Colorado
coll...@ucsu.colorado.edu

David Thielen

unread,
Dec 10, 1997, 3:00:00 AM12/10/97
to

Make sure the wakes interfere with each other properly too. I saw one
like this and the wakes looked good until the hit each other - and
there was no interference - it looked all wrong then.

- David Thielen
Try Enemy Nations -- Red Alert meets Sim City
at www.windward.net

Thatcher Ulrich

unread,
Dec 10, 1997, 3:00:00 AM12/10/97
to

In article <collinkr-091...@ats8.colorado.edu>, Kris Collins
coll...@ucsu.colorado.edu says...

> Hey,
> I want to do a little program which loads a pcx,
> and from there you can control a 'boat' (represented
> by a single pixel), which leaves a little wake behind,
> distorting the picture below. I saw something in a demo
> (by Iguana?) a couple years ago that was pretty close to
> what I want. Havent taken fluid dynamics in school yet,
> but I'm guessing that this program will not really need it.
>
> I have some ideas, but nothing solid enough to get me started.
> Any resources you could direct me to would be appreciated mucho! Or,
> if you can explain it yourselves, thats even better.

I think you can do this with Cellular Automata. In other words, make
a matrix, with values at each point in the matrix that represent the
height of the water, and the vertical speed of the water at that
point. Then, define an update rule that generates the state of a
point at time the next timestep, based on the state of the point and
its neighbors at the current time step.

For water waves, you would define things something like:

* the height value defaults to 0, which represents "sea-level".

* the height of the water at a point (x,y) changes based on maybe:

struct WaterState {
float Height;
float Velocity;
};


void Update(WaterState Current[SIZE][SIZE], New[SIZE][SIZE])
{
// Adjust to taste.
float Coefficients[3][3] = {
{ -0.05, -0.10, -0.05 },
{ -0.10, -0.20, -0.10 },
{ -0.05, -0.10, -0.05 }
};

for (int y = 1; y < SIZE-1; y++) {
for (int x = 1; x < SIZE-1; x++) {

float VelocityChange = 0;

for (int j = 0; j < 3; j++) {
for (int i = 0; i < 3; i++) {
VelocityChange +=
Current[y+j-1][x+i-1] *
Coefficient[i][j];
}
}

VelocityChange -= New[y][x].Velocity *
DAMPING_FACTOR;
New[y][x].Velocity += VelocityChange;
New[y][x].Height = Current[y][x].Height +
New[y][x].Velocity;
}
}
}

I got a little carried away with detail. Anyway, that code probably
doesn't work they way you want as written, but the skeleton is there.
At each time step, use the height of the water, or some other function
of the water height to modulate the color of the corresponding pixel
in the bitmap.

--
Thatcher Ulrich
http://world.std.com/~ulrich

Glenn Corpes

unread,
Dec 10, 1997, 3:00:00 AM12/10/97
to

coll...@ucsu.colorado.edu (Kris Collins) wrote:

> Hey,
> I want to do a little program which loads a pcx,
> and from there you can control a 'boat' (represented
> by a single pixel), which leaves a little wake behind,
> distorting the picture below. I saw something in a demo
> (by Iguana?) a couple years ago that was pretty close to
> what I want. Havent taken fluid dynamics in school yet,
> but I'm guessing that this program will not really need it.
>
> I have some ideas, but nothing solid enough to get me started.
> Any resources you could direct me to would be appreciated mucho! Or,
> if you can explain it yourselves, thats even better.
>

> Thanks in advance to any super cool guys (or gals) who can
> assist me on my little project!

I think you need to look into SHM (simple harmonic motion), i've seen
this done a couple of times, all you need to do is store a 'height' for
each pixel and 'lower' the pixels the boat travels over, you then
process every pixel on screen (or point in your map) and adjust it
slightly towards the values of it's neighbours with something like this:

A B C
H X D
G F E

NewX = ((X*9)+((B+D+F+H)*3)+((A+C+E+G)*2))/(9+4*3+4*2);

I have no idea if the constants 9, 3 and 2 are appropriate, they will
need to be played with to give convincing movement, you also probably
want to contrive these so that the divide (by 29 in this case) could be
replaced by a shift. You could also try different shapes other than a
weighted 3*3 grid, you may be able to get away with using only four
samples or may need to go to 5*5, remember this will have a huge effect
on the speed though.

-=< gco...@ea.com, Project Leader Bullfrog >=-

Acuity

unread,
Dec 10, 1997, 3:00:00 AM12/10/97
to

coll...@ucsu.colorado.edu (Kris Collins) wrote:
>Hey,
>I want to do a little program which loads a pcx,
>and from there you can control a 'boat' (represented
>by a single pixel), which leaves a little wake behind,
>distorting the picture below. I saw something in a demo
>(by Iguana?) a couple years ago that was pretty close to
>what I want. Havent taken fluid dynamics in school yet,
>but I'm guessing that this program will not really need it.
>
>I have some ideas, but nothing solid enough to get me started.
>Any resources you could direct me to would be appreciated mucho! Or,
>if you can explain it yourselves, thats even better.
>
>Thanks in advance to any super cool guys (or gals) who can
>assist me on my little project!

Okay, here's what you do:

Create a heightmap for your landscape. This is a greyscale bitmap,
where the lighter the color is, the higher that point in the landscape
is.

Create a colormap for your landscape. Or link specific heights to
specific colors.

Now all you have to do is modify the heightmap, (and possibly the
colormap) when you want your boat to make waves and ripples.

Now what you might do is whenever your boat tocuhes a new pixel, lower
that pixel down to the approriate height. When the pixel is
"released" after the boat passes, then modify it's height and velocity
each frame thereafter using a sine wave to make it bob up and down.

How you might do all this is this way:
(Note that because I don't want to be writing this ALL night, that
this will ONLY move water pixels that have actually been touched by
your moving object. It should be fairly easy to write a routine that
transfers some of the velocity of a pixel to neighboring pixels. This
average VELOCITY would probabally affect WATER_TENSION as the
mutliplier.)

(Another note: I'm not sure this will look 100% correct. I may very
well be inventing some new effect here that doesn't look anyhting like
water.)

(The more I think aobut it, I probabally am. I don't think water
behaves in this way)

Allocate a HEIGHT map of ints.
Allocate a COLOR map of bytes.
Allocate a VELOCITY map of FLOATS.
Allocate a DIRECTION map of bytes.

Find the height of the water-line of your body of water.
Set your "WATER TENSION".

To animate, set any water pixel's height to how far down the boat
presses it, and then se it's DIRECTION to -1 the moment the boat
releases it's grip on it. In your main loop, do the following,
scanning ALL water pixels:

If a water pixel's DIRECTION != 2
// If the water pixel has been touched recently...
{
// Decease the velocity of this pixel each iteration so the
// water gradually stops moving. May want to use some other
// number than water_tension, if it slows down too fast or too

// slowly.
VELOCITY = VELOCITY * WATER TENSION;


If VELOCITY = 0
{
If HEIGHT != WATER_LINE
DIRECTION = -DIRECTION;
// If the pixel isn't moving, and it's been touched
// recently, and it's not at a neutral position, then

// it must be at the top or bottom of
// a wave. Therefore, it has reached the limits of
// it's motion, and should start moving towards
// a neutral position again.
ELSE
DIRECTION = 2;
// Otherwise, if it's not moving, and it's in

// a neutral positon, then stop it from
// being tested constantly.

}

If DIRECTION = 1
// If water pixel is moving in an upwardly direction...
{
if HEIGHT < WATER_LINE
// And it's height is less than neutral
VELOCITY = VELOCITY / WATER_TENSION;
// Divide by water tension, which should be
// very close to, but less than 1.
else
if HEIGHT > WATER_LINE
VELOCITY = VELOCITY * WATER TENSION;

}
ELSE
IF DIRECTION = -1
{
if HEIGHT < WATER_LINE
VELOCITY = VELOCITY * WATER_TENSION;

else
if HEIGHT > WATER_LINE
VELOCITY = VELOCITY / WATER TENSION;

}


}


What the above does is:
A) Check to see if a pixel should be in motion at all.

B) Bob it up and down in a sine wave like way, and deceasing it's
speed each iteration.

C) Set a value when it ceases motion so that you save calculations.

What it does not do is:
D) Modify the speed of a pixel based on those around it

E) Allow solitary waves that move across the surface of the water.

That last one seems a little complicated to implement, but if tyou
water model is to behave completely realstically, then it's important.
What that implies is that a pixel would move up and down perhaps once
at most, and slow down extremely quickly, passing most or all of it's
energy onto neighboring pixels. Perhaps cancelling waves would
simulate this. Ie: If you have a pixel moving in a sine pattern, and
it sets it's neighbors in motion in a similar pattern, but out of
phase with it, and the neighbors try to set IT in motion and THEIR
neightbors, then only the neighbors that are not in motion will ever
be in motion, and neighbors that try to set other neighbors in motion
that are already in motion will cancel the moving neighbors out.
However, it can't be that simple, because a "neighbor" would have to
be about 100 pixels away or something... a whole wavelength.

But that's what I get for forgetting the wave motion part of my
physics class.

Thatcher Ulrich

unread,
Dec 11, 1997, 3:00:00 AM12/11/97
to

In article <memo.19971210...@frog.compulink.co.uk>, Glenn
Corpes gle...@cix.co.uk.notthisbityoumoron says...

> coll...@ucsu.colorado.edu (Kris Collins) wrote:
>
> > Hey,
> > I want to do a little program which loads a pcx,
> > and from there you can control a 'boat' (represented
> > by a single pixel), which leaves a little wake behind,
> > distorting the picture below. I saw something in a demo
> > (by Iguana?) a couple years ago that was pretty close to
> > what I want. Havent taken fluid dynamics in school yet,
> > but I'm guessing that this program will not really need it.
> >
> > I have some ideas, but nothing solid enough to get me started.
> > Any resources you could direct me to would be appreciated mucho! Or,
> > if you can explain it yourselves, thats even better.
> >
> > Thanks in advance to any super cool guys (or gals) who can
> > assist me on my little project!
>
> I think you need to look into SHM (simple harmonic motion), i've seen
> this done a couple of times, all you need to do is store a 'height' for
> each pixel and 'lower' the pixels the boat travels over, you then
> process every pixel on screen (or point in your map) and adjust it
> slightly towards the values of it's neighbours with something like this:
>
> A B C
> H X D
> G F E
>
> NewX = ((X*9)+((B+D+F+H)*3)+((A+C+E+G)*2))/(9+4*3+4*2);
>
> I have no idea if the constants 9, 3 and 2 are appropriate, they will
> need to be played with to give convincing movement, you also probably
> want to contrive these so that the divide (by 29 in this case) could be
> replaced by a shift. You could also try different shapes other than a
> weighted 3*3 grid, you may be able to get away with using only four
> samples or may need to go to 5*5, remember this will have a huge effect
> on the speed though.
>
> -=< gco...@ea.com, Project Leader Bullfrog >=-
>

I think a velocity variable is necessary to make it oscillate;
otherwise it just kind of smears or "melts". I could be wrong,
though.

Tom Valesky

unread,
Dec 11, 1997, 3:00:00 AM12/11/97
to

: On Tue, 09 Dec 1997 17:56:46 -0700, coll...@ucsu.colorado.edu (Kris
: Collins) wrote:

: >Hey,
: >I want to do a little program which loads a pcx,
: >and from there you can control a 'boat' (represented
: >by a single pixel), which leaves a little wake behind,
: >distorting the picture below. I saw something in a demo
: >(by Iguana?) a couple years ago that was pretty close to
: >what I want. Havent taken fluid dynamics in school yet,
: >but I'm guessing that this program will not really need it.
: >
: >I have some ideas, but nothing solid enough to get me started.
: >Any resources you could direct me to would be appreciated mucho! Or,
: >if you can explain it yourselves, thats even better.
: >
: >Thanks in advance to any super cool guys (or gals) who can
: >assist me on my little project!

You might want to check out the following paper:
[KASS90] Kass, Michael, and Miller, Gavin "Rapid, Stable Fluid Dynamics
for Computer Graphics"
Computer Graphics (Proc. Siggraph) Vol. 24, No. 4, August 1990, pp. 49-55

If I recall correctly, the paper presents an optimization for fluid
simulations that allows you to get away with only calculating the surface
effects, rather than the entire volume. This is a large win.

I've seen the demo of which you speak, but I haven't been able to find it
on the Web.


--
===========================================================================
Tom Valesky -- tval...@patriot.net
http://www.patriot.net/users/tvalesky

Glenn Corpes

unread,
Dec 11, 1997, 3:00:00 AM12/11/97
to

t.ul...@tectrix.com (Thatcher Ulrich) wrote:

> In article <memo.19971210...@frog.compulink.co.uk>, Glenn
> Corpes gle...@cix.co.uk.notthisbityoumoron says...

> > coll...@ucsu.colorado.edu (Kris Collins) wrote:
> >
> > > Hey,
> > > I want to do a little program which loads a pcx,
> > > and from there you can control a 'boat' (represented
> > > by a single pixel), which leaves a little wake behind,
> > > distorting the picture below. I saw something in a demo
> > > (by Iguana?) a couple years ago that was pretty close to
> > > what I want. Havent taken fluid dynamics in school yet,
> > > but I'm guessing that this program will not really need it.
> > >
> > > I have some ideas, but nothing solid enough to get me started.
> > > Any resources you could direct me to would be appreciated mucho!
> Or,
> > > if you can explain it yourselves, thats even better.
> > >
> > > Thanks in advance to any super cool guys (or gals) who can
> > > assist me on my little project!
> >

I think you're right, the point's velocity would need to be adjusted
according to the height difference of it's neighbours and the velocity
added to the height of the point. something like:

vel += A+B+C+D+E+F+G+H-(8*X);
X += vel;

with a lot of experimenting with weightings for each neighbour, it would
also be vital to use fixed point (or maybe floats) rather than basic
ints.

Steve

unread,
Dec 12, 1997, 3:00:00 AM12/12/97
to

>> > coll...@ucsu.colorado.edu (Kris Collins) wrote:
>> >
>> > > Hey,
>> > > I want to do a little program which loads a pcx,
>> > > and from there you can control a 'boat' (represented
>> > > by a single pixel), which leaves a little wake behind,
>> > > distorting the picture below. I saw something in a demo
>> > > (by Iguana?) a couple years ago that was pretty close to
>> > > what I want. Havent taken fluid dynamics in school yet,
>> > > but I'm guessing that this program will not really need it.
>> > >
>> > > I have some ideas, but nothing solid enough to get me started.
>> > > Any resources you could direct me to would be appreciated mucho!
>> Or,
>> > > if you can explain it yourselves, thats even better.
>> > >
>> > > Thanks in advance to any super cool guys (or gals) who can
>> > > assist me on my little project!

Remedy Entertainment has a Java applet that does what I think you're
looking for (http://www.remedy.fi, go to the cool stuff section). Also,
check out http://www.users.globalnet.co.uk/~tomh, lots of good graphics
programming info including water effects, which might be what you want.
--
--- <A HREF="http://weber.u.washington.edu/~link"> Optik Nirvana </A> ---
As soon as you mention something; if it is good, it goes away.
if it is bad, it happens.
--- NewSIG 2.01 145/266 ---

jede...@interlog.com

unread,
Dec 14, 1997, 3:00:00 AM12/14/97
to

Acuity <Acu...@nowhere.net> wrote:
> coll...@ucsu.colorado.edu (Kris Collins) wrote:
> >Hey,
> >I want to do a little program which loads a pcx,
> >and from there you can control a 'boat' (represented
> >by a single pixel), which leaves a little wake behind,
> >distorting the picture below. I saw something in a demo
> >(by Iguana?) a couple years ago that was pretty close to
> >what I want. Havent taken fluid dynamics in school yet,
> >but I'm guessing that this program will not really need it.
> >
> >I have some ideas, but nothing solid enough to get me started.
> >Any resources you could direct me to would be appreciated mucho! Or,
> >if you can explain it yourselves, thats even better.
> >
> >Thanks in advance to any super cool guys (or gals) who can
> >assist me on my little project!

I have read all the answers to this and the one in the Iguana demo was
much simpler than all of them. The formula looks something like this:

u(t+1,x,y) = (u(t,x+1,y)+u(t,x-1,y)+u(t,x,y+1)+u(t,x,y-1))/2 - u(t-1,x,y)

where,
u is a value in your height table at time index t and position x,y

In plain english all you do is add up the four bounding points in the
_previous_ height table (up, down, right, left), divide by two, subtract
the point in the _current_ height table and put the result in the same
point in the _next_ height table.

You can get all the info and source of the original effect in a file
called hq_water.zip which you can find in many places. Try looking around

http://www.hornet.org

PS I havn't quite been able to get this effect to work yet.

--
|o|------------------------------------------------------------------------|o|
|o| Jedediah Smith - jede...@interlog.com |o|
|o| |o|
|o| Obelus Unlimited - Toronto, Canada - obe...@interlog.com |o|
|o| Hardware Tech./Programmer |o|
|o| "Custom computers, on-site installation, custom software solutions" |o|
|o|------------------------------------------------------------------------|o|

jede...@interlog.com

unread,
Dec 14, 1997, 3:00:00 AM12/14/97
to

jede...@interlog.com wrote:

> u(t+1,x,y) = (u(t,x+1,y)+u(t,x-1,y)+u(t,x,y+1)+u(t,x,y-1))/2 - u(t-1,x,y)

> where,
> u is a value in your height table at time index t and position x,y

> In plain english all you do is add up the four bounding points in the
> _previous_ height table (up, down, right, left), divide by two, subtract
> the point in the _current_ height table and put the result in the same
> point in the _next_ height table.

Oops, the _previous_ and _current_ in that sentence should be switched.

0 new messages