Skip to content

Instantly share code, notes, and snippets.

@vasturiano
Last active October 22, 2017 04:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vasturiano/17fd83953443cb6b4b76fecac5779797 to your computer and use it in GitHub Desktop.
Save vasturiano/17fd83953443cb6b4b76fecac5779797 to your computer and use it in GitHub Desktop.
Pendulum

Ok, I'm confused. Why isn't energy conserved and does the pendulum eventually stop?

<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/4.8.0/d3.min.js"></script>
<script src="//unpkg.com/d3-force-constant"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<svg id="canvas" width="100%" height="100%">
<line id="wire-el" stroke="slategray"></line>
<circle id="ball-el" r="15" fill="midnightblue"></circle>
</svg>
<script src="index.js"></script>
</body>
const BALL_RADIUS = 20,
WIRE_LENGTH = window.innerHeight/ 2,
GRAVITY = 0.6;
const canvasWidth = window.innerWidth,
canvasHeight = window.innerHeight;
const ball = { x: canvasWidth/2 - WIRE_LENGTH, y: canvasHeight/2 - WIRE_LENGTH/2 },
pivot = { fx: canvasWidth/2, fy: canvasHeight/2 - WIRE_LENGTH/2 },
wire = { source: 0, target: 1 };
let init = false;
d3.forceSimulation()
.alphaDecay(0)
.velocityDecay(0)
.nodes([ball, pivot])
.force('gravity', d3.forceConstant()
.strength(GRAVITY)
.direction(90)
)
.force('suspension', d3.forceLink([wire])
.distance(WIRE_LENGTH)
)
.force('init', () => {
if (!init) {
ball.vx = 0;
ball.vy = 0;
init = true;
}
})
.on('tick', () => { ballDigest(); wireDigest(); });
// Drag interaction
d3.select('#ball-el').call(d3.drag()
.on("start", d => { d.fx = d.x; d.fy = d.y; })
.on("drag", d => { d.fx = d3.event.x; d.fy = d3.event.y; })
.on("end", d => { d.fx = null; d.fy = null; })
);
//
function ballDigest() {
d3.select('#ball-el').datum(ball)
.attr('cx', d => d.x)
.attr('cy', d => d.y);
}
function wireDigest() {
d3.select('#wire-el').datum(wire)
.attr('x1', d => d.source.x)
.attr('y1', d => d.source.y)
.attr('x2', d => d.target.x)
.attr('y2', d => d.target.y);
}
body {
margin: 0;
text-align: center;
}
#ball-el {
cursor: grab;
cursor: -webkit-grab;
}
#ball-el:active {
cursor: grabbing;
cursor: -webkit-grabbing;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment