Python 我的对齐网格代码有什么问题?

Python 我的对齐网格代码有什么问题?,python,graphics,grid,Python,Graphics,Grid,首先,我相当确定捕捉到网格是相当容易的,但是在这种情况下我遇到了一些奇怪的问题,我的数学太弱了,无法明确指出哪里出了问题 情况是这样的 我有一个网格的抽象概念,Y步与Y_步完全分开(x步工作正常,所以暂时忽略它们) 网格是在一个抽象的坐标空间中,为了使物体对齐,我在那里有一个神奇的偏移量,我们称之为Y_偏移量 为了捕捉到网格,我有以下代码(python) 所以我将光标位置、Y_偏移量和Y_步长传递到该函数中,它返回网格上最近的楼层Y位置 在最初的场景中,这似乎工作得很好,但是当我考虑到视图是可滚

首先,我相当确定捕捉到网格是相当容易的,但是在这种情况下我遇到了一些奇怪的问题,我的数学太弱了,无法明确指出哪里出了问题

情况是这样的

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

网格是在一个抽象的坐标空间中,为了使物体对齐,我在那里有一个神奇的偏移量,我们称之为Y_偏移量

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

所以我将光标位置、Y_偏移量和Y_步长传递到该函数中,它返回网格上最近的楼层Y位置

在最初的场景中,这似乎工作得很好,但是当我考虑到视图是可滚动的这一事实时,事情变得有点奇怪

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

下面是光标mouseMotion代码的一个片段:

def mouseMotion(self, event):
    pixelPos = event.pos[Y]
    odePos = Scroll.pixelPosToOdePos(pixelPos)
    self.tool.positionChanged(odePos)
所以这里有两件事情要看,首先是滚动模块从像素位置到抽象坐标空间的转换,然后是工具的位置更改功能,它获取抽象坐标空间值并捕捉到最近的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)
最后一个相关的区块是工具开始渲染自身时。它通过滚动对象,将工具的捕捉坐标空间位置转换为屏幕上的像素位置,代码如下:

#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)
哇,这解释太长了。希望你仍然和我在一起

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

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


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

您是否在positionChanged()中有输入错误

我猜由于浮点除法中的精度问题,您的偏移量为1像素。尝试将snapToGrid()更改为:


谢谢你的回答,可能有输入错误,但我看不出来

不幸的是,对snapToGrid的更改并没有带来什么不同,所以我认为这不是问题所在


它不是以一个像素为单位,而是以Y_步为单位。再仔细研究一下,我发现我无法精确地确定屏幕是否向上滚动,并且它是否发生在屏幕顶部,我怀疑这是ODE位置零,所以我猜我的问题是关于小值或负值。

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

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

抱歉,原来的问题没有包含足够的信息,无法真正找出问题所在。当时我没有额外的信息

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

关于打字错误,您正在将
originalPos
而不是
newPos
传递到
snapToGrid()
。至于负值,这可能与int(-1.5)=-1有关吗?很高兴你修复了它。仅供参考,您不必每次更新都创建新帖子,您只需编辑原始问题即可。
#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)
def positionChanged(self, newPos):
    self.snappedPos = snapToGrid(newPos, Y_OFFSET, Y_STEP)
def snapToGrid(originalPos, offset, step):
    EPS = 1e-6
    index = int((originalPos - offset) / step  + EPS) #truncates the remainder away
    return index * gap + offset