6

快速提问。我基本上正在开发一个程序,其中我们有一个跨网格的实体。每次它完成一个“步骤”(即从 (0, 0) 到 (1, 0))时,我都需要触发一个事件。实体每帧的移动通过以下方式计算:

frameMovement = entitySpeed * (frameDeltaMs / 1000)

然后添加到实体的 X 坐标上。我选择使用世界单位(1 个世界单位是 16 像素)而不是坐标系的原始像素,只是为了分离关注点。世界不需要知道一个正方形的距离是 16 像素——只有绘图系统知道。

所以基本上,我试图弄清楚如何告诉系统该单元已经完成了一个“步骤”。显然,由于计算框架移动的方式,你永远不会完全在一个新的正方形上,所以我必须将单元“剪辑”到那个正方形,或者如果我们在一定距离内,有一个方法会返回“真”从正方形(现在我决定为 0.05wu - 距正方形约 0.8 像素)。

到目前为止我的功能是这样的:

return Math.floor(x) % x == 0;

我只使用 X 查看,因为我现在只是想让它工作。但是我遇到的问题是这个函数似乎返回两个结果之一:

x = 0f;
System.out.println(Math.floor(x) % x);
> NaN

这是意料之中的,因为 0 % 0 确实是 NaN。我可以解决这个问题。但是我目前遇到的问题是另一个结果..

x = 1f; // Or any number with 1sd > 0
System.out.println(Math.floor(x) % x);
> 1f

也就是说,另一个结果总是返回 X 的值,而不是正确的模数(如果 math.floor(x) 和 x 相等,即 x 等于 1f),它应该是 0。

我不完全确定是什么原因造成的。如果您对我有任何答案或有关如何以更好的方式解决此问题的任何建议,我会全力以赴。

TL;DR:我需要弄清楚实体何时从一个坐标移动到下一个坐标。坐标(以及实体在它们之间的转换)存储为浮点数。例如,如果一个实体穿过一个正方形的一半,则该实体的 X 坐标存储为 1.5。最后, Floor(1.0) % 1.0 返回 1.0,而不是 0。

编辑:

在我的代码中,我有这个

    System.out.println("x equals " + x + ". Math.floor(x)%x==Math.floor(x): "+(Math.floor(x)%x==Math.floor(x)));

输出http://pastebin.com/egDwj7Gs

编辑2:图像很有趣!

http://prntscr.com/1j193n

白色方块是实体。红色方块只是一个绘制的网格。每个正方形是 16 x 16。

如您所见,现在白色方块位于 (6.5, 0)。我需要程序基本识别它何时通过 (7, 0)。

编辑:李和我聊天,这是我们的聊天: https ://chat.stackoverflow.com/rooms/34727/discussion-between-neglected-and-lee-meador

他为我解决了这个问题,所以我接受他的回答是正确的。

        float after = pos.x+changeInPosition;

        if (Math.floor(after) != Math.floor(pos.x)) {
            // We passed a boundary
        }
        pos.x = after;
4

1 回答 1

4

模数意味着我们除以其余部分(就像我在三年级时一样)。

所以 ...

10 % 9 is 1.

10 % 10 is 0

10.5 % 10.5 is 0. 

(如果你有 x = ...计算 10.5.. 然后 x % x 你会得到一个略低于 10.5 或略大于 0 的数字,也许你可能会遇到舍入问题。)

因此,对于所有整数,

Floor(x) % x is 0.

对于非整数,它的工作方式不同。

Floor(10.5) => 10 

10 % 10.5 is 10.

因此,除非浮点数舍入误差的影响,Floor(x) % x 要么为 0(整数),要么为非整数的 Floor(x)。

更多的

也许您可以通过比较前后位置来判断它是否通过了网格线:

if (Math.Floor(xAfterMoving / gridSize) != Math.floor(xBeforeMoving / gridSize)) {
    fireXGridCrossingEvent();
}
于 2013-08-02T20:50:45.230 回答