Using simple physics, we can easily create an interactive liquid surface.
The most natural representation of a liquid such as water is a particle system.
While a simulation on molecular level is still impossible,and even more with Flash, for obvious reasons, the approach can be made practical on a lower level, by increasing the particle size.
Each particle carries state information about a small subset of the water body, and is subject to external forces acting on it.
The particle state, such as velocity and position, will be resolve by our wave model.
So lets represent our liquid surface as a collection of nodes.
There is a default distance between each two nodes, so we can asume and calculate the force acting on a particle based on the diference of distance between it and its two close neighbours.
We know by the ( Hooke's Law ) that the force is related to the strength of the surface and the diference of distance, so we can write:
force = strength × extension
Then using the basic equation
Force = mass × aceleration
and assuming nodes with unit mass, we have a direct realtion btween aceleration and force,
aceleration = force
Knowing the aceleration of a node, we know the velocity per unit of time, and with the velocity we can calculate the variation in the position of each node.
velocity = velocity + aceleration × time
espace = espace + velocity × time
And that's almost all...
now , we know position and velocity for all our nodes, so we only need to connect this nodes and draw our surface.
For this, we can use the node's x and y positions as curveTo's control points and use the point in between two particles as the anchor point.
This will create a smooth curve btween our nodes like this.
Finally, taking care of the borders, and drawing the area under the curve, this is the result.
All this ecuations, translate to actionscript for a node -n looks like:
dx = this.x[n + 1] + this.x[n - 1] - 2 * this.x[n]; dy = this.y[n + 1] + this.y[n - 1] - 2 * this.y[n]; // propagation factor (kp) dy *= this.kp; dx *= this.kp; // atenuation factor (ka) this.vx[n] = (this.vx[n] + dx) * this.ka; this.vy[n] = (this.vy[n] + dy) * this.ka; // Node position and aceleration this.x[n] = this.x[n] + this.vx[n]; this.y[n] = this.y[n] + this.vy[n]; // Force the node to return to the original position this.vx[n] = this.vx[n] + (this.xo[n] - this.x[n]) / 100; this.vy[n] = this.vy[n] + (this.yo[n] - this.y[n]) / 100;
Download the ActionScript 2.0 class