13

このプログラミングゲームを参考に現在制作中です。

代替テキスト http://img12.imageshack.us/img12/2089/shapetransformationf.jpg

Canvas を WPF で変換するには、TranslateTransform(移動する) とRotateTransform(回転する) [同じの子 TransformationGroup]の 2 つのフォームを使用しています。

キャンバスが回転していない場合(または同じになるため、90度回転した場合)、キャンバスの左上のx、y座標を簡単に取得できますが、直面している問題は左上(および他の3点)を取得することです座標。

これは、 aRotateTransformが適用されても、およびプロパティが変更されないためです (したがって、正方形TranslateTransformの左上が点線の正方形のようであることを示しています (画像から))。XY

キャンバスはその中心から回転しているため、それが原点です。

では、回転後に4点の「新しい」x座標とy座標を取得するにはどうすればよいですか?

[アップデート]

代替テキスト http://img25.imageshack.us/img25/8676/shaperotationaltransfor.jpg

回転の OffsetX と OffsetY を開始 X 座標と Y 座標に追加することで、(新しい画像からわかるように) 回転後の左上の座標を見つける方法を見つけました。

しかし、残りの座標 (他の 3 つ) を把握するのに苦労しています。

この回転した形状で、残りの 3 つの角の x 座標と y 座標をどのように把握できますか?

[編集]

2 番目の画像のポイントは、正確で正確なポイントではありません。私は頭の中で見積もりをしてポイントを作りました。

[更新] 解決策:

まず第一に、プロセス全体の背後にある数学について説明した、非常に有益な長文の投稿をしてくれたJason Sに感謝したいと思います。あなたの投稿を読んで値を試すことで、確かに多くのことを学びました。

しかし、私が望むことを正確に行うコードスニペットを見つけました( EugeneZの言及のおかげですTransformBounds):

public Rect GetBounds(FrameworkElement of, FrameworkElement from)
{
    // Might throw an exception if of and from are not in the same visual tree
    GeneralTransform transform = of.TransformToVisual(from);

    return transform.TransformBounds(new Rect(0, 0, of.ActualWidth, of.ActualHeight));
} 

参照: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/86350f19-6457-470e-bde9-66e8970f7059/

4

5 に答える 5

16

私があなたの質問を正しく理解していれば:

given:
shape has corner (x1,y1), center (xc,yc)
rotated shape has corner (x1',y1') after being rotated about center

desired:
how to map any point of the shape (x,y) -> (x',y') by that same rotation

関連する方程式は次のとおりです。

(x'-xc) = Kc*(x-xc) - Ks*(y-yc)
(y'-yc) = Ks*(x-xc) + Kc*(y-yc)

ここでKc=cos(theta)Ks=sin(theta)thetaは反時計回りの回転角度です。(検証: theta=0 の場合、座標は変更されません。それ以外の場合、xc=yc=0 の場合、(1,0) を (cos(theta),sin(theta)) に、(0,1) を (- sin(theta), cos(theta)) . 警告: これは (x,y)=(1,1) が右上の象限にある座標系の場合です. 右下の象限にあるあなたの座標系の場合, theta は次のようになります.反時計回りではなく、時計回りの回転角度です。)

xy 軸に合わせた長方形の座標がわかっている場合、xc は 2 つの x 座標の平均になり、yc は 2 つの y 座標の平均になります。(あなたの状況では、xc=75,yc=85 です。)

シータがわかれば、新しい座標を計算するのに十分な情報が得られます。シータがわからない場合は、Kc、Ks を解くことができます。あなたの例に関連する計算は次のとおりです。

(62-75) = Kc*(50-75) - Ks*(50-85)
(40-85) = Ks*(50-75) + Kc*(50-85)

-13 = -25*Kc + 35*Ks = -25*Kc + 35*Ks
-45 = -25*Ks - 35*Kc = -35*Kc - 25*Ks

これは、解くことができる線形方程式のシステムです(読者のための演習: MATLAB では:

[-25 35;-35 -25]\[-13;-45]

この場合、Kc=1.027、Ks=0.3622 は意味をなしません (K 2 = Kc 2 + Ks 2は、純粋な回転では 1 に等しいと想定されています。この場合は K = 1.089 です)。長方形の中心を中心とした純粋な回転。これは、図面が示すものです。また、原点を中心とした純粋な回転ではないようです。確認するには、ピタゴラスの定理 d 2 = deltax 2 + deltay 2を使用して、回転前後の回転の中心からの距離を比較します。. (xc=75,yc=85 を中心とした回転の場合、前の距離は 43.01、後の距離は 46.84、比率は K=1.089 です。原点を中心とした回転の場合、前の距離は 70.71、後の距離は 73.78、比率は 1.043 です。I 1.01 以下の比率は、整数への座標の丸めから生じると考えられますが、これは丸め誤差よりも明らかに大きい)

そのため、ここにはいくつかの情報が不足しています。どのようにして数字 (62,40) を取得しましたか?

ただし、これはローテーションの背後にある数学の基本的な要点です。

編集:ああ、私はそれらが推定値であることを知りませんでした. (でもかなりリアルに近い!)

于 2009-02-26T15:38:40.687 に答える
8

私はこの方法を使用します:

Point newPoint = rotateTransform.Transform(new Point(oldX, oldY));

ここで、rotateTransformは、私が作業して角度を設定するインスタンスです...など。

于 2009-04-23T11:27:43.720 に答える
3

GeneralTransform.TransformBounds() メソッドを見てください。

于 2009-02-27T04:46:11.230 に答える
1

わかりませんが、これはあなたが探しているものですか - デカルト座標系での点の回転: リンク

于 2009-02-24T14:05:46.917 に答える
1

ポイントで同じ変換を使用して Transform.Transform() メソッドを使用して、これらの変換が適用された新しいポイントを取得できます。

于 2009-02-24T15:34:06.533 に答える