-2

このプロセスを使用して、wpfのコーナーとして4つの境界線の長方形を回転します。

    'find the center
    Dim center As New Point(((topRight.Margin.Left - topLeft.Margin.Left) / 2) + topLeft.Margin.Left,
                            ((topLeft.Margin.Top - bottomLeft.Margin.Top) / 2) + bottomLeft.Margin.Top)

    'shift the points to center and calculate the rotation
    Dim tl As Point = getRotatedPoint(New Point(topLeft.Margin.Left - center.X,
                                                topLeft.Margin.Top - center.Y), 1)
    Dim tr As Point = getRotatedPoint(New Point(topRight.Margin.Left - center.X,
                                                topRight.Margin.Top - center.Y), 1)
    Dim bl As Point = getRotatedPoint(New Point(bottomLeft.Margin.Left - center.X,
                                                bottomLeft.Margin.Top - center.Y), 1)
    Dim br As Point = getRotatedPoint(New Point(bottomRight.Margin.Left - center.X,
                                                bottomRight.Margin.Top - center.Y), 1)

    'shift the points back from center and move
    topLeft.Margin = New Thickness(tl.X + center.X, tl.Y + center.Y, 0, 0)
    topRight.Margin = New Thickness(tr.X + center.X, tr.Y + center.Y, 0, 0)
    bottomLeft.Margin = New Thickness(bl.X + center.X, bl.Y + center.Y, 0, 0)
    bottomRight.Margin = New Thickness(br.X + center.X, +br.Y + center.Y, 0, 0)

getRotatedPoint関数は次のとおりです。

'rotating the borders
Private Function getRotatedPoint(ByVal pnt As Point, ByVal degrees As Double)
    Dim rAngle As Double = degrees * (Math.PI / 180)
    Dim x As Double = pnt.X * Math.Cos(rAngle) - pnt.Y * Math.Sin(rAngle)
    Dim y As Double = pnt.X * Math.Sin(rAngle) + pnt.Y * Math.Cos(rAngle)
    Return New Point(x, y)
End Function

しかし、私は非常に厄介な結果を得ます、私は知りません、どんな考えも歓迎されます:)

edit1:getRotatedPoint関数をdoubleに変更し、ラジアンから度への変換を追加しました。

edit2:ラジアン変換関数を修正しました。

edit3:中心座標を修正しましたが、それでもオフセットが発生します。

edit4:テスター向けのサンプルプロジェクトは次のとおりです: http ://dl.dropbox.com/u/33417300/testapp.zip

4

1 に答える 1

2

前述のように、「乱雑な結果」が何を意味するのかが不明確であるため、いくつかの解釈が思い浮かびます。

回転が正しくない場合は、角度を度単位で渡している可能性がありますが、SIN関数とCOS関数はラジアンを期待しています。これは、浮動小数点表現ではなく整数として角度を渡しているためと思われます。それらを度として渡したい場合は、三角関数に渡す前にラジアンに変換してください。

次に、乱雑な結果によってコードが複雑であることを意味する場合は、アフィン変換を行列として表現することをお勧めします。2次元の場合、3番目の要素として1を追加することにより、2次元ベクトルを3次元に拡張します。変換は3x3の行列であり、これらを乗算して、回転、スケーリング、スキュー、平行移動などのシーケンスを作成できます。結果の変換は、ベクトル(行列の乗算)として適用できます。

アップデート:

この関数にはいくつかの問題があります。

Private Function getRotatedPoint(ByVal pnt As Point, ByVal angle As Integer)
    Dim x As Integer = pnt.X * Math.Cos(angle) - pnt.Y * Math.Sin(angle)
    Dim y As Integer = pnt.X * Math.Sin(angle) + pnt.Y * Math.Cos(angle)
    Return New Point(x, y)
End Function

度/ラジアンの混乱の問題に加えて、整数と浮動小数点の間の型変換はコンパイラと.Net Frameworkに任されており、意図と一致しない可能性があります。私は次のように書き直します:

Private Function getRotatedPoint(ByVal pnt As Point, ByVal radians As Double)
    Dim x As Double = CDbl(pnt.X) * Math.Cos(radians) - CDbl(pnt.Y) * Math.Sin(radians)
    Dim y As Double = CDbl(pnt.X) * Math.Sin(radians) + CDbl(pnt.Y) * Math.Cos(radians)
    Return New Point(CInt(x), CInt(y))
End Function

ただし、これを行うには、マトリックスライブラリを使用することをお勧めします。これにより、何度も書き込まれたり書き直されたりしたものをデバッグしたりトラブルシューティングしたりするのではなく、プログラムのコア機能の開発に集中できます。

アップデート2:

これも問題があります。

Dim center As New Point((topLeft.Margin.Left + topRight.Margin.Left) / 2,
                            (topLeft.Margin.Left + bottomLeft.Margin.Left) / 2)

代わりにこれを行うべきではありません:

Dim center As New Point((topLeft.Margin.Left + topRight.Margin.Right) / 2,
                            (topLeft.Margin.Top + bottomLeft.Margin.Bottom) / 2)

私が間違っている場合は、topLeft、topRight、bottomLeft、bottomRightの値が、誰もがあなたを助けるのに十分な詳細を表していることを説明する必要があります...SSCCEに関するKendallFreyのコメントを参照してください。

于 2012-06-25T16:41:44.807 に答える