Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
369 lines (337 sloc) 11.6 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Chart of frames/second with d3.js</title>
<script type="text/javascript"
src="http://code.jquery.com/jquery-1.6.4.min.js">
</script>
<script type="text/javascript"
src="http://mbostock.github.com/d3/d3.js">
</script>
<script type="text/javascript"
src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.0.6/modernizr.min.js">
</script>
</script>
<script type="text/javascript"
src="http://threebean.org/js-experiments/fps/fps.js">
</script>
<script type="text/javascript">
$(document).ready(function (){
var cell_size = 16;
var isolevel = 0.0008;
var edge_table = [
0x0, //0000,
0x9, //1001,
0x3, //0011
0xa, //1010
0x6, //0110,
0xf, //1111,
0x5, //0101
0xc, //1100
0xc, //1100
0x5, //0101
0xf, //1111,
0x6, //0110,
0xa, //1010
0x3, //0011
0x9, //1001,
0x0, //0000
];
var segment_table = [
[-1,-1,-1,-1,-1],
[0,3,-1,-1,-1],
[1,0,-1,-1,-1],
[1,3,-1,-1,-1],
[2,1,-1,-1,-1],
[2,1,0,3,-1],
[2,0,-1,-1,-1],
[2,3,-1,-1,-1],
[3,2,-1,-1,-1],
[0,2,-1,-1,-1],
[1,0,3,2,-1],
[1,2,-1,-1,-1],
[3,1,-1,-1,-1],
[0,1,-1,-1,-1],
[3,0,-1,-1,-1],
[-1,-1,-1,-1,-1]
];
var epsilon = 0.00000001;
function vertex_interp(isolevel, p1, p2, valp1, valp2) {
if ( Math.abs(isolevel - valp1) < epsilon ) { return p1; }
if ( Math.abs(isolevel - valp2) < epsilon ) { return p2; }
if ( Math.abs(valp1 - valp2) < epsilon ) { return p2; }
var mu = (isolevel - valp1) / (valp2 - valp1);
var p = {
x: p1.x + mu * (p2.x - p1.x),
y: p1.y + mu * (p2.y - p1.y),
};
return p;
}
function get_grid_cell(x, y) {
// We should do some caching here.
var cell = {
x: x,
y: y,
v: [
{x: x, y: y},
{x: x+cell_size, y: y},
{x: x+cell_size, y: y+cell_size},
{x: x, y: y+cell_size},
],
val: [
threshold(x, y),
threshold(x+cell_size, y),
threshold(x+cell_size, y+cell_size),
threshold(x, y+cell_size),
]
}
if (
cell.val[0] < isolevel ||
cell.val[1] < isolevel ||
cell.val[2] < isolevel ||
cell.val[3] < isolevel
) { return cell; }
return false;
}
function polygonize(cell, isolevel) {
var index = 0;
if ( cell.val[0] < isolevel ) { index |= 1; }
if ( cell.val[1] < isolevel ) { index |= 2; }
if ( cell.val[2] < isolevel ) { index |= 4; }
if ( cell.val[3] < isolevel ) { index |= 8; }
if ( edge_table[index] == 0 ) {
return []; // no segments here!
}
var vertlist = [
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
{x:0, y:0},
];
if ( edge_table[index] & 1 ) {
vertlist[0] = vertex_interp(isolevel,
cell.v[0], cell.v[1], cell.val[0], cell.val[1]
);
}
if ( edge_table[index] & 2 ) {
vertlist[1] = vertex_interp(isolevel,
cell.v[1], cell.v[2], cell.val[1], cell.val[2]
);
}
if ( edge_table[index] & 4 ) {
vertlist[2] = vertex_interp(isolevel,
cell.v[2], cell.v[3], cell.val[2], cell.val[3]
);
}
if ( edge_table[index] & 8 ) {
vertlist[3] = vertex_interp(isolevel,
cell.v[3], cell.v[0], cell.val[3], cell.val[0]
);
}
var segments = [];
for ( var i = 0; segment_table[index][i] != -1; i += 2 ) {
segments.push({
a: vertlist[segment_table[index][i ]],
b: vertlist[segment_table[index][i+1]],
});
}
return segments;
}
var grid = {
width: 800,
height: 600,
};
var balls = [];
var num_balls = 20;
for ( var i = 0; i < num_balls; i++ ) {
balls.push({
x: Math.random() * grid.width,
y: Math.random() * grid.height,
vx: 0,
vy: 0,
});
}
var canvas = document.getElementById('myCanvas');
canvas.width = grid.width;
canvas.height = grid.height;
var c = canvas.getContext('2d');
var mousePos = null;
var mouse_weight = 10;
if ( Modernizr.touch ) {
console.log("touch");
} else {
$('canvas').bind('mousedown', function(ev) {
mousePos = { x: ev.clientX, y: ev.clientY, };
});
$('canvas').bind('mousemove', function(ev) {
if ( mousePos ) {
mousePos = { x: ev.clientX, y: ev.clientY, };
}
});
$('canvas').bind('mouseup', function(ev) {
mousePos = null;
});
}
function threshold(x, y) {
var f = 0;
for ( var i = 0; i < balls.length; i++ ) {
d = Math.sqrt(
Math.pow(balls[i].x - x, 2) +
Math.pow(balls[i].y - y, 2)
);
g_force = 1 / Math.pow(d, 2);
f += g_force;
}
return f;
}
function draw_marching_squares() {
c.beginPath();
for ( var i = 0; i < grid.width / cell_size; i += 1 ) {
for ( var j = 0; j < grid.height / cell_size; j += 1 ) {
cell = get_grid_cell(i*cell_size, j*cell_size, isolevel);
if ( cell ) {
segments = polygonize(cell, isolevel);
for ( var k = 0; k < segments.length; k++ ) {
c.moveTo(segments[k].a.x, segments[k].a.y);
c.lineTo(segments[k].b.x, segments[k].b.y);
}
}
}
}
c.closePath();
c.stroke();
}
function draw_marching_squares_old() {
var cell_map = [];
for ( var i = 0; i < grid.width / cell_size; i += 1 ) {
cell_map[i] = [];
for ( var j = 0; j < grid.height / cell_size; j += 1 ) {
cell_map[i][j] = threshold(i*cell_size, j*cell_size);
if ( cell_map[i][j] > 0.00025 ) {
c.beginPath();
c.arc(i*cell_size, j*cell_size, cell_size/3, 0 , Math.PI*2, true);
c.closePath();
c.fill();
}
}
}
}
var lastDate = new Date();
var dt = 100;
function draw() {
// Performance scaling
var date = new Date();
dt = date - lastDate;
lastDate = date;
var fps = 1 / (dt / 1000.0);
var target_fps = 19.0;
if ( fps > 100 ) {
fps = target_fps;
}
var target_cellsize = 8;
d_cell_size = 1 - (fps/target_fps);
cell_size += 0.25 * d_cell_size;
// Done with performance scaling
c.fillStyle = '#FFFFFF';
c.fillRect(0, 0, canvas.width, canvas.height);
c.fillStyle = '#000000';
for ( var i = 0; i < balls.length; i++ ) {
c.beginPath();
c.arc(balls[i].x, balls[i].y, 2, 0, Math.PI*2, true);
c.closePath();
c.fill();
}
draw_marching_squares();
requestAnimFrame(draw);
}
function animate() {
var scale = 9.8 * (dt / 33.0);
for ( var i = 0; i < balls.length; i++ ) {
var dx = 0;
var dy = 0;
// Update each ball based on every other ball
for ( var j = 0; j < balls.length; j++ ) {
if ( i == j ) { continue; }
d = Math.sqrt(
Math.pow(balls[i].x - balls[j].x, 2) +
Math.pow(balls[i].y - balls[j].y, 2)
);
if ( d == 0 ) {
// OMG, what do we do?
dx += (Math.random() * 2) - 1;
dy += (Math.random() * 2) - 1;
continue;
}
g_force = 1 / Math.pow(d, 2);
dx -= g_force * ((balls[i].x - balls[j].x)/d)
dy -= g_force * ((balls[i].y - balls[j].y)/d)
}
if ( mousePos != null ) {
d = Math.sqrt(
Math.pow(balls[i].x - mousePos.x, 2) +
Math.pow(balls[i].y - mousePos.y, 2)
);
if ( d == 0 ) {
// OMG, what do we do?
dx += (Math.random() * 2) - 1;
dy += (Math.random() * 2) - 1;
continue;
}
g_force = mouse_weight * (
1 / Math.pow(d, 1) -
cell_size*10 / Math.pow(d, 2)
);
dx -= g_force * ((balls[i].x - mousePos.x)/d)
dy -= g_force * ((balls[i].y - mousePos.y)/d)
}
balls[i].vx += (dx * scale);
balls[i].vy += (dy * scale);
}
var LIMIT = 50;
for ( var i = 0; i < balls.length; i++ ) {
if ( balls[i].vx > LIMIT ) { balls[i].vx = LIMIT / 100.0; }
if ( balls[i].vy > LIMIT ) { balls[i].vy = LIMIT / 100.0; }
balls[i].vx = 99 * balls[i].vx / 100.0;
balls[i].vy = 99 * balls[i].vy / 100.0;
}
for ( var i = 0; i < balls.length; i++ ) {
balls[i].x += balls[i].vx;
balls[i].y += balls[i].vy;
if ( balls[i].x < 0 ) {
balls[i].x = 1;
balls[i].vx = -1 * balls[i].vx * 0.75;
}
if ( balls[i].y < 0 ) {
balls[i].y = 1;
balls[i].vy = -1 * balls[i].vy * 0.75;
}
if ( balls[i].x > grid.width ) {
balls[i].x = grid.width - 1;
balls[i].vx = -1 * balls[i].vx * 0.75;
}
if ( balls[i].y > grid.height ) {
balls[i].y = grid.height - 1;
balls[i].vy = -1 * balls[i].vy * 0.75;
}
}
requestAnimFrame(animate);
}
animate();
draw();
});
</script>
</head>
<body>
<a href="http://github.com/ralphbean/js-experiments"><img style="z-index: 100; position: absolute; top: 0; right: 0; border: 0;" src="https://d3nwyuy0nl342s.cloudfront.net/img/7afbc8b248c68eb468279e8c17986ad46549fb71/687474703a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6461726b626c75655f3132313632312e706e67" alt="Fork me on GitHub"></a>
<a href="http://www.w3.org/html/logo/">
<img
style="position:absolute; bottom: 15px; right: 0; border: 0; width: 197px; height: 64px;"
src="http://www.w3.org/html/logo/badge/html5-badge-h-connectivity-css3-graphics.png"
alt="HTML5 Powered with Connectivity / Realtime, CSS3 / Styling, and Graphics, 3D &amp; Effects"
title="HTML5 Powered with Connectivity / Realtime, CSS3 / Styling, and Graphics, 3D &amp; Effects">
</a>
</div>
<canvas id='myCanvas'></canvas>
</body>
</html>