0

まず第一に、グリッドへのスナップはかなり簡単だと確信していますが、この状況で奇妙な問題に遭遇し、数学が弱すぎて具体的に何が悪いのかを特定できません.

状況はこちら

私はグリッドの抽象的な概念を持っており、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 位置が返されます

元のシナリオでは問題なく動作しているように見えますが、ビューがスクロール可能であるという事実を考慮すると、少し奇妙になります。

スクロールは可能な限り基本的に行われます。Y 軸に沿ってスクロールされた距離をカウントし、それを通過するすべてのものをオフセットする viewPort があります。

カーソルの mouseMotion コードのスニペットを次に示します。

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

1 つ目は Scroll モジュールのピクセル位置から抽象座標空間への変換、次に抽象座標空間の値を取得して最も近い 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)

うーん、説明が長かった。あなたがまだ私と一緒にいることを願っています...

私が今得ている問題は、上にスクロールすると、描画された画像がカーソルとの位置合わせを失うことです。
カーソルのちょうど 1 ステップ下の Y ステップにスナップし始めます。さらに、アラインメントから段階的に出たり入ったりしているように見えます。
一部のスクロールでは 1 アウトで、他のスクロールでは問題ありません。
1 を超えることはなく、常に有効なグリッド位置にスナップしています。

私が思いつくことができる最善の推測は、どこかで間違った場所でいくつかのデータを切り捨てているということですが、どこでどのようにこの動作になるのかわかりません。

座標空間、スクロール、スナップに詳しい人はいますか?

4

3 に答える 3

1

わかりました、ここで自分の質問に答えています。alexk が述べたように、int を使用して切り捨てたのは私の間違いでした。

私が求めている動作は、math.floor() によって最もよくモデル化されています。

申し訳ありませんが、元の質問には、問題が何であるかを実際に解決するのに十分な情報が含まれていません。その時点で私は余分な情報を持っていませんでした。

タイプミスのメモに関しては、コンテキストを混乱させる方法で使用している可能性があると思います... positionChanged() 関数の観点から、パラメーターは入ってくる新しい位置です。
snapToGrid() 関数の観点からパラメータは、スナップされた位置に変更される元の位置です。言語の一部はイベント処理コードにあり、他の部分は一般的なサービス コードにあるため、言語はそのようなものです。例に合わせて変更する必要がありました

于 2008-09-23T03:56:48.403 に答える
0

答えてくれてありがとう、タイプミスがあるかもしれませんが、私はそれを見ることができません...

残念ながら、snapToGridへの変更は違いをもたらさなかったので、それが問題だとは思いません。

1ピクセルずれているのではなく、Y_STEPでずれています。もう少し遊んでみると、画面が上にスクロールされた時点で正確に把握できないことがわかりました。また、画面の上部に向かって発生していることがわかりました。これは、ODEの位置がゼロであると思われます。私の問題は小さいか負の値にあると思います。

于 2008-09-23T02:54:08.240 に答える
0

positionChanged() にタイプミスがありますか?

def positionChanged(self, newPos):
    self.snappedPos = snapToGrid(newPos, Y_OFFSET, Y_STEP)

float 除算中の精度の問題により、1 ピクセルずれていると思います。snapToGrid() を次のように変更してみてください。

def snapToGrid(originalPos, offset, step):
    EPS = 1e-6
    index = int((originalPos - offset) / step  + EPS) #truncates the remainder away
    return index * gap + offset
于 2008-09-23T01:33:59.197 に答える