物体经常可以相互穿过?另外,在计算动量时,偶尔精灵会在碰撞时形成斑点,一起移动而不是反弹。
代码适用于大多数冲突,但通常会失败。有什么想法吗?
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());
}
答案 0 :(得分:0)
您指的是哪种类型的碰撞?弹性还是无弹性?对于弹性碰撞,代码将失败,您必须创建一个附加属性以防止两个对象在接触时粘在一起。您还必须使用循环或if语句确保如果一个对象与另一个对象同时穿过另一个对象的位置,则两者将以与碰撞速度成比例的角度分离。使用适当的物理公式。
答案 1 :(得分:0)
作为一个推断的,潜在的问题(所提供的速度,尺寸等没有值,所以我不能肯定地说),你并不认为四边形是完全接触。也就是distance == combinedRadius
。因此,当这是真的时,检查失败,然后对象继续在下一个滴答中移动......正好相互通过。
将支票更改为distance <= combinedRadius
。此外,您可能只是获得隧道效应,因为对象足够小并且移动得足够快,以至于它们彼此穿过的每个刻度线。有多种方法可以解决这个问题,其中一些方法是:施加最大速度和最小尺寸;增加物理检查的帧速率;使用连续碰撞检查与离散检查:see wikipedia article on subject
答案 2 :(得分:0)
我有same issue和here是我为了证明问题所做的快速视频。
解决此问题的方法是计算碰撞的确切时间,因此粒子将使用新的速度移动迭代/时间步的剩余时间。要做到这一点,你必须在更新位置之前检查是否会发生碰撞,所以: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;
}