Last active
July 23, 2017 11:47
-
-
Save stephanbogner/bd96b24bfea82e7d2b6531060e386d59 to your computer and use it in GitHub Desktop.
Joint between two particles (verlet integration)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <canvas id="myCanvas" width="600" height="400"></canvas> | |
| <style type="text/css"> | |
| canvas { | |
| background: #F9F9F9; | |
| margin: 3rem auto; | |
| display: block; | |
| } | |
| </style> | |
| <script> | |
| var point1, point2, canvas, context, fps, interval, cursorX, cursorY; | |
| init(); | |
| function init() { | |
| // Set the start coordinates of our points | |
| point1 = { | |
| "x": 150, | |
| "y": 170 | |
| } | |
| point2 = { | |
| "x": 250, | |
| "y": 180 | |
| } | |
| // Reference canvas | |
| canvas = document.getElementById('myCanvas'); | |
| context = canvas.getContext('2d'); | |
| fps = 30; | |
| interval = 1 / fps * 1000; // 30 fps = doing something every (1/fps*1000) ms | |
| cursorX = 0; // start position of cursor (before we get the mouse position) | |
| cursorY = 0; | |
| initMouseListener(); | |
| setInterval(function() { update(); }, interval); // Draw 30 times per second | |
| } | |
| function update() { | |
| clearCanvas(); // Clear canvas | |
| setPointCoordinates(point1, { "x": cursorX, "y": cursorY }); // Move point to position of cursor | |
| constraint(point1, point2, 100); // Move point 1 and 2 so their distance equals exactly 100 pixels | |
| drawLine(point1, point2); // Draw line between point 1 and 2 | |
| drawPoint(point1); // Draw point 1 | |
| drawPoint(point2); // Draw point 2 | |
| } | |
| function constraint(point1, point2, targetDistance) { | |
| var fraction = 0.8; // This dampens the movement (1 = instant movement, 0 is no movement, 0.5 is a wobbly movement) | |
| var dx = point1.x - point2.x; // Distance between coordinates in x direction | |
| var dy = point1.y - point2.y; // Distance between coordinates in y direction | |
| var currentDistance = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); // Distance between Point 1 and Point 2 (pythagoras) | |
| var distanceDifference = targetDistance - currentDistance; // How far the points should be apart vs how far are they apart | |
| var angle = -Math.atan2(dx, dy); // Angle between points | |
| var moveX = Math.sin(angle) * distanceDifference; // Move much do you have to push a point in x direction | |
| var moveY = Math.cos(angle) * distanceDifference; // Move much do you have to push a point in y direction | |
| // Push points (divided by 2 because we want to push both ends and fraction for bouncy movement) | |
| point1.x -= moveX * fraction / 2; | |
| point1.y += moveY * fraction / 2; | |
| point2.x += moveX * fraction / 2; | |
| point2.y -= moveY * fraction / 2; | |
| } | |
| function drawPoint(point) { | |
| var radius = 10; | |
| context.beginPath(); | |
| context.arc(point.x, point.y, radius, 0, 2 * Math.PI, false); | |
| context.fillStyle = '#0000FF'; | |
| context.fill(); | |
| } | |
| function drawLine(point1, point2) { | |
| context.beginPath(); | |
| context.lineWidth = 4; | |
| context.strokeStyle = '#C3C3F9'; | |
| context.moveTo(point1.x, point1.y); | |
| context.lineTo(point2.x, point2.y); | |
| context.stroke(); | |
| } | |
| function setPointCoordinates(point, newCoordinates) { | |
| point.x = newCoordinates.x; | |
| point.y = newCoordinates.y; | |
| } | |
| function clearCanvas() { | |
| context.clearRect(0, 0, canvas.width, canvas.height); | |
| } | |
| function initMouseListener() { | |
| document.getElementById('myCanvas').onmousemove = function(e) { | |
| cursorX = e.pageX - this.offsetLeft | |
| cursorY = e.pageY - this.offsetTop | |
| } | |
| } | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment