泥庭

2013年5月23日

マルチタッチで拡大縮小・回転・移動 その2

Filed under: .NET, ストアアプリ, Windows8 — タグ: , , — yone64 @ 12:25 AM

前々回の続き。

さてさて、中心点を変えた場合になぜオブジェクトがワープするかというと、下図参照。

image

中央の赤四角を、左上の点で2倍に拡大したものがオレンジの四角です。この拡大の中心を右下の点に移動させると拡大後の四角は緑色のものになります。なので、中心点を移動させた場合、それと同じ方向に(拡大倍率ー1)倍移動させ補正する必要があります。

private void Rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var transform = ((UIElement)sender).RenderTransform as CompositeTransform;
    var diffX = e.Position.X - transform.CenterX;
    var diffY = e.Position.Y - transform.CenterY;

    transform.CenterX = e.Position.X;
    transform.CenterY = e.Position.Y;

    transform.TranslateX += e.Delta.Translation.X + diffX * (transform.ScaleX - 1);
    transform.TranslateY += e.Delta.Translation.Y + diffY * (transform.ScaleY - 1);

    transform.ScaleX *= e.Delta.Scale;
    transform.ScaleY *= e.Delta.Scale;

    transform.Rotation += e.Delta.Rotation;
}

とりあえず、これで拡大時の補正が終了です。同様に回転時の補正もする必要があります。

image

拡大縮小時と同様、中心を左上から右下に移動したケースです。今度はちょっと複雑ですが、中心の移動線の角度+回転角だけ回転させた座標と中心の移動船の角度の座標の差分を補正する必要がでます。

private void Rectangle_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
    var transform = ((UIElement)sender).RenderTransform as CompositeTransform;
    var diffX = e.Position.X - transform.CenterX;
    var diffY = e.Position.Y - transform.CenterY;

    var rad = Math.Atan2(diffY, diffX);
    var d = rad + transform.Rotation * Math.PI / 180;
    var dist = Math.Sqrt(diffX * diffX + diffY * diffY);
    var newX = dist * Math.Cos(d);
    var newY = dist * Math.Sin(d);

    transform.CenterX = e.Position.X;
    transform.CenterY = e.Position.Y;

    transform.ScaleX *= e.Delta.Scale;
    transform.ScaleY *= e.Delta.Scale;

    transform.Rotation += e.Delta.Rotation;

    transform.TranslateX += e.Delta.Translation.X + diffX * (transform.ScaleX - 1) - (diffX - newX) * transform.ScaleX;
    transform.TranslateY += e.Delta.Translation.Y + diffY * (transform.ScaleY - 1) - (diffY - newY) * transform.ScaleY;
}

結果、こんな感じになりました。これでワープしなくなります。ちなみに最後の2行はまとめてもう少し短くなります。

transform.TranslateX += e.Delta.Translation.X - diffX + newX * transform.ScaleX;
transform.TranslateY += e.Delta.Translation.Y - diffY + newY * transform.ScaleY;

#三角関数計算はもう少し簡単になったりするのかな?

広告

1件のコメント »

  1. […] 前回と前々回の続き。 […]

    ピンバック by マルチタッチで拡大縮小・回転・移動 その3 | 泥庭 — 2013年5月26日 @ 8:44 PM


RSS feed for comments on this post. TrackBack URI

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

WordPress.com Blog.

%d人のブロガーが「いいね」をつけました。