javascript - Collision detect fails when velocity is too high -


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