0

首先,我很确定捕捉到网格相当容易,但是在这种情况下我遇到了一些奇怪的麻烦,而且我的数学太弱,无法具体找出问题所在。

这是情况

我有一个网格的抽象概念,Y 步完全分开 Y_STEP(x 步工作正常,所以暂时忽略它们)

网格在一个抽象的坐标空间中,为了让东西对齐,我在里面有一个神奇的偏移量,我们称之为 Y_OFFSET

捕捉到网格我有以下代码(python)

def snapToGrid(originalPos, offset, step):
    index = int((originalPos - offset) / step) #truncates the remainder away
    return index * gap + offset

所以我将光标位置、Y_OFFSET 和 Y_STEP 传递给该函数,它返回网格上最近的地板 y 位置

这在原始场景中似乎工作正常,但是当我考虑到视图是可滚动的事实时,事情变得有点奇怪。

滚动是尽可能基本的,我有一个视口,可以计算沿 Y 轴滚动的距离,并抵消通过它的所有内容。

这是光标的 mouseMotion 代码片段:

def mouseMotion(self, event):
    pixelPos = event.pos[Y]
    odePos = Scroll.pixelPosToOdePos(pixelPos)
    self.tool.positionChanged(odePos)

所以这里有两件事要看,首先是 Scroll 模块从像素位置到抽象坐标空间的转换,然后是工具的 positionChanged 函数,它获取抽象坐标空间值并捕捉到最近的 Y 步长。

这是相关的滚动代码

def pixelPosToOdePos(pixelPos):
    offsetPixelPos = pixelPos - self.viewPortOffset
    return pixelsToOde(offsetPixelPos)

def pixelsToOde(pixels):
    return float(pixels) / float(pixels_in_an_ode_unit)

工具更新代码

def positionChanged(self, newPos):
    self.snappedPos = snapToGrid(originalPos, Y_OFFSET, Y_STEP)

最后一个相关的块是工具去渲染自己的时候。它通过 Scroll 对象,该对象将工具的捕捉坐标空间位置转换为屏幕上的像素位置,代码如下:

#in Tool
def render(self, screen):
    Scroll.render(screen, self.image, self.snappedPos)

#in Scroll
def render(self, screen, image, odePos):
    pixelPos = self.odePosToPixelPos(odePos)
    screen.blit(image, pixelPos) # screen is a surface from pygame for the curious

def odePosToPixelPos(self.odePos):
    offsetPos = odePos + self.viewPortOffset
    return odeToPixels(offsetPos)

def odeToPixels(odeUnits):
    return int(odeUnits * pixels_in_an_ode_unit)

唷,这是一个很长的解释。希望你还在我身边...

我现在遇到的问题是,当我向上滚动时,绘制的图像会与光标失去对齐。
它开始捕捉到光标下方恰好 1 步的 Y 步。此外,它似乎逐步进入和退出联盟。
在某些卷轴上它是 1,而在其他卷轴上它是正确的。
它永远不会超过 1,并且总是捕捉到有效的网格位置。

我能想到的最好的猜测是,我在错误的地方截断了一些数据,但不知道它在哪里或如何以这种行为结束。

任何熟悉坐标空间、滚动和捕捉的人?

4

3 回答 3

1

好的,正如 alexk 提到的,我在这里回答我自己的问题,使用 int 截断是我的错误。

我所追求的行为最好由 math.floor() 建模。

抱歉,最初的问题没有包含足够的信息来真正解决问题所在。那时我没有额外的信息。

关于打字错误,我想我可能会以一种令人困惑的方式使用上下文......从 positionChanged() 函数的角度来看,参数是一个新的位置。
从 snapToGrid() 函数的角度来看该参数是正在更改为捕捉位置的原始位置。语言就是这样,因为它的一部分在我的事件处理代码中,另一部分在我的通用服务代码中。我应该为示例更改它

于 2008-09-23T03:56:48.403 回答
0

你在 positionChanged() 中有错字吗?

def positionChanged(self, newPos):
    self.snappedPos = snapToGrid(newPos, Y_OFFSET, Y_STEP)

我猜你是因为浮点除法的准确性问题而偏离了一个像素。尝试将您的 snapToGrid() 更改为:

def snapToGrid(originalPos, offset, step):
    EPS = 1e-6
    index = int((originalPos - offset) / step  + EPS) #truncates the remainder away
    return index * gap + offset
于 2008-09-23T01:33:59.197 回答
0

谢谢解答,可能有错别字,但我看不到...

不幸的是,对 snapToGrid 的更改并没有产生任何影响,所以我认为这不是问题所在。

它不是偏离一个像素,而是偏离 Y_STEP。再玩一些,我发现在屏幕向上滚动的任何时候我都无法让它准确,而且它发生在屏幕顶部,我怀疑这是 ODE 位置为零,所以我猜我的问题是围绕小值或负值。

于 2008-09-23T02:54:08.240 回答