The n-body problem involves predicting the motion of celestial objects under mutual gravitation. With many objects, this simulation can be computationally taxing due to n2 force calculations. Here we simulate two hundred massive objects, using the Barnes–Hut algorithm to approximate forces in O(n log n). Using dynamic properties, we can easily encode speed using color, and velocity with a white arrow. Watch as worlds collide, undergo planetary accretion, and spin out of control!
Next: PolarClock
<html>
<head>
<title>N-Body Problem</title>
<script type="text/javascript" src="../protovis-r3.2.js"></script>
<style type="text/css">
body {
margin: 0;
background: #222;
}
</style>
</head>
<body>
<script type="text/javascript+protovis">
var w = document.body.clientWidth,
h = document.body.clientHeight,
nodes = pv.range(200).map(function(i) {
return {x: w * Math.random(),
y: h * Math.random(),
r: 2 + Math.random() * 8};
});
var sim = pv.simulation(nodes)
.force(pv.Force.charge(3))
.constraint(pv.Constraint.collision(function(d) d.r))
.stabilize();
var vis = new pv.Panel()
.width(w)
.height(h);
vis.add(pv.Dot)
.data(nodes)
.left(function(d) d.x)
.top(function(d) d.y)
.radius(function(d) d.r)
.strokeStyle(pv.ramp("steelblue", "brown").by(function(d) d.vx * d.vx + d.vy * d.vy));
vis.add(pv.Panel)
.data(nodes)
.add(pv.Line)
.data(pv.range(2))
.strokeStyle("white")
.left(function(i, d) d.x + i * 10 * d.vx)
.top(function(i, d) d.y + i * 10 * d.vy);
setInterval(function() {
sim.step();
vis.render();
}, 42);
</script>
</body>
</html>