Wave Equation

Numerical simulation of the wave equation using Java

This applet shows a water effect. The effect is calculated in real time using a solution of the wave equations by means of finite differences. More about the wave equation can be found at the wikipedia.

Implementation details

Consider an area equally sampled in x and y directions. The water heights are stored in an two-dimensional array. All values are stored as integer values. In order to calculate the wave effect you need 2 arrays. One is representing the state of the wave field in the current time step, the other is representing the wave field in the previous timestep. The wave heights of the next time step can be calculated by applying the following formula to every cell of the array:

java plugin is missing
  NewHeights[x, y] =  ((  CurrentHeights[x-1, y+1]
                        + CurrentHeights[x  , y+1]
                        + CurrentHeights[x+1, y+1]
                        + CurrentHeights[x-1, y  ]
                        + CurrentHeights[x+1, y  ]
                        + CurrentHeights[x-1, y-1]
                        + CurrentHeights[x  , y-1]
                        + CurrentHeights[x+1, y-1] ) DIV 2 ) - 
                       PreviousHeights[x, y];

This means that the wave heights in the next time step depend only on the current water heights of the neigboring cells and the water height of the cell in question one timestep ago.

What these few lines do is a simplified solution of the wave equation, a partial differential equation. This algorithm does not provide an exact solution but it does provide a very fast solution.

After calculation the water heights one can apply a very simple form of raytracing. Not physically correct of course but again very fast and realistically looking. For every cell of the height array one can calculate the gradient. The gradient vector contains of the first derivation in x and y direction:

  dx = CurrentHeights[x, y] - CurrentHeights[x+1, y  ];
  dy = CurrentHeights[x, y] - CurrentHeights[x  , y+1];

Using this vector you can calculate the position of the pixel in an underlying image. (This image must be preload of course) The position results from the x,y position with the scaled gradient applied as a displacement:

  iOffX = x + (dx>>4);
  iOffY = y + (dy>>4);

So instead of displaying the height value directly you transform it into a displacement vector and apply it to an underlying image. If you finally increase the pixel color depending on the legth of the x or y component of the gradient vector you add a realistically looking light.

Download and Useage

Download icon  Download jar file
Download icon  Download source code (requires Netbeans)

In order to use the applet add the following lines to your html code:

  <object classid="java:waves.class" type="application/x-java-applet" width="400" height="400">
    <param name="archive" value="JWaves.jar"/>
    <param name="code" value="waves.class"/>
    <param name="pixsize" value="1"/>
    <param name="sleep" value="10"/>
    <param name="raindrops" value="true"/>
    <param name="preview" value="false"/>
    <param name="showfps" value="false"/>
    <param name="sourceheight" value="2000"/>

The following table lists the applet parameters and their meaning:

Parameter Meaning
pixsize The size of a pixel
sleep Time to wait after each frame (in milli seconds)
raindrops If this flag is set random raindrops are falling permanently
preview If this value is true the applet looks like an image only moving when the mouse is over the applet.
showfps If this flag is the frames per second are displayed in the upper left corner
sourceheight The height of the waterwaves beeing created

Related Links