1

物体可以经常互相穿过吗?此外,在计算动量时,有时精灵会在碰撞时形成斑点,一起移动而不是反弹。

该代码确实适用于大多数碰撞,但它经常失败。有任何想法吗?

xV = X 速度。yV = Y 速度。每一帧,这个速度值都被添加到四边形的 X 和 Y 位置。

bool Quad::IsTouching(Quad &q)
{
    float distance = 0;
    float combinedRadius = (size/2) + (q.GetSize()/2);

    distance = sqrt(pow(q.GetX() - GetX(), 2) + pow(q.GetY() - GetY(), 2));

    if(distance < combinedRadius)
    {
        return true;
    }

    return false;
}

void Quad::Collide(Quad &q)
{
    float mX, mY, mX2, mY2, mXTmp, mYTmp;

    mX = mass * xV;
    mY = mass * yV;
    mXTmp = mX;
    mYTmp = mY;

    mX2 = q.GetMass() * q.GetxV();
    mY2 = q.GetMass() * q.GetyV();

    mX = mX2;
    mY = mY2;

    mX2 = mXTmp;
    mY2 = mYTmp;

    xV = mX/mass;
    yV = mY/mass;

    q.SetxV(mX2/q.GetMass());
    q.SetyV(mY2/q.GetMass());
}
4

3 回答 3

0

你指的是什么类型的碰撞?有弹性还是无弹性?对于弹性碰撞,代码会失败,您必须创建一个附加属性来防止两个对象在接触时粘在一起。您还必须使用循环或 if 语句确保如果一个对象与另一个对象同时穿过另一个对象的位置,则两者将以与碰撞速度成比例的角度分开。使用适当的物理公式。

于 2013-04-20T21:50:29.823 回答
0

我有同样的问题是我制作的一个快速视频来演示这个问题。

解决这个问题的方法是计算碰撞的确切时间,因此粒子将以新的速度移动迭代/时间步长的剩余时间。为此,您必须在更新位置之前检查是否会发生碰撞,因此:sqrt((x1 - x2 + dt * (vx1 - vx2))^2 + (y1 - y2 + dt * (vy1 - vy2))^2) <= distance

您也许还可以采用更简单的解决方案,在该解决方案中稍微移动两个对象,以使它们不再发生碰撞。这会导致创建者不准确,但确实需要更少的计算:

dx = x1 - x2;
dy = y1 - y2;
d = sqrt(dx^2 + dy^2);
D = r1 + r2;
if(d < D)
{
    s = (d - D) / (2 * d);
    x1 = x1 + s * dx;
    x2 = x2 - s * dx;
    y1 = y1 + s * dy;
    y2 = y2 - s * dy;
}
于 2013-04-21T08:24:08.917 回答
0

作为一个推断的、潜在的问题(没有提供速度、尺寸等的值,所以我不能肯定地说),你没有考虑到四边形完全接触。即,distance == combinedRadius。因此,如果为真,则检查失败,然后对象继续在下一个滴答声中移动……彼此穿过。

将您的支票更改为distance <= combinedRadius. 此外,您可能只是获得了隧道效应,因为对象足够小并且移动速度足够快,以至于它们在每个滴答声中都相互穿过。有多种方法可以解决这个问题,其中一些是:施加最大速度和最小尺寸;提高物理检查的帧速率;使用连续碰撞检查与离散检查:请参阅有关主题的维基百科文章

于 2013-04-20T22:44:38.437 回答