Skip to content

Instantly share code, notes, and snippets.

@bellbind
Last active August 29, 2015 14:04
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save bellbind/2b3fd84a8b9766013598 to your computer and use it in GitHub Desktop.
[d3js][javascript]Simulation of SYNC (Peskin model)
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
window.addEventListener("load", function () {
"use strict";
var canvas = document.createElement("canvas");
document.body.appendChild(canvas);
canvas.width = canvas.height = 600;
var c2d = canvas.getContext("2d");
var newNodes = function () {
var nodes = [];
for (var x = 0; x < 10; x++) {
for (var y = 0; y < 10; y++) {
nodes.push({voltage: Math.random() * 255});
}
}
return nodes;
};
var draw = function (nodes) {
c2d.clearRect(0, 0, 600, 600);
for (var x = 0; x < 10; x++) {
for (var y = 0; y < 10; y++) {
var node = nodes[x * 10 + y];
c2d.save();
c2d.translate(30 + x * 60, 30 + y * 60);
c2d.beginPath();
c2d.arc(0, 0, node.voltage / 10, 0, Math.PI * 2, false);
c2d.closePath();
c2d.fill();
c2d.restore();
}
}
};
var syncNext = function (nodes) {
var charge = function (node) {
var v = node.voltage / 255;
return Math.log(Math.pow(Math.E, v) + (Math.E - 1) / 20) * 255;
};
var nexts = [];
for (var x = 0; x < 10; x++) {
for (var y = 0; y < 10; y++) {
var node = nodes[x * 10 + y];
nexts.push({voltage: charge(node)});
}
}
/*
// propagate siblings only: late to sync all
for (var x = 0; x < 10; x++) {
for (var y = 0; y < 10; y++) {
var next = nexts[x * 10 + y];
if (next.voltage < 255) continue;
var l = nexts[(x === 0 ? 9 : x - 1) * 10 + y];
var r = nexts[(x === 9 ? 0 : x + 1) * 10 + y];
var u = nexts[x * 10 + (y === 0 ? 9 : y - 1)];
var d = nexts[x * 10 + (y === 9 ? 0 : y + 1)];
l.voltage += next.voltage / 8;
r.voltage += next.voltage / 8;
u.voltage += next.voltage / 8;
d.voltage += next.voltage / 8;
}
}
*/
// propagate all others: quickly sync all
for (var x = 0; x < 10; x++) {
for (var y = 0; y < 10; y++) {
var next = nexts[x * 10 + y];
if (next.voltage < 255) continue;
nexts.forEach(function (n, i) {
if (i !== x * 10 + y) n.voltage += next.voltage / 100;
});
}
}
// fire
for (var x = 0; x < 10; x++) {
for (var y = 0; y < 10; y++) {
var next = nexts[x * 10 + y];
if (next.voltage > 255) next.voltage = 0;
}
}
return nexts;
};
var current = newNodes();
draw(current);
var id = setInterval(function () {
current = syncNext(current);
draw(current);
}, 100);
}, false);
</script>
</head>
<body>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
window.addEventListener("load", function (ev) {
"use strict";
// stage
var chart = d3.select("body").append("svg")
.attr("width", 960).attr("height", 760)
.append("g").attr("transform", "translate(80, 80)");
var x = d3.scale.linear().domain([0, 200]).range([0, 800]);
var y = d3.scale.linear().domain([0, 1.2]).range([600, 0]);
var xaxis = d3.svg.axis().scale(x).ticks(10).orient("botton");
var yaxis = d3.svg.axis().scale(y).ticks(12).orient("left");
chart.append("g").attr("class", "x axis")
.attr("transform", "translate(0, 600)").call(xaxis);
chart.append("g").attr("class", "y axis")
.attr("transform", "translate(0, 0)").call(yaxis);
// sync simulation data
var charge = function (y) {
//return Math.sin(Math.asin(y) + Math.PI/20);
return Math.log(Math.pow(Math.E, y) + (Math.E - 1) / 20);
};
var propagate = function (y, otherys) {
//return y;
return otherys.reduce(function (y, oy) {
return y + (oy === 0 ? 0.1 : 0);
}, y);
};
var fire = function (y) {
return y >= 1 ? 0 : y;
};
var dataA = [{x: 0, y: 0}];
var dataB = [{x: 0, y: 0.33}];
var dataC = [{x: 0, y: 0.66}];
for (var i = 0; i < 200; i++) {
var lastA = dataA[dataA.length - 1];
var lastB = dataB[dataB.length - 1];
var lastC = dataC[dataC.length - 1];
// charge
var chargeA = charge(lastA.y);
var chargeB = charge(lastB.y);
var chargeC = charge(lastC.y);
// propagate
var propA = propagate(chargeA, [lastB.y, lastC.y]);
var propB = propagate(chargeB, [lastA.y, lastC.y]);
var propC = propagate(chargeC, [lastA.y, lastC.y]);
var nextA = {x: lastA.x + 1, y: fire(propA)};
var nextB = {x: lastB.x + 1, y: fire(propB)};
var nextC = {x: lastC.x + 1, y: fire(propC)};
dataA.push(nextA);
dataB.push(nextB);
dataC.push(nextC);
}
// plot lines
var line = d3.svg.line().x(function (d) {return x(d.x);}).
y(function (d) {return y(d.y);});
chart.append("path").attr("class", "dataA").attr("d", line(dataA));
chart.append("path").attr("class", "dataB").attr("d", line(dataB));
chart.append("path").attr("class", "dataC").attr("d", line(dataC));
}, false);
</script>
<style>
path.dataA {
stroke: red;
fill: none;
}
path.dataB {
stroke: blue;
fill: none;
}
path.dataC {
stroke: green;
fill: none;
}
</style>
</head>
<body>
<h1>Simulation of SYNC</h1>
</body>
</html>
@bellbind
Copy link
Author

Peskin's capacitor sync model from Steven Strogatz book "SYNC".

demo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment