내 스냅 투 그리드 코드에 어떤 문제가 있나요?
문제
우선, 그리드에 스냅하는 것이 매우 쉽다고 확신합니다. 하지만 이 상황에서 이상한 문제에 부딪혔고 수학 능력이 너무 약해서 무엇이 잘못되었는지 구체적으로 알아낼 수 없습니다.
상황은 이렇습니다
나는 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인 것으로 의심됩니다. 내 문제는 작거나 음수 값에 관한 것 같아요.