문제

우선, 그리드에 스냅하는 것이 매우 쉽다고 확신합니다. 하지만 이 상황에서 이상한 문제에 부딪혔고 수학 능력이 너무 약해서 무엇이 잘못되었는지 구체적으로 알아낼 수 없습니다.

상황은 이렇습니다

나는 Y 단계가 정확히 Y_STEP 떨어져 있는 그리드에 대한 추상적 개념을 가지고 있습니다. (x 단계는 잘 작동하므로 지금은 무시하십시오.)

그리드는 추상 좌표 공간에 있고 일렬로 정렬하기 위해 거기에 마법 오프셋이 있습니다. Y_OFFSET이라고 부르겠습니다.

그리드에 스냅하려면 다음 코드가 있습니다 (파이썬)

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

그래서 커서 위치인 Y_OFFSET과 Y_STEP을 해당 함수에 전달하면 그리드에서 가장 가까운 바닥 y 위치가 반환됩니다.

원래 시나리오에서는 제대로 작동하는 것처럼 보이지만 뷰가 스크롤 가능하다는 사실을 고려하면 상황이 조금 이상해집니다.

스크롤링은 가능한 한 기본적으로 만들어졌습니다. Y축을 따라 스크롤된 거리를 계산하고 이를 통과하는 모든 것을 오프셋하는 viewPort가 있습니다.

다음은 커서의 mouseMotion 코드 조각입니다.

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

따라서 거기에서 살펴봐야 할 두 가지가 있습니다. 먼저 픽셀 위치에서 추상 좌표 공간으로의 스크롤 모듈의 변환과 추상 좌표 공간 값을 가져와 가장 가까운 Y 단계로 스냅하는 도구의 positionChanged 함수입니다.

관련 스크롤 코드는 다음과 같습니다.

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 이상 벗어나지 않으며 항상 유효한 그리드 위치에 맞춰집니다.

내가 생각해 낼 수 있는 가장 좋은 추측은 잘못된 위치에서 일부 데이터를 잘라내고 있지만 이것이 어디서 어떻게 이런 동작으로 끝나는지 전혀 모른다는 것입니다.

좌표 공간, 스크롤 및 스냅에 익숙한 사람이 있습니까?

도움이 되었습니까?

해결책

좋아, Alexk가 언급했듯이 여기에 내 자신의 질문에 대답하고 있습니다. int를 사용하여 잘라내는 것은 내 실수였습니다.

내가 추구하는 행동은 math.floor()에 의해 가장 잘 모델링되었습니다.

죄송합니다. 원래 질문에는 문제가 무엇인지 실제로 해결하기에 충분한 정보가 포함되어 있지 않습니다.그 시점에는 추가 정보가 없었습니다.

오타 메모와 관련하여 문맥을 혼란스럽게 사용하고 있는 것 같습니다...positionChanged() 함수의 관점에서 보면 매개변수는 들어오는 새로운 위치입니다.
snapToGrid() 함수의 관점에서 보면 매개변수는 스냅된 위치로 변경되는 원래 위치입니다.일부는 내 이벤트 처리 코드에 있고 다른 부분은 내 일반 서비스 코드에 있기 때문에 언어가 이와 같습니다.예를 들어 바꿨어야 했는데

다른 팁

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를 변경해도 아무런 변화가 없었으므로 그게 문제가 아니라고 생각합니다.

1픽셀 어긋난 게 아니라 Y_STEP만큼 어긋난 거죠.좀 더 가지고 놀면서 화면이 위로 스크롤되는 어느 지점에서나 그것이 화면 상단을 향해 발생한다는 것을 정확히 알 수 없다는 것을 발견했습니다. 이는 ODE 위치 0인 것으로 의심됩니다. 내 문제는 작거나 음수 값에 관한 것 같아요.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top