使用epsilon值来确定游戏中的球是否没有移动?

时间:2008-12-10 00:02:53

标签: vector physics epsilon

我有球弹跳,每次碰撞他们的速度向量都会被归还系数降低。

现在我的球为我的球的CoR是.80。因此,经过多次弹跳后,我的球已“停止”滚动,因为它们的速度变得有些可笑。

在什么阶段检查速度值是否足够小以简单地将其称为零(因此我没有对球的微速度做出反应的疯狂抖动)。我之前在一些论坛上看过,人们有时候会使用一个epsilon常量,一些小数字,并检查它。

我应该定义一个epsilon常量并执行以下操作:

if Math.abs(velocity.x) < epsilon then velocity.x = 0

每次更新球的速度和位置?这是通常做的吗?将它放在我的Vector类设置器中用于x和y是否合理?或者,当我计算速度时,我应该在矢量类之外进行。

另外,如果我使用花车作为我的速度矢量,那将是一个合理的epsilon值吗?

4 个答案:

答案 0 :(得分:1)

epsilon的合理值取决于系统的约束。如果您以图形方式表示球,那么您的epsilon可能对应于,例如,每秒0.1像素的速度(确保您的停止概念与用户对屏幕对象停止的体验相匹配)。如果您正在进行物理模拟,则需要将其调整到您尝试测量系统的精度。

至于你检查的频率 - 这也取决于你。如果您是实时模拟某些内容,额外检查可能会很昂贵,并且您需要检查每10次更新或每秒检查一次。或者性能可能不是问题,您可以查看每次更新。

答案 1 :(得分:1)

可能您可以使用UpdatePosition函数代替IsStillMoving函数的epsilon,该函数基于其速度逐个对象进行调度。

我会做这样的事情(在我自己的make-it-up-you-go-go伪代码中):

void UpdatePosition(Ball b) {

   TimeStamp now = Clock.GetTime();
   float secondsSinceLastUpdate = now.TimeSince(b.LastUpdate).InSeconds;

   Point3D oldPosition = b.Position;
   Point3D newPosition = CalculatePosition(b.Position, b.Velocity, interval);
   b.MoveTo(newPosition);

   float epsilonOfAccuracy = 0.5; // Accurate to one half-pixel
   float pixelDistance = Camera.PixelDistance(oldPosition, newPosition);
   float fps = System.CurrentFramesPerSecond;
   float secondsToMoveOnePixel = (pixelDistance * secondsSinceLastUpdate) / fps;
   float nextUpdateInterval = secondsToMoveOnePixel / epsilonOfAccuracy;

   b.SetNextUpdateAt(now + nextUpdateInterval);
}

快速移动的球会在每一帧都得到更新。球移动得更慢可能每五或十帧更新一次。停止(或几乎停止)的球只会很少更新。

答案 2 :(得分:0)

IMO你的epsilon方法很好。我只是试着看看游戏中动画的外观和感觉。

答案 3 :(得分:0)

Epsilon本质上是可能的最小增量。不幸的是,计算机根据浮点表示具有不同的“最小”增量。我会非常小心(甚至可能比我为安全而计算的更高)玩这个,特别是如果我想要一个可移植的代码。

您可能希望编写一个函数来计算浮点数的最小增量,而不是使用魔术值。

豫ICP备18024241号-1