Прежде всего, я уверен, что привязка к сетке довольно проста, однако я столкнулся с некоторыми странными проблемами в этой ситуации, и моя математика слишком слаба, чтобы понять, что именно не так.
Вот ситуация
У меня есть абстрактное представление о сетке, с шагом 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)
Уфф, это было длинное объяснение. Надеюсь, ты все еще со мной ...
Проблема, которую я сейчас получаю, заключается в том, что при прокрутке вверх нарисованное изображение теряет выравнивание с курсором.
Он начинает привязываться к шагу Y ровно на 1 шаг ниже курсора.
Кроме того, он, похоже, постепенно вступает в союз.
На некоторых свитках он отсутствует на 1, а на других - на месте.
Он никогда не выходит больше чем на 1 и всегда привязывается к правильному расположению сетки.
Лучшее предположение, которое я могу придумать, это то, что где-то я обрезаю некоторые данные в неправильном месте, но не знаю, где и как это заканчивается таким поведением.
Кто-нибудь знаком с координатными пространствами, прокруткой и привязкой?