球与球的碰撞分辨率粘在一起

Ball to Ball Collision resolution Stick together

如果有以下模拟球与球碰撞的代码。我的问题是,球相互弹跳。我想让球像雪粒一样粘在一起。有人知道怎么做吗?

/**
 * 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
 */

glm::vec3 rotateVel(glm::vec3 vel, float angle) {
    glm::vec3 rotatedVelocities = {
        vel.x * std::cos(angle) - vel.y * std::sin(angle),
        vel.x * std::sin(angle) + vel.y * std::cos(angle),
        0
    };

    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
 */

void resolveCollision(Particle& particle, Particle& otherParticle) {
    float xVelocityDiff = particle.speed.x - otherParticle.speed.x;
    float yVelocityDiff = particle.speed.y - otherParticle.speed.y;

    float xDist = otherParticle.pos.x - particle.pos.x;
    float yDist = otherParticle.pos.y - particle.pos.y;

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

        // Grab angle between the two colliding particles
        float angle = -std::atan2(otherParticle.pos.y - particle.pos.y, otherParticle.pos.x - particle.pos.x);

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

        // Velocity before equation
        glm::vec3 u1 = rotateVel(particle.speed, angle);
        glm::vec3 u2 = rotateVel(otherParticle.speed, angle);

        // Velocity after 1d collision equation
        glm::vec3 v1(u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2),
            u1.y,
            0.0);
        glm::vec3 v2(u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m2 / (m1 + m2),
            u2.y,
            0.0);

        // Final velocity after rotating axis back to original location
        glm::vec3 vFinal1 = rotateVel(v1, -angle);
        glm::vec3 vFinal2 = rotateVel(v2, -angle);

        // Swap particle velocities for realistic bounce effect
        particle.speed.x = vFinal1.x *0.5;
        particle.speed.y = vFinal1.y * 0.5;

        otherParticle.speed.x = vFinal2.x * 0.5;
        otherParticle.speed.y = vFinal2.y * 0.5;
    }
}

我理解代码但不知道在哪里更改它以获得我想要的结果。

void resolveCollision(Particle& particle, Particle& otherParticle) {
    float xVelocityDiff = particle.speed.x - otherParticle.speed.x;
    float yVelocityDiff = particle.speed.y - otherParticle.speed.y;

    float xDist = otherParticle.pos.x - particle.pos.x;
    float yDist = otherParticle.pos.y - particle.pos.y;

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

        // Grab angle between the two colliding particles
        float angle = -std::atan2(otherParticle.pos.y - particle.pos.y, otherParticle.pos.x - particle.pos.x);

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

        // Velocity before equation
        glm::vec3 u1 = rotateVel(particle.speed, angle);
        glm::vec3 u2 = rotateVel(otherParticle.speed, angle);

        // Velocity after 1d collision equation
        glm::vec3 v1(u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2),
            u1.y,
            0.0);
        glm::vec3 v2(u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m2 / (m1 + m2),
            u2.y,
            0.0);

        // Final velocity after rotating axis back to original location
        glm::vec3 vFinal1 = rotateVel(v1, -angle);
        glm::vec3 vFinal2 = rotateVel(v2, -angle);

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

        otherParticle.speed.x = vFinal1.x;
        otherParticle.speed.y = vFinal1.y;
    }
}

这个解决方案对我有用。