user1590534
user1590534

Reputation: 322

Javascript, Canvas: Calculating the angle from a flying bubble

What I have:

A lot of bubbles. But to make it more simple, let's say I have two. When they meet each other they collide and change the direction.

var xVelocityBubble1 = Math.random();
var yVelocityBubble1 = Math.random();

var xVelocityBubble2 = Math.random();
var yVelocityBubble2 = Math.random();

moveBubbles = function() {
xbubble1 += xVelocityBubble1;
ybubble1 += yVelocityBubble1;

xbubble2 -= xVelocityBubble2;
xbubble2 -= yVelocityBubble2;

if (Math.sqrt(Math.pow(xbubble1 - xbubble2, 2) + Math.pow(ybubble1 - ybubble2, 2)) < radius * 2) {
xVelocityBubble1 *= -1;
yVelocityBubble1 *= -1;
xVelocityBubble2 *= -1;
yVelocityBubble2 *= -1;
}
}

What I want:

I do not want the circles to simply change the direction, because that looks strange and boring. So I want to calculate the angle where the circle meet, and from that I need to calculate how much momentum they exchange and how that affects each circle.

My problem:

I really do not know how to calculate the angle and the momentum! Any hints?

Upvotes: 1

Views: 391

Answers (2)

Mher Sarkissian
Mher Sarkissian

Reputation: 131

This code shows collision of asteroids:

            for (var i = 0; i < asteroidsLength; i++) {
                var tmpAsteroid = asteroids[i];

                for (var j = i + 1; j < asteroidsLength; j++) {
                    var tmpAsteroidB = asteroids[j];

                    var dX = tmpAsteroidB.x - tmpAsteroid.x;
                    var dY = tmpAsteroidB.y - tmpAsteroid.y;
                    var distance = Math.sqrt((dX * dX) + (dY * dY));

                    if (distance < tmpAsteroid.radius + tmpAsteroidB.radius) {
                        var angle = Math.atan2(dY, dX);
                        var sine = Math.sin(angle);
                        var cosine = Math.cos(angle);

                        // Rotate asteroid position
                        var x = 0;
                        var y = 0;

                        // Rotate asteroidB position
                        var xB = dX * cosine + dY * sine;
                        var yB = dY * cosine - dX * sine;

                        // Rotate asteroid velocity

                        var vX = tmpAsteroid.vX * cosine + tmpAsteroid.vY * sine;
                        var vY = tmpAsteroid.vY * cosine - tmpAsteroid.vX * sine;

                        // Rotate asteroidB velocity
                        var vXb = tmpAsteroidB.vX * cosine + tmpAsteroidB.vY * sine;
                        var vYb = tmpAsteroidB.vY * cosine - tmpAsteroidB.vX * sine;

                        // Conserve momentum
                        var vTotal = vX - vXb;
                        vX = ((tmpAsteroid.mass - tmpAsteroidB.mass) * vX + 2 * tmpAsteroidB.mass * vXb) / (tmpAsteroid.mass + tmpAsteroidB.mass);
                        vXb = vTotal + vX;

                        // Move asteroids apart
                        xB = x + (tmpAsteroid.radius + tmpAsteroidB.radius);

                        // Rotate asteroid positions back
                        tmpAsteroid.x = tmpAsteroid.x + (x * cosine - y * sine);
                        tmpAsteroid.y = tmpAsteroid.y + (y * cosine + x * sine);

                        tmpAsteroidB.x = tmpAsteroid.x + (xB * cosine - yB * sine);
                        tmpAsteroidB.y = tmpAsteroid.y + (yB * cosine + xB * sine);

                        // Rotate asteroid velocities back
                        tmpAsteroid.vX = vX * cosine - vY * sine;
                        tmpAsteroid.vY = vY * cosine + vX * sine;

                        tmpAsteroidB.vX = vXb * cosine - vYb * sine;
                        tmpAsteroidB.vY = vYb * cosine + vXb * sine;
                    };

                };

Upvotes: 0

Delta
Delta

Reputation: 4328

To get the angle between those two bubbles if they collide do as follows:

get the direction vector in which one of those bubbles were moving

direction = {x: Math.abs(xVelocityBubble1), y: Math.abs(yVelocityBubble1)};

Then normalize that vector (divide it's x and y components by it's length)

After doing that you'll have the cosine of the angle as the x component and the sine as the y, just use any of them in Math.acos or Math.asin and you'll have the angle in which they collided.

Upvotes: 1

Related Questions