Elastic Collision in 2D(No Gravity)
A Pen by Piyush Keshari on CodePen.
Elastic Collision in 2D(No Gravity)
A Pen by Piyush Keshari on CodePen.
| <canvas style="background-color:black"></canvas> |
| let canvas = document.querySelector("canvas"); | |
| let ctx = canvas.getContext("2d"); | |
| canvas.width = document.body.clientWidth; | |
| canvas.height = document.body.clientHeight; | |
| let w = canvas.width; | |
| let h = canvas.height; | |
| const g = 9.8; | |
| const no = 25; | |
| //Bubble Object | |
| function bubble() { | |
| this.r = 15; | |
| this.x = Math.random() * (w - this.r - this.r) + this.r; | |
| this.y = Math.random() * (h - this.r - this.r) + this.r; | |
| this.mass = 100; | |
| this.color = "#" + Math.floor(Math.random() * 16777215).toString(16); | |
| this.Vx = Math.random() < 0.5 ? Math.random() * -10 : Math.random() * 10; | |
| this.Vy = Math.random() < 0.5 ? Math.random() * -10 : Math.random() * 10; | |
| } | |
| //Bubble Array | |
| let bubbles = []; | |
| //Function to fill array with different bubbles | |
| function create_bubbles(no) { | |
| for (let i = 0; i < no; i++) { | |
| bubbles[i] = new bubble(); | |
| } | |
| } | |
| //Function to draw Circle | |
| function circle(width, height, radius, color) { | |
| ctx.beginPath(); | |
| ctx.arc(width, height, radius, 0, Math.PI * 2, false); | |
| ctx.strokeStyle = color; | |
| ctx.fillStyle = color; | |
| ctx.fill(); | |
| ctx.stroke(); | |
| } | |
| //Function to detect Collision | |
| function collision(x1, y1, r1, x2, y2, r2) { | |
| if (Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) <= r1 + r2) { | |
| return true; | |
| } | |
| } | |
| //Creating Bubbles | |
| create_bubbles(no); | |
| //Function to draw bubbles on canvas | |
| function animate() { | |
| ctx.clearRect(0, 0, w, h); | |
| for (let i = 0; i < no; i++) { | |
| for (let j = i + 1; j < no; j++) { | |
| if ( | |
| collision( | |
| bubbles[i].x, | |
| bubbles[i].y, | |
| bubbles[i].r, | |
| bubbles[j].x, | |
| bubbles[j].y, | |
| bubbles[j].r | |
| ) | |
| ) { | |
| //velocity Change | |
| let temp = bubbles[i].Vx; | |
| bubbles[i].Vx = bubbles[j].Vx; | |
| bubbles[j].Vx = temp; | |
| temp = bubbles[i].Vy; | |
| bubbles[i].Vy = bubbles[j].Vy; | |
| bubbles[j].Vy = temp; | |
| //Bouncing Back | |
| let theta = Math.atan( | |
| (bubbles[i].y - bubbles[j].y) / (bubbles[i].x - bubbles[j].x) | |
| ); | |
| if (theta < 0) { | |
| theta = -theta; | |
| } | |
| const midpointX = (bubbles[i].x + bubbles[j].x) / 2; | |
| const midpointY = (bubbles[i].y + bubbles[j].y) / 2; | |
| if (bubbles[i].x < bubbles[j].x) { | |
| bubbles[i].x = midpointX - bubbles[i].r * Math.cos(theta); | |
| bubbles[j].x = midpointX + bubbles[j].r * Math.cos(theta); | |
| } else if (bubbles[i].x > bubbles[j].x) { | |
| bubbles[i].x = midpointX + bubbles[i].r * Math.cos(theta); | |
| bubbles[j].x = midpointX - bubbles[j].r * Math.cos(theta); | |
| } | |
| if (bubbles[i].y < bubbles[j].y) { | |
| bubbles[i].y = midpointY - bubbles[i].r * Math.sin(theta); | |
| bubbles[j].y = midpointY + bubbles[j].r * Math.sin(theta); | |
| } else if (bubbles[i].y > bubbles[j].y) { | |
| bubbles[i].y = midpointY + bubbles[i].r * Math.sin(theta); | |
| bubbles[j].y = midpointY - bubbles[j].r * Math.sin(theta); | |
| } else { | |
| bubbles[i].y = midpointY - bubbles[i].r * Math.sin(theta); | |
| bubbles[j].y = midpointY + bubbles[j].r * Math.sin(theta); | |
| } | |
| } | |
| } | |
| if (bubbles[i].x < bubbles[i].r) { | |
| bubbles[i].x = bubbles[i].r; | |
| bubbles[i].Vx *= -1; | |
| } else if (bubbles[i].x > w - bubbles[i].r) { | |
| bubbles[i].x = w - bubbles[i].r; | |
| bubbles[i].Vx *= -1; | |
| } | |
| if (bubbles[i].y < bubbles[i].r) { | |
| bubbles[i].y = bubbles[i].r; | |
| bubbles[i].Vy *= -1; | |
| } else if (bubbles[i].y > h - bubbles[i].r) { | |
| bubbles[i].y = h - bubbles[i].r; | |
| bubbles[i].Vy *= -1; | |
| } | |
| bubbles[i].x += bubbles[i].Vx; | |
| bubbles[i].y += bubbles[i].Vy; | |
| circle(bubbles[i].x, bubbles[i].y, bubbles[i].r, bubbles[i].color); | |
| } | |
| setTimeout(animate, 17); | |
| //requestAnimationFrame(animate); | |
| } | |
| animate(); |
| body { | |
| margin: 0px; | |
| padding: 0px; | |
| width: 100vw; | |
| height: 100vh; | |
| } |