在碰撞检测和解决scheme中处理浮点精度错误

我正在试验连续的碰撞检测和瓦片地图上的点的响应。 这是我现在的结果:

没问题

我通过从当前位置( 红色圆圈 )到目标位置( 绿色圆圈 )拍摄射线( 红色线 ),并使用此algorithm检查其上的所有拼贴。 如果射线击中一个坚实的瓦片,我计算碰撞的确切位置( 黄色圆圈 )和一个新的目标位置取决于光线是否碰到实心瓦片在另一种情况下垂直或水平我可以简单地设置当前位置到目标位置并完成,因为没有发生碰撞。 现在我正在向这个新的目标位置拍摄第二道光线( 蓝线 ),并再次检查它上面的实心瓷砖。 如果碰撞发生,我将当前位置设置为光线点击位置( 青色圆圈 )并完成。 在另一种情况下,我只把当前位置设置到新的目标位置( 青色圆圈 ),因为这次没有发生碰撞。

这里最重要的源代码:

void update(float start_x, float start_y, float target_x, float target_y, float *corrected_x, float *corrected_y) { float hit0_x; float hit0_y; LineTraceResult res0 = line_trace(start_x, start_y, target_x, target_y, &hit0_x, &hit0_y); switch (res0) { case LINE_TRACE_NONE: { // No collision occurred so the target position is valid and we can move to it. *corrected_x = target_x; *corrected_y = target_y; } break; case LINE_TRACE_VERT: { // We hit a solid tile on the vertical edge. *corrected_x = hit0_x; *corrected_y = target_y; float hit1_x; float hit1_y; LineTraceResult res1 = line_trace(hit0_x, hit0_y, *corrected_x, *corrected_y, &hit1_x, &hit1_y); if (res1 != LINE_TRACE_NONE) { // There was a second collision on the corrected position so we need to adjust it. // Because the x axis did not changed we don't need to change it. *corrected_y = hit1_y; } } break; case LINE_TRACE_HORI: { // We hit a solid tile on the horizontal edge. *corrected_x = target_x; *corrected_y = hit0_y; float hit1_x; float hit1_y; LineTraceResult res1 = line_trace(hit0_x, hit0_y, *corrected_x, *corrected_y, &hit1_x, &hit1_y); if (res1 != LINE_TRACE_NONE) { // There was a second collision on the corrected position so we need to adjust it. // Because the y axis did not changed we don't need to change it. *corrected_x = hit1_x; } } break; } 

所以在理论上这一切都很好,但实际上由于浮标的精确度有限而造成了很多问题。

例如在这两种情况下:
问题1
Problem2

“解决”这个问题的一个方法就是每次碰撞时都会添加一种名为Epsilon的填充,但是这种方法在我看来并不是很准确和肮脏。

所以我想知道所有的专业游戏开发者是如何解决这类问题的?

编辑:
这个问题的发生是因为由射线计算出的命中位置不能100%精确,所以可能是例如y坐标从6.9999到四舍五入,6.9999就意味着6和7.0001意味着第7块,这是一个巨大的差异。