Что не так с моей привязкой к коду сетки? - PullRequest
0 голосов
/ 23 сентября 2008

Прежде всего, я уверен, что привязка к сетке довольно проста, однако я столкнулся с некоторыми странными проблемами в этой ситуации, и моя математика слишком слаба, чтобы понять, что именно не так.

Вот ситуация

У меня есть абстрактное представление о сетке, с шагом 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 и всегда привязывается к правильному расположению сетки.

Лучшее предположение, которое я могу придумать, это то, что где-то я обрезаю некоторые данные в неправильном месте, но не знаю, где и как это заканчивается таким поведением.

Кто-нибудь знаком с координатными пространствами, прокруткой и привязкой?

Ответы [ 3 ]

1 голос
/ 23 сентября 2008

Хорошо, я отвечаю на свой вопрос здесь, как упомянул Алекс, использование int для усечения было моей ошибкой.

Поведение, за которым я следую, лучше всего моделируется math.floor ().

Извинения, оригинальный вопрос не содержит достаточно информации, чтобы действительно решить, в чем проблема. На тот момент у меня не было лишней информации.

Что касается примечания к опечатке, я думаю, что я могу использовать контекст в замешательстве ... С точки зрения функции positionChanged (), параметр представляет собой новую позицию. С точки зрения функции snapToGrid () параметр представляет собой исходную позицию, которая изменяется на привязанную позицию. Язык таков, потому что его часть находится в моем коде обработки событий, а другая часть - в моем коде общих служб. Я должен был изменить это для примера

0 голосов
/ 23 сентября 2008

Спасибо за ответ, возможна опечатка, но я ее не вижу ...

К сожалению, изменение snapToGrid не имело значения, поэтому я не думаю, что это проблема.

Это не на один пиксель, а на Y_STEP. Поэкспериментируя с этим, я обнаружил, что не могу получить точную информацию в любой момент, когда экран прокручивается вверх, а также что это происходит в верхней части экрана, что, как я подозреваю, является нулевой позицией ODE, поэтому Я предполагаю, что моя проблема заключается в небольших или отрицательных значениях.

0 голосов
/ 23 сентября 2008

У вас есть опечатка в 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
...