Skip to content

Instantly share code, notes, and snippets.

@vasturiano
Last active March 27, 2021 22:26
  • Star 1 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 vasturiano/1d3dad0a970d6d61629cd84babd2bbd1 to your computer and use it in GitHub Desktop.
Cluster Collision

Simulation of the interleaving effect resulting of two different groups of particles colliding. The red group follows the mouse cursor, while the blue group is focused on the canvas center.

Uses d3.forceX, d3.forceY, and d3.forceCollide as forces, and d3ForcePod for the simulation scaffolding.

<head>
<style>body { margin: 0; }</style>
<script src="//unpkg.com/d3-force-pod"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.min.js"></script>
</head>
<body>
<script>
const NODE_R = 6;
const pod = d3ForcePod()(document.body)
.genNodes({
density: 5e-4,
radiusRange: [NODE_R, NODE_R],
velocityRange: [0, 0]
});
pod.simulation().velocityDecay(0.2)
// split into two groups
const numNodes = pod.nodes().length;
pod.nodes().forEach((d, i) => d.group = i < numNodes / 2 ? 0 : 1);
pod.nodeColor(({ group }) => group ? 'midnightblue' : 'crimson');
// Set x/y attraction forces
const center = { x: window.innerWidth / 2, y: window.innerHeight / 2 };
const forceX = d3.forceX().strength(0.01).x(center.x);
const forceY = d3.forceY().strength(0.01).y(center.y);
pod.addForce(forceX);
pod.addForce(forceY);
// Have one of the groups follow cursor
d3.select('body').on('mousemove', function () {
const [x, y] = d3.mouse(this);
forceX.x(d => d.group ? center.x : x);
forceY.y(d => d.group ? center.y : y);
});
// Add collision force
pod.addForce(d3.forceCollide()
.radius(NODE_R + 2)
.strength(0.9)
);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment