基于C++与SFML的可移动小球与固定小球碰撞问题
问题分析与修复方案
你的碰撞处理逻辑存在三个核心问题:
- 粒子已经嵌入重力源内部才处理速度,会导致持续触发碰撞判定
- 法向速度分量计算错误,误用了分量相乘而非点积运算
- 速度合成逻辑混乱,错误地将法向分量与切向单位向量直接相加
修复后的完整代码
void updatePhysics(GravitySource& gravitySource, float deltaTime) { //Normal Vector (from particle to gravity source) float distanceX = gravitySource.getPos().x - pos.x; float distanceY = gravitySource.getPos().y - pos.y; //Distance between GravitySource and Particle float distance = std::sqrt(distanceX * distanceX + distanceY * distanceY); //Simplifying division to speed up calculations float inverseDistance = 1.f / distance; //Unit Normal Vector float normalizedX = inverseDistance * distanceX; float normalizedY = inverseDistance * distanceY; float inverseSquareDropOff = inverseDistance * inverseDistance; //Calculating Acceleration float accelerationX = normalizedX * gravitySource.getStrength() * inverseSquareDropOff * deltaTime; float accelerationY = normalizedY * gravitySource.getStrength() * inverseSquareDropOff * deltaTime; //Updating Velocity vel.x += accelerationX; vel.y += accelerationY; //Updating Position pos.x += vel.x; pos.y += vel.y; //Updating Render Position relPos.x = pos.x - radius; relPos.y = pos.y - radius; //Collision Handling float minDistance = radius + gravitySource.getRadius(); if (distance <= minDistance) { // 1. 修正位置:将粒子从重力源内部推到碰撞边界外 float overlap = minDistance - distance; pos.x -= normalizedX * overlap; pos.y -= normalizedY * overlap; relPos.x = pos.x - radius; relPos.y = pos.y - radius; // 2. 计算速度的法向分量(向量点积) float normalSpeed = vel.x * normalizedX + vel.y * normalizedY; // 3. 法向速度反向(重力源固定,质量视为无穷大,弹性碰撞下法向速度反转) // 可调整restitution值(0~1)模拟非完全弹性碰撞 float restitution = 1.0f; float reversedNormalSpeed = -normalSpeed * restitution; // 4. 提取速度的切向分量(原速度减去法向分量) float tangentSpeedX = vel.x - normalizedX * normalSpeed; float tangentSpeedY = vel.y - normalizedY * normalSpeed; // 5. 合成新速度:切向分量 + 反转后的法向分量 vel.x = tangentSpeedX + normalizedX * reversedNormalSpeed; vel.y = tangentSpeedY + normalizedY * reversedNormalSpeed; } }
关键修复点说明
- 位置修正:计算粒子与重力源的重叠量,沿法向反方向移动粒子,确保它刚好贴在重力源表面,避免下一帧重复触发碰撞判定。
- 法向速度计算:通过向量点积
vel · normal得到速度在法向上的标量大小,这是法向分量的正确计算方式。 - 速度合成:
- 切向速度分量完全保留(无摩擦力时,碰撞不影响切向速度)
- 法向速度分量反向(重力源固定不动,等效于质量无穷大,粒子碰撞后法向速度反转,恢复系数可调整弹性程度)
内容的提问来源于stack exchange,提问作者jaqubm
相关产品推荐
相关产品推荐

