物理世界中的引力Vector2是(0; 0.1)。
已知数字0.1有问题,因为“它无法准确表示,但约为1.10011001100110011001101×2-4”。
拥有重力的这个值让我遇到了碰撞的问题,并产生了非常讨厌的错误。将值更改为0.11可以解决这些问题。
是否有一个更优雅的解决方案,根本不需要更改值?
http://www.youtube.com/watch?v=bRynch1EtnE
第一种方法(AABBIsOverlapping)检查两个AABB实体之间的交集。 每帧为每个主体调用第二个方法(Update)。
我将尝试解释Update方法的工作原理:
答案 0 :(得分:6)
总之没有。通常的解决方案是永远不检查相等性,并始终检查范围+ - epsilon(非常小的值)。
答案 1 :(得分:4)
物理学中无法代表数字根本不重要。在物理学中唯一重要的是舍入误差的累积。
我认为你的问题与错误的epsilon比较有关,甚至与没有epsilon的比较有关。但没有更多的信息,我无法帮助你。如果您的代码无法处理小的舍入错误,则它存在缺陷并需要修复。
您可以使用Decimal
作为数学代码,它可以完全代表0.1m
。但我不认为这是你真正需要的,因为你的问题很可能与0.1
无法在float
完全无法表示的事实无关。
我在代码中看到的一个潜在问题是,在解决碰撞时,您将身体完全移出到碰撞边界。也许你需要进一步将它移出epsilon。
答案 2 :(得分:2)
如果不可表示性导致代码中出现错误,那么您的算法在某些方面存在缺陷。很难说它们是如何存在缺陷的,因为你没有共享任何细节,但使用可表示的数字将无法修复它。
事实上0.11也不具有代表性,所以如果它能解决你的问题,那么除了这个之外,它还是出于某种原因。
答案 3 :(得分:2)
简而言之 - 您不能像在现实生活中一样使用PC上的浮点值。由于用于在非常宽的范围内存储值的内存量有限,总会出现精度损失和舍入误差。
始终检查与某些epsilon的相等性,这可能是工作值之间的一半,例如0.1:
IsEqual(0.1, 0.2, 0.05) = false
IsEqual(0.1, 0.1001, 0.05) = true
IsEqual(0.1, 0.1499, 0.05) = true
或给定比例下的最佳精度和给定的浮点格式(例如,64位的epsilon明显小于32位)(您可能需要检查您的语言以获取该值的方法):
IsEqual(0.1, 0.2, BestPrecisionAt(0.1)) = false
IsEqual(0.1, 0.1001, BestPrecisionAt(0.1)) = false
IsEqual(0.1, 0.1499, BestPrecisionAt(0.1)) = false
IsEqual(0.1, 0.1000001, BestPrecisionAt(0.1)) = true
//Where for example BestPrecisionAt(0.1) could be 0.00001
修改强> 你没有说过你遇到的错误。那么0.1的错误是什么? 我只能假设你的时间步长不够精确,你的物体速度允许它们在碰撞检查之间相互通过。那是对的吗?如果是 - 您应该提高时间步长分辨率和/或更早地检查碰撞。