我对网格代码的捕捉出了什么问题?

时间:2020-03-06 14:34:31  来源:igfitidea点击:

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

这是情况

我有一个网格的抽象概念,其中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位置

在原始场景中,这似乎很好用,但是当我考虑到视图是可滚动的事实时,事情就变得有些奇怪了。

滚动是我获得的最基本的东西,我有一个viewPort,它可以保持沿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,并且总是捕捉到有效的网格位置。

我能想到的最好猜测是,我在某个地方将某些数据截断了,但是却不知道它在哪里或者如何以这种方式结束。

有人熟悉坐标空间,滚动和捕捉吗?

解决方案

我们在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

感谢回答,可能有错字,但我看不到...

不幸的是,对snapToGrid的更改没有任何改变,所以我认为这不是问题。

它没有偏移一个像素,而是由Y_STEP偏移了。进行更多的操作后,我发现在屏幕向上滚动的任何时候都无法准确显示它,而且它也恰好朝着屏幕顶部发生,我怀疑它的ODE位置为零,所以我猜我的问题出在小值或者负值附近。

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

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

抱歉,最初的问题没有足够的信息来真正解决问题所在。那时我还没有更多的信息。

关于拼写错误,我想我可能会以一种混乱的方式使用上下文...从positionChanged()函数的角度来看,参数是一个新的位置。
从snapToGrid()函数的角度来看,该参数是原始位置,该位置将更改为捕捉位置。
之所以说这种语言,是因为它的一部分在我的事件处理代码中,而另一部分在我的常规服务代码中。我应该为示例更改它