圆撞毛刺和破坏水池原型

时间:2019-02-17 11:56:57

标签: c++ sfml

我正在使用SFML进行2D球对球碰撞以进行绘制。 我添加了静态和动态响应,但是遇到一个我从未在任何地方讨论过的问题。当有2个球时,碰撞效果很好,但有时如果我添加第3个球,它就会破裂。第一个球从墙壁上弹起,而第三个和第二个碰撞,然后第二个球通过第一个球毛刺,增压 两者都没有遵守物理定律。

我无法发布图片,因此,这里的gif链接: https://drive.google.com/file/d/0B27p1fiTRRJoRXd6QmxYdjM3SGZJNVFyRkR4SVFOeEVCWlZR/view?usp=sharing

这是一个告诉球是否碰撞的函数:

bool Ball::isColliding(Ball & ball)
{
float distance = std::sqrt(((pos.x - ball.pos.x) * (pos.x - 
ball.pos.x)) + ((pos.y - ball.pos.y) * (pos.y - ball.pos.y)));
float radiusSum = this->radius + ball.radius;


if (distance <= radiusSum)
{
    return true;
}

return false;
}

并具有解决冲突的功能:

void Ball::resolveCollison(Ball &ball)
{

//Static resolution
float fDistance = std::sqrt(((pos.x - ball.pos.x) * (pos.x - 
    ball.pos.x)) + ((pos.y - ball.pos.y) * (pos.y - ball.pos.y)));
float fOverlap = 0.5f * (fDistance - radius - ball.radius);

//Displace current ball
pos.x -= fOverlap * (pos.x - ball.pos.x) / fDistance;
pos.y -= fOverlap * (pos.y - ball.pos.y) / fDistance;
//Displace target ball
ball.pos.x += fOverlap * (pos.x - ball.pos.x) / fDistance;
ball.pos.y += fOverlap * (pos.y - ball.pos.y) / fDistance;

//Dynamic resolution

//Normal
float nx = (ball.pos.x - pos.x ) / fDistance;
float ny = (ball.pos.y - pos.y ) / fDistance;

//Tangent
float tx = -ny;
float ty = nx;

float dpTan1 = vel.x * tx + vel.y * ty;
float dpTan2 = ball.vel.x * tx + ball.vel.y * ty;

float dpNorm1 = vel.x * nx + vel.y * ny;
float dpNorm2 = ball.vel.x * nx + vel.y * ny;

float m1 = (dpNorm1 * (mass - ball.mass) + 2.0f * ball.mass * dpNorm2) 
    / (mass + ball.mass);
float m2 = (dpNorm2 * (ball.mass - mass) + 2.0f * mass * dpNorm1) / 
    (mass + ball.mass);

vel.x = tx * dpTan1 + (nx * m1);
vel.y = ty * dpTan1 + (ny * m1);
ball.vel.x = tx * dpTan2 + (nx * m2);
ball.vel.y = ty * dpTan2 + (ny * m2);

}

我知道这不是最优雅的解决方案,但这是我第一次这样做。无论如何,我还会像这样在每个循环中更新球:

void Ball::update()
{
//friction - do not touch
acc.x = -vel.x * 0.001f;
acc.y = -vel.y * 0.001f;

//updating the position
vel += acc;
pos += vel;
circ.setPosition(pos);
 }

还请注意,Ball只是一个类,用于保存球的速度,加速度和位置矢量,进行初始化,并使用sf::CircleShape(命名为circ)进行绘制。

这些球本应通过弹性碰撞现实地碰撞(或尽可能真实地碰撞,因为没有角动量),但实际上,它们会不断发生毛刺。 我不确定为什么会这样,因此非常感谢您的帮助。

0 个答案:

没有答案