i'm having problem while trying detect collisions between 2 balls when 1 (or both) have high velocity. guess common issue , understand why happens. guess solution have derivatives, have designed don't want "re-invent wheel" if there known solution.
anything may enlight path apretiated!
i did simple example. if both balls have speed of, lets say, 1.5 or 3, collide. if use higher, 50, fail.
<html> <head> <title>collision test</title> </head> <body> <canvas id="canvas"></canvas> <script> const canvas = document.getelementbyid("canvas"); const ctx = canvas.getcontext("2d"); const width = window.innerwidth; const height = window.innerheight-4; const center = { x: width/2, y: height/2 }; canvas.width = width; canvas.height = height; // ball class definition class ball { constructor(x, y, mass, direction, speed, color) { this.x = x; this.y = y; this.vx = (math.cos(direction) * speed) || 0; this.vy = (math.sin(direction) * speed) || 0; this.mass = mass || 1; this.radius = mass * 3; this.color = color || "#000000"; } update() { this.x += this.vx; this.y += this.vy; } } let speeda = 1.5; let speedb = 1; // create 2 balls collide let balla = new ball(center.x - 300, center.y, 3, math.pi*2, speeda, "green"); let ballb = new ball(center.x + 100, center.y, 2.2, math.pi, speedb, "green"); // main update/draw function function draw() { window.requestanimationframe(draw); ctx.clearrect(0,0, width, height); balla.update(); ballb.update(); handlecollisions(balla, ballb); // draw ball ctx.beginpath(); ctx.arc(balla.x, balla.y, balla.radius, 0, math.pi * 2, false); ctx.fillstyle = balla.color; ctx.fill(); // draw ball b ctx.beginpath(); ctx.arc(ballb.x, ballb.y, ballb.radius, 0, math.pi * 2, false); ctx.fillstyle = ballb.color; ctx.fill(); } // detect , handle collision function handlecollisions(p1, p2) { let xdist, ydist; xdist = p1.x - p2.x; ydist = p1.y - p2.y; let distsquared = xdist*xdist + ydist*ydist; //check squared distances instead of the distances, same result, avoids square root. if(distsquared <= (p1.radius + p2.radius)*(p1.radius + p2.radius)){ let xvelocity = p2.vx - p1.vx; let yvelocity = p2.vy - p1.vy; let dotproduct = xdist*xvelocity + ydist*yvelocity; //neat vector maths, used checking if objects moves towards 1 another. if(dotproduct > 0){ let collisionscale = dotproduct / distsquared; let xcollision = xdist * collisionscale; let ycollision = ydist * collisionscale; //the collision vector speed difference projected on dist vector, //thus component of speed difference needed collision. let combinedmass = p1.mass + p2.mass; let collisionweighta = 2 * p2.mass / combinedmass; let collisionweightb = 2 * p1.mass / combinedmass; p1.vx += collisionweighta * xcollision; p1.vy += collisionweighta * ycollision; p2.vx -= collisionweightb * xcollision; p2.vy -= collisionweightb * ycollision; } } } draw(); </script> </body> </html>
i added code jsbin.
the problem collision detection done using distance between locations of balls, if moving fast, might "hop" right on each other , never near enough collision detected.
one solution might calculate points along hop, , respective times, each ball. then, compare list of points each ball, , see if there time when balls close enough collision. in other words, interpolate positions in between frames , check collision @ these interpolated positions. have careful though because though balls might pass through point close enough collision, need @ around same time.
i sure there exists javascript frameworks or libraries games , physics if not want take on yourself. have not ever dealt them, google should know.
Comments
Post a Comment