c++ - 碰撞前对象暂存
问题描述
我正在做台球游戏。目前,当一个球与另一个球高速碰撞时,并不总是能正确计算碰撞。我知道问题是什么,但我不是 100% 确定如何解决它。
目前,我的物理引擎将在此时处理碰撞。这不会产生预期的结果,因为这不是球在现实中碰撞的地方——球不会相互穿过。所以,我们需要将球备份到它们真正碰撞的地方。看起来像这样:
我正在寻找一种有效的算法来帮助我做到这一点。目前,我有一个非常幼稚和低效的方法 - 我将两个球移动到碰撞前的位置,并在碰撞时刻采取非常小的步骤。当然,这是非常低效的。这是它的样子:
void CBallCollision::StageCollision()
{
double sumOfRadii = mBall1->GetRadius() + mBall2->GetRadius();
mBall1->SetCenter(mBall1->GetLastLocationOnTable().first, mBall1->GetLastLocationOnTable().second);
mBall2->SetCenter(mBall2->GetLastLocationOnTable().first, mBall2->GetLastLocationOnTable().second);
double timeStep = 0.008;
double tolerance = 0.1 * min(mBall1->GetRadius(), mBall2->GetRadius());
int iter = 0;
while (GetDistance() > sumOfRadii)
{
double xGoal1 = mBall1->GetX() + mBall1->GetVelocityX() * timeStep;
double yGoal1 = mBall1->GetY() + mBall1->GetVelocityY() * timeStep;
pair<double, double> newCoords1 = mBall1->LinearInterpolate(xGoal1, yGoal1);
double xGoal2 = mBall2->GetX() + mBall2->GetVelocityX() * timeStep;
double yGoal2 = mBall2->GetY() + mBall2->GetVelocityY() * timeStep;
pair<double, double> newCoords2 = mBall2->LinearInterpolate(xGoal2, yGoal2);
double dist = (pow(newCoords1.first - newCoords2.first, 2) + pow(newCoords1.second - newCoords2.second, 2));
if (abs(dist - sumOfRadii) > tolerance)
{
timeStep *= 0.5;
}
else
{
mBall1->SetX(newCoords1.first);
mBall1->SetY(newCoords1.second);
mBall2->SetX(newCoords2.first);
mBall2->SetY(newCoords2.second);
}
iter++;
if (iter > 1000)
{
break;
}
}
}
如果我不对迭代次数设置上限,程序就会崩溃。我确信有一种更有效的方法来解决这个问题。任何帮助表示赞赏。
解决方案
推荐阅读
- java - 在 java 中,如何使用正则表达式模式来解析事件名称和两个数字字符串的“Event=Bell,time=9000,rings=5”?
- javascript - 如何将单个对象对象转换为对象数组?
- winforms - Windows 窗体 - 单击按钮将数据添加到列表视图
- java - 比较子实体列表时获取父实体 ID
- r - 如何在 kknn 函数中进行预测?图书馆(kknn)
- python - 如何将数组相乘以输出多个数组而不是相乘的值?
- python - 运行 tox 时如何修复“envreport”中的“UnicodeDecodeError”?
- vim - 紧迫
突然映射到 Esc(而不是字符“#” - jquery - 使用 jquery 解析 json 并在 ayyas 上捕获一些值
- c# - 一种解析多维字符串数组以列出c#的方法