减速不按预期工作

时间:2012-10-10 16:40:37

标签: c# math xna acceleration

几个小时前我问了一个类似的问题,但我认为这个问题的信息太多了,所以我删除了那个问题并使这个问题更具相关性。

我试图在指定时间内移动加速度减小的物体但在物体到达目的地之前加速度达到0。

我像这样计算加速度:

//Linear acceleration starts at 0 and finishes at 2.
acceleration = this.elapsed / (this.duration / 2.0f);

加速度将是0到2之间的值,具体取决于经过的时间。当经过的时间越接近(总)持续时间时,该值将接近2。

所以要计算减速度,我会这样做:

 //Linear deceleration starts at 2 and finishes at 0.
 acceleration = 2.0f - this.elapsed / (this.duration / 2.0f);

这似乎工作得很好,但是减速物体永远不会到达目的地,在经过的时间大约99%的距离时,时间变得大于总持续时间,导致加速度变为负值。换句话说,它似乎已经过快减速约1%。

原始加速度完美,线速度也是如此。这只是减速无法正常工作。

我做错了吗?

由于

2 个答案:

答案 0 :(得分:1)

您可以尝试将C#Clamp函数用于浮点数:http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.mathhelper.clamp.aspx

acceleration = MathHelper.Clamp(2.0f - this.elapsed/(this.duration/2.0f), 0.0, 2.0);

它只是设置第一个参数的最小值和最大值。

答案 1 :(得分:1)

在没有看到完整代码的情况下,我认为问题可能是由于float在某个for循环中使用float作为迭代变量。

使用以下程序作为示例,当我尝试直接使用float duration = 10f; for(float elapsed = 0.0f; elapsed <= duration; elapsed = elapsed + 0.1f) { Console.WriteLine(2.0f - elapsed / (duration / 2.0f)); } Console.ReadLine(); 作为我的迭代变量时,我能够复制浮点精度在循环中的某处被搞砸了。

2
1.98
1.96
1.94
1.92
1.9
1.88
1.86
1.84
1.82
1.8
1.78
1.76
1.74
1.72
1.7
1.68
1.66
1.64
1.62
1.6
1.58
1.56
1.54
1.52
1.5
1.48
1.46
1.44
1.42
1.4
1.38
1.36
1.34
1.32
1.3
1.28
1.26
1.24
1.22
1.2
1.18
1.16
1.14
1.12
1.1
1.08
1.06
1.04
1.02
1
0.9800005
0.9600005
0.9400005
0.9200006
0.9000006
0.8800006
0.8600006
0.8400006
0.8200006
0.8000007
0.7800007
0.7600007
0.7400007
0.7200007
0.7000008
0.6800008
0.6600008
0.6400008
0.6200008
0.6000009
0.5800009
0.5600009
0.5400009
0.5200009
0.500001
0.480001
0.460001
0.440001
0.420001
0.400001
0.3800011
0.360001
0.3400009
0.3200008
0.3000008
0.2800007
0.2600006
0.2400005
0.2200005
0.2000004
0.1800003
0.1600002
0.1400001
0.1200001
0.1
0.07999992
0.05999985
0.03999977
0.01999969

该程序的输出是:

integer

你可以看到大约精确射击的一半,这是因为迭代变量本身的精度被搞砸了。

在第二个例子中,我使用integer代替迭代变量,我只是将float duration = 10f; float offset_scale = 10.0f; for (int elapsed = 0; elapsed <= (duration * offset_scale); elapsed++) { Console.WriteLine(2.0f - (elapsed / offset_scale) / (duration / 2.0f)); } Console.ReadLine(); 缩放到我每次迭代内的计算中。这可以防止迭代变量变得棘手:

2
1.98
1.96
1.94
1.92
1.9
1.88
1.86
1.84
1.82
1.8
1.78
1.76
1.74
1.72
1.7
1.68
1.66
1.64
1.62
1.6
1.58
1.56
1.54
1.52
1.5
1.48
1.46
1.44
1.42
1.4
1.38
1.36
1.34
1.32
1.3
1.28
1.26
1.24
1.22
1.2
1.18
1.16
1.14
1.12
1.1
1.08
1.06
1.04
1.02
1
0.98
0.96
0.94
0.92
0.9
0.88
0.86
0.84
0.82
0.8
0.78
0.76
0.74
0.72
0.7
0.68
0.66
0.64
0.62
0.6
0.58
0.56
0.54
0.52
0.5
0.48
0.46
0.44
0.42
0.4
0.38
0.36
0.34
0.32
0.3
0.28
0.26
0.24
0.22
0.2
0.18
0.16
0.14
0.12
0.1
0.08
0.06
0.04
0.02
0

该程序的输出是:

{{1}}

你可以看到精确度永远不会发疯,结果会在0结束。