Oliver's simple fluid dynamics simulator

by PhilQ

HTML

<table style="width: 100%;">
	<tr>
		<td style="text-align: center"><h1>Oliver's simple fluid dynamics simulator</h1>
		</td>
	</tr>
</table>
<table style="width: 100%;">
	<tr>
		<td>
			<canvas id=canvas style="width: 512px; height: 512px;" width=512 height=512></canvas>
		</td>
		<td>
			Simple fluid dynamics simulator based on the navier-stokes equations, implemented in JavaScript.
			<ul>
				<li>Click and drag to add density and velocity</li>
				<li>Add density source with alt-click or anything other than the left-button</li>
			</ul>
			<div id = log></div>
			<button onclick="startAnimation()">start</button>
			<button onclick="stopAnimation()">stop</button>
			<button onclick="field.reset(); frames = 0; sources = [];">reset</button><br />
			<button onclick="field.setDisplayFunction(toggleDisplayFunction(canvas))">Toggle drawing mode</button><br />
			Solver Iterations:
			<input id=iterations type="range" onchange="field.setIterations(event.target.value)" min=1 max=75><br />
			Resolution:
			<select id=resolution onchange="updateRes()">
				<option>64</option>
				<option>8</option>
				<option>16</option>
				<option>24</option>
				<option>32</option>
				<option>48</option>
				<option>96</option>
				<option>128</option>
				<option>256</option>
				<option>512</option>
			</select>
		</td>
	</tr>
</table>

CSS

body {
	background: #333333;
	color: white;
	font-family: Helvetica;
}

JavaScript

// Based on http://www.dgp.toronto.edu/people/stam/reality/Research/pdf/GDC03.pdf
/**
 * Copyright (c) 2009 Oliver Hunt <http://nerget.com>
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

function FluidField(canvas) {
	function addFields(x, s, dt)
	{
		for (var i=0; i<size ; i++ ) x[i] += dt*s[i];
	}

	function set_bnd(b, x)
	{
		return;
		if (b===1) {
			for (var i = 1; i <= width; i++) {
				x[i] =  x[i + rowSize];
				x[i + (height+1) *rowSize] = x[i + height * rowSize];
			}

			for (var j = 1; i <= height; i++) {
				x[j * rowSize] = -x[1 + j * rowSize];
				x[(width + 1) + j * rowSize] = -x[width + j * rowSize];
			}
		} else if (b === 2) {
			for (var i = 1; i <= width; i++) {
				x[i] = -x[i + rowSize];
				x[i + (height + 1) * rowSize] = -x[i + height * rowSize];
			}

			for (var j = 1; j <= height; j++) {
				x[j * rowSize] =  x[1 + j * rowSize];
				x[(width + 1) + j * rowSize] =  x[width + j * rowSize];
			}
		} else {
			for...