- PR -

画像の中心を支点に回転させるには?

投稿者投稿内容
fuzuki
常連さん
会議室デビュー日: 2003/08/23
投稿数: 48
投稿日時: 2003-08-30 19:39

引用:

これでは基本的にはうまくいかないはずです。但し、たまたま
   回転の中心 = (50, 50)
である場合だけ、例外的にうまくいきますが。



af.setToTranslation(50.0d, 50.0d);
この、(50,50)というポイントは実際には変数になって、指定した場所に任意の角度で回転させた画像を描画するのが目的です。ですから、回転の中心は常にここで指定した値になるのでうまくいっているのだと思います。

引用:

rotate(<回転角>, <回転の中心のx座標>, <回転の中心のy座標>)
の形式でrotateメソッドを呼び出すのなら、setToTranslationメソッドの呼び出しは不要です。



これですと、指定したX,Y座標に画像が移動してから、画像の左上が支点となって回転することになりませんか??実際に試したのですが、なぜか予想と違って、あらぬところに画像が表示されましたが・・・

引用:

それから、細かいことで申し訳ないですが「画像の中心の幅」という言い方は変ですよね。



変ですね。確かに。Javaの前に日本語を勉強しなおしてきます(^^;

引用:

ところで、(50, 50)ってどういう座標なんでしょうか?



これは、上で言ったとおり単なる例としてこの点を指定しているだけです。混乱させてしまってすみません。
それにしても、単に回転させるだけなのにとても難しいですね。色々試しているのですが、私の以前の投稿以外の方法ではうまくいっていません。
ocean
ベテラン
会議室デビュー日: 2003/07/06
投稿数: 65
投稿日時: 2003-08-30 21:59
引用:

実際に試したのですが、なぜか予想と違って、あらぬところに画像が表示されましたが・・・



もしかして、(50, 50)というのはフレームの左上端を原点にした座標ではないですか?もしそうなら、デフォルトのGraphics2Dの座標系ではそのコンポーネントの左上端が原点なので、ずれているのではないでしょうか。

#たーぞーさんのおっしゃっているのも、こういう意味だと思います。


[ メッセージ編集済み 編集者: ocean 編集日時 2003-08-30 22:01 ]
fuzuki
常連さん
会議室デビュー日: 2003/08/23
投稿数: 48
投稿日時: 2003-08-31 00:36
引用:

もしかして、(50, 50)というのはフレームの左上端を原点にした座標ではないですか?もしそうなら、デフォルトのGraphics2Dの座標系ではそのコンポーネントの左上端が原点なので、ずれているのではないでしょうか。



はい。実は実際のプログラムの中では、JPanelを用意し、そこにイメージを描くようにしています。ここで指定している(50,50)の座標はこのパネルの中の座標です。
ただ、そうだとしても、たーぞうさんのおっしゃるやり方だと、やはり画像の中心を支点にしては回転しないのではないでしょうか。
それに、私が以前に投稿したような

af.setToTranslation(50.0d - <画像の半分の幅>, 50.0d - <画像の半分の高さ>);
af.rotate(45 * Math.PI/180, <画像の半分の幅>, <画像の半分の高さ>);

という方法で正常な位置に描写されるのが(自分でやっておいてなんですが)どうも理解できません。(ここでは通常のGraphicsを使って同時に同じ座標にイメージを描くことによって、指定したパネル上の座標通りに描かれているかどうかを判断をしています)

あと、回転したイメージを描くのに通常はgetGraphicsを使ってボタンが押された時に描写するようにしているのですが、ウィンドウサイズが変更されたときのためにpaintComponent(Graphics g)メソッドを使って自動的に再描写するようにしています。
ここでGraphics2Dを使って回転させたイメージを表示させようとすると、同じ座標を指定しているにもかかわらず、paintComponentとgetGraphicsの時とでは位置がずれてしまっていました。getGraphicsを使用している時の画像の表示位置はパネルの中の指定座標通りなのですが、paintComponentを使った時のほうはウィンドウを広げても狭めてもある一定の場所にしか表示されず、ウィンドウのサイズには従ってくれませんでした。
一応、どちらの場合も同じGraphics2Dの処理を使用して描いているのですが、これはoceanさんのおっしゃっていることも関係してきているのではないかと考えています。
ocean
ベテラン
会議室デビュー日: 2003/07/06
投稿数: 65
投稿日時: 2003-08-31 00:56
このスレッドでも書いたのですが、setTransform()は既存の変換(たぶん、デフォルトでは原点の平行移動)を上書きしてしまうので、transform()またはGraphics2D#rorate()を使うことでうまくいくと思います。

#追記

protected void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;

g2.rotate(Math.PI, _image.getWidth(null) / 2, _image.getHeight(null) / 2);

g2.drawImage(_image, 0, 0, null);
}

といったコードで、反転することを確認しました。ただ、スクロールが激しく重くなりましたが・・・



[ メッセージ編集済み 編集者: ocean 編集日時 2003-08-31 01:50 ]
fuzuki
常連さん
会議室デビュー日: 2003/08/23
投稿数: 48
投稿日時: 2003-08-31 21:08
oceanさんのおっしゃる通り、transformを使うことでうまく動作するようになりました。前回書いたgetGraphicsとpaintComponentの座標の違いもこれで解消されました。
具体的には以下のような感じでやりました。

Graphics2D g2 = (Graphics2D)g;
AffineTransform af = new AffineTransform();
af.setToTranslation(x - <画像の半分の幅>, y - <画像の半分の高さ>);
g2.transform(af);
g2.rotate(degrees * Math.PI/180, <画像の半分の幅>, <画像の半分の高さ>);
g2.drawImage(image, 0, 0, this);

みなさん、どうもありがとうございました。

スキルアップ/キャリアアップ(JOB@IT)