5

ズームとパンが可能で、コンパスの読みで回転する画像を表示しようとしています。以下のコードでは、3 つのアクションはすべて機能しますが、互いに影響を及ぼします。

私が達成したいことは次のとおり
です。 1.画面の中心を中心に回転します
2.画像の同じ部分を中央に残して拡大縮小し
ます 3.画像内の目的の場所にパンします

以下のコードで実際に何が起こっているかを次に示します
。 1. 回転は意図したとおりに機能し、画面の中心を中心に機能します
2. スケーリングは機能しますが、画像の中心を中心に
拡大縮小します 3. 平行移動angleは がゼロの場合にのみ意図したとおりに機能し、それ以外の場合は機能しますそれは間違った方向に進んでいる

// the center of the view port
float centerX = screen.right/2;
float centerY = screen.bottom/2;

Matrix m = new Matrix();
m.preRotate(angle, centerX, centerY);
m.preScale(mScaleFactor, mScaleFactor, centerX, centerY);

// scaling the amount of translation, 
// rotating the translation here gave crazy results
float x = mPosX / mScaleFactor;
float y = mPosY / mScaleFactor;
m.preTranslate(x, y);

canvas.drawBitmap(pic, m, null);

最初に移動し、後で回転すると、移動は意図したとおりに機能しますが、回転はビューポートの中心を中心としていません。

相互に影響を与えることなく、3 つの変換すべてを適用するにはどうすればよいでしょうか?

4

1 に答える 1

1

画像の中心付近のスケーリングについてはわかりませんが、翻訳が間違った方向にあるのは、画像を回転させた結果ではなく、翻訳ではありませんか? たぶん、次のようなことを試してください:

float x = (mPosX*(cos(angle) + sin(angle)) / mScaleFactor;
float y = (mPosY*(cos(angle) - sin(angle)) / mScaleFactor;
m.preTranslate(x, y);

また、行列オブジェクトにはアフィン変換を直接適用するメソッドがありますか? そうすれば、操作の順序を考える必要がなくなるからです。

アフィン変換は次のようになります。

M = |mScaleFactor*cos(angle)       sin(angle)            x|
    |     -sin(angle)          mScaleFactor*cos(angle)   y|
    |          0                         0               1|

ただし、これは画像の角を中心に回転するため、最初に preTranslate() 関数を次のように使用する必要があります。

Mt.preTranslate(-centerX,-centerY);

そして、Mを適用する前にMtをpicに適用し、次に-Mtを適用する必要があります

于 2012-05-04T09:38:28.007 に答える