- PR -

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

投稿者投稿内容
fuzuki
常連さん
会議室デビュー日: 2003/08/23
投稿数: 48
投稿日時: 2003-08-29 13:37
こんにちは。

画像を回転させて表示させたいと思っています。Grahpics2Dを使って回転させることはできたのですが、回転する時の支点を画像の中心点にすることはできますか?
以下の例の方法だと、支点が画像の左上になってしまいます。回転させてから画像のX軸とY軸を移動させて中心にもっていこうとしたのですが、このような数学的な計算は苦手で、どうもうまくいきませんでした。以下の例では45度に回転させていますが、他に、135、225、315度に回転させたいと思っています。
最初から中心を支点にして回転させる方法があれば一番良いのですが・・・何か良い方法がありましたらお願いいたします。

----------------------------
import javax.swing.*;
import java.awt.*;
import java.awt.geom.*;

/* <APPLET CODE="Test3.class" height=350 width=200></APPLET> */
public class Test3 extends JApplet
{
private Image image;
private AffineTransform trans;

public void init()
{
image = getImage(getDocumentBase(),"image.gif");
}
public void paint(Graphics g)
{
g.drawImage(image, 50, 50, this);

Graphics2D g2 = (Graphics2D) g;

AffineTransform af = new AffineTransform();
af.setToTranslation(50.0d, 50.0d);
double[] flatmatrix = new double[6];
af.getMatrix(flatmatrix);
af.rotate(45 * Math.PI/180);

g2.setTransform(af);
g2.drawImage(image, 0, 0, this);
}
}
----------------------------
ほむら
ぬし
会議室デビュー日: 2003/02/28
投稿数: 583
お住まい・勤務地: 東京都
投稿日時: 2003-08-29 16:45
ども、ほむらです。
適当なんですが。。。。
--------------------
>af.setToTranslation(50.0d, 50.0d);

af.setToTranslation(画像の横幅半分, 0.0d);

にしてみたらどうですか?
名前からしてここで回転の支点を決めているような気がするのですが

[ メッセージ編集済み 編集者: ほむら 編集日時 2003-08-29 16:46 ]
たーぞう
ぬし
会議室デビュー日: 2003/08/08
投稿数: 317
お住まい・勤務地: お花畑
投稿日時: 2003-08-29 17:19
引用:

ほむらさんの書き込み (2003-08-29 16:45) より:
>af.setToTranslation(50.0d, 50.0d);

af.setToTranslation(画像の横幅半分, 0.0d);

にしてみたらどうですか?
名前からしてここで回転の支点を決めているような気がするのですが



そりはちがいます ^^;
setToTranslationは平行移動を行うためのメソッドで、回転はrotateにより行います。
但し、rotateには回転の角度だけでなく中心座標も指定することができるので、下記のようにすればうまくいくのではないでしょうか。

af.rotate(45 * Math.PI/180.0d, <画像の中心のx座標>, <画像の中心のy座標>);



[ メッセージ編集済み 編集者: たーぞう 編集日時 2003-08-29 17:20 ]

[ メッセージ編集済み 編集者: たーぞう 編集日時 2003-08-29 17:21 ]
さる
会議室デビュー日: 2003/08/29
投稿数: 3
投稿日時: 2003-08-29 17:22
ほむらさんの書かれているように
setToTranslation()
で、画像の中心点を指定すればよいかと思います。
”アフィン変換”をキーワードにいろいろ調べてみては如何でしょうか。
アフィン変換自体は数学ですが、"アフィン変換を使う"ことは数学でも何でもないので
一度覚えてしまわれることをお勧めします。
たーぞう
ぬし
会議室デビュー日: 2003/08/08
投稿数: 317
お住まい・勤務地: お花畑
投稿日時: 2003-08-29 17:43
なんだか実にいい加減な・・・ ^^;

setToTranslationを使用するとしたら、
setToTranslation(-<回転の中心のx座標>, -<回転の中心のy座標>)
で回転の中心の座標を(0, 0)にした後、
rotate(回転角)
で回転させ、
setToTranslation(<回転の中心のx座標>, <回転の中心のy座標>)
として、ずれた座標系を戻しておかなければいけませんね。

ところでみなさん
http://java.sun.com/j2se/1.4/ja/docs/ja/api/index.html
をご覧になってますか?
びしばし
大ベテラン
会議室デビュー日: 2002/03/13
投稿数: 181
投稿日時: 2003-08-29 18:21
たーぞうさんに一票。
ほむらさんとさるさんの言われている方法では「平行移動してから回転する」ための行列を作成しているので、複数回適用するとどんどんずれていきますね。
fuzuki
常連さん
会議室デビュー日: 2003/08/23
投稿数: 48
投稿日時: 2003-08-29 19:15
みなさん、ありがとうございました。
アドバイスを元に試行錯誤したところ、うまくいきました。

> af.setToTranslation(50.0d, 50.0d);

af.setToTranslation(50.0d - <画像の中心の幅>, 50.0d - <画像の中心の高さ>);

> af.rotate(45 * Math.PI/180);

af.rotate(45 * Math.PI/180, <画像の中心の幅>, <画像の中心の高さ>);

以上のように変更したところ、中心を支点にして回転するようになりました。
一応、これで正常に回転しているようですが、間違ってませんよね??(^^;

最初、APIを見ながらやっていたのですが、混乱してきて煮詰まってしまったので、みなさんの助けを借りようと質問したわけです。とても助かりました。ありがとうございました。
たーぞう
ぬし
会議室デビュー日: 2003/08/08
投稿数: 317
お住まい・勤務地: お花畑
投稿日時: 2003-08-30 11:13
すみません、私の説明が悪かったようで。
引用:

> af.setToTranslation(50.0d, 50.0d);

af.setToTranslation(50.0d - <画像の中心の幅>, 50.0d - <画像の中心の高さ>);

> af.rotate(45 * Math.PI/180);

af.rotate(45 * Math.PI/180, <画像の中心の幅>, <画像の中心の高さ>);



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

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

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

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

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