球与球的碰撞分辨率粘在一起
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;
}
}
这个解决方案对我有用。
如果有以下模拟球与球碰撞的代码。我的问题是,球相互弹跳。我想让球像雪粒一样粘在一起。有人知道怎么做吗?
/**
* 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;
}
}
这个解决方案对我有用。