Goal:
(1,2),(1,3),(1,5),(1,7), (2,4),(2,6), (3,6),(3,8), (4,5),(4,9), (5,11), (6,9),(6,10), (7,11),(7,8), (8,10), (9,11), (10,11)⇒
<div id="graph"></div>
<script>
let graph = [[1,2], [0,2], [0,1]];
let g = new Graph(
document.getElementById("graph"),
graph,
function(g) { /* compute forces */ }
);
</script>
// Reset forces to 0
this.nodes.forEach(function(n) {
[n.ax, n.ay] = [0, 0];
})
// Run provided function to calculate forces
update(this);
// Step simulation
for (let i = 0; i < n; i++) {
let n = this.nodes[i];
// v' = a
n.vx += n.ax;
n.vy += n.ay;
// x' = v
n.x += n.vx;
n.y += n.vy;
// boundary-conditions
if (n.x < 0) {
n.x = 0;
n.vx = Math.max(n.vx, -n.vx);
}
if (n.x > c.width-1) {
n.x = c.width-1;
n.vx = Math.min(n.vx, -n.vx);
}
if (n.y < 0) {
n.y = 0;
n.vy = Math.max(n.vy, -n.vy);
}
if (n.y > c.height-1) {
n.y = c.height-1;
n.vy = Math.min(n.vy, -n.vy);
}
}
Hooke's law: \(\vec F = -k\vec x\)
function(g) {
const springK = 0.001;
for (let i = 0; i < g.nodes.length; i++) {
let n = g.nodes[i];
g.edges[i].forEach(function(j) {
let m = g.nodes[j];
let [dx, dy] = [n.x-m.x, n.y-m.y];
n.ax -= springK * dx;
n.ay -= springK * dy;
})
}
}
Drag force: \(\vec F = -c\vec v\)
function(g) {
const springK = 0.001;
const drag = 0.1;
for (let i = 0; i < g.nodes.length; i++) {
let n = g.nodes[i];
g.edges[i].forEach(function(j) {
let m = g.nodes[j];
let [dx, dy] = [n.x-m.x, n.y-m.y];
n.ax -= springK * dx;
n.ay -= springK * dy;
})
n.ax -= n.vx * drag;
n.ay -= n.vy * drag;
}
}
Coulomb's law: \(\vec F = k_e \frac{q_1q_2}{|r|^2}\frac{\vec r}{|r|}\)
function(g) {
const springK = 0.001;
const drag = 0.1;
const electricK = 1000;
for (let i = 0; i < g.nodes.length; i++) {
let n = g.nodes[i];
g.edges[i].forEach(function(j) {
let m = g.nodes[j];
let [dx, dy] = [n.x-m.x, n.y-m.y];
n.ax -= springK * dx;
n.ay -= springK * dy;
})
for (let j = 0; j < g.nodes.length; j++) {
if (i == j) { continue; }
let m = g.nodes[j];
let [dx, dy] = [n.x-m.x, n.y-m.y];
let d = Math.sqrt(dx*dx+dy*dy);
if (d == 0) { continue; }
let F = electricK / d**3;
n.ax += dx * F;
n.ay += dy * F;
}
n.ax -= n.vx * drag;
n.ay -= n.vy * drag;
}
}