javascriptcanvasvector

Collision of two balls are getting stuck sometimes instead of bouncing off each other in html5 canvas


Balls do bounce, but sometimes they get stuck to each other.

Do tell if you need the rest of the code to solve this query.

This function is used to measure the distance between two balls.

    const measureDistance = (x1, y1, x2, y2) => {
        let result
        result = Math.pow(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2), 0.5)
        return result
    }
    function rotate(velocity, angle) {
        const rotatedVelocities = {
            x: velocity.dx * Math.cos(angle) - velocity.dy * Math.sin(angle),
            y: velocity.dx * Math.sin(angle) + velocity.dy * Math.cos(angle)
        };

        return rotatedVelocities;
    }
    const manageCollition = (tempArr, i, j) => {
        const angle = Math.tan(tempArr[j].dy - tempArr[i].dy / tempArr[j].dx - tempArr[i].dx)
        console.log(tempArr[j].dy - tempArr[i].dy / tempArr[j].dx - tempArr[i].dx)
        const u1 = rotate(tempArr[i], angle)
        const u2 = rotate(tempArr[j], angle)
        return { u1, u2 }

    }
    const checkCollisions = (ball, tempArr, i) => {
        let returnArr = tempArr;
        for (let j = 0; j < tempArr.length; j++) {
            if (j === i) continue
            const distance = measureDistance(ball.x, ball.y, tempArr[j].x, tempArr[j].y) - 2 * radius
            if (distance <= 0) {
                    const { u1, u2 } = manageCollition(tempArr, i, j)
                    returnArr = tempArr.map((element, index) => {
                        let newBall = element
                        if (index === i) {
                            newBall.dx = u1.x
                            newBall.dy = u1.y
                        }
                        if (index === j) {
                            newBall.dx = u2.x
                            newBall.dy = u2.y
                        }
                        return newBall
                    })
                }

            }
        return returnArr
    }

I think I made a mistake in physics or math somewhere.


Solution

  • const checkCollisions = (tempArr, i) => {
        let returnArr = tempArr;
        for (let j = 0; j < tempArr.length; j++) {
            if (j === i) continue
            const distance = measureDistance(tempArr[i].x, tempArr[i].y, tempArr[j].x, tempArr[j].y) - 2 * radius
            const xVelocityDiff = tempArr[i].dx - tempArr[j].dx
            const yVelocityDiff = tempArr[i].dy - tempArr[j].dy
            const xDistance = tempArr[j].x - tempArr[i].x
            const yDistance = tempArr[j].y - tempArr[i].y
            if (distance <= 0) {
                if (xVelocityDiff * xDistance + yVelocityDiff * yDistance >= 0) {
                    const { u1, u2 } = manageCollition(tempArr, i, j)
                    returnArr = tempArr.map((element, index) => {
                        let newBall = element
                        if (index === i) {
                            newBall.dx = u1.x
                            newBall.dy = u1.y
                        }
                        if (index === j) {
                            newBall.dx = u2.x
                            newBall.dy = u2.y
                        }
                        return newBall
                    })
                }
    
            }
        }
        return returnArr
    }
    

    Try this code for checkCollisions funtion.