Разрешение столкновения шара с мячом - PullRequest
0 голосов
/ 26 ноября 2018

Я проходил некоторые уроки по обнаружению столкновений на YouTube. В одном из руководств парень использовал следующий код для разрешения столкновения между двумя шарами:

/**
 * Rotates coordinate system for velocities
 *
 * Takes velocities and alters them as if the coordinate system they're on was rotated
 *
 * @param  Object | velocity | The velocity of an individual particle
 * @param  Float  | angle    | The angle of collision between two objects in radians
 * @return Object | The altered x and y velocities after the coordinate system has been rotated
 */

function rotate(velocity, angle) {
    const rotatedVelocities = {
        x: velocity.x * Math.cos(angle) - velocity.y * Math.sin(angle),
        y: velocity.x * Math.sin(angle) + velocity.y * Math.cos(angle)
    };

    return rotatedVelocities;
}

/**
 * Swaps out two colliding particles' x and y velocities after running through
 * an elastic collision reaction equation
 *
 * @param  Object | particle      | A particle object with x and y coordinates, plus velocity
 * @param  Object | otherParticle | A particle object with x and y coordinates, plus velocity
 * @return Null | Does not return a value
 */

function resolveCollision(particle, otherParticle) {
    const xVelocityDiff = particle.velocity.x - otherParticle.velocity.x;
    const yVelocityDiff = particle.velocity.y - otherParticle.velocity.y;

    const xDist = otherParticle.x - particle.x;
    const yDist = otherParticle.y - particle.y;

    // Prevent accidental overlap of particles
    if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) {

        // Grab angle between the two colliding particles
        const angle = -Math.atan2(otherParticle.y - particle.y, otherParticle.x - particle.x);

        // Store mass in var for better readability in collision equation
        const m1 = particle.mass;
        const m2 = otherParticle.mass;

        // Velocity before equation
        const u1 = rotate(particle.velocity, angle);
        const u2 = rotate(otherParticle.velocity, angle);

        // Velocity after 1d collision equation
        const v1 = { x: u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2), y: u1.y };
        const v2 = { x: u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m2 / (m1 + m2), y: u2.y };

        // Final velocity after rotating axis back to original location
        const vFinal1 = rotate(v1, -angle);
        const vFinal2 = rotate(v2, -angle);

        // Swap particle velocities for realistic bounce effect
        particle.velocity.x = vFinal1.x;
        particle.velocity.y = vFinal1.y;

        otherParticle.velocity.x = vFinal2.x;
        otherParticle.velocity.y = vFinal2.y;
    }
}

Я в основном понял этот код,Тем не менее, я не могу понять, как это работает, если условие работает, чтобы узнать, перекрываются ли шары или нет.

if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0)

Может кто-нибудь объяснить, пожалуйста?

1 Ответ

0 голосов
/ 27 ноября 2018

Взяв разницу положений и скоростей, вы видите все в кадре otherParticle.В этом кадре otherParticle стоит неподвижно в начале координат, а particle движется с velocityDiff.Вот как это выглядит:

Visualization

Термин xVelocityDiff * xDist + yVelocityDiff * yDist является точечным произведением двух векторов.Это точечное произведение отрицательно, если velocityDiff указывает несколько в противоположном направлении dist, то есть если частица становится ближе, как на картинке выше.Если скалярное произведение положительно, частица удаляется от otherParticle, и вам не нужно ничего делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...