実験室 |
Java 2D AffineTransform (2) |
|||||||||||||||||||
ところで AffineTransform とは何なのか |
|||||||||||||||||||
今まで、AffineTransform クラスを使ってきましたが、さて AffineTransform とは何なのでしょうか。 ここから少し数学の話になるので、いやな人は次の節に飛んでいただいて結構です。 結論から先にいえば、AffineTransform クラスはアフィン変換を行うクラスです。ところでアフィン変換って何でしょう。アフィン変換は平行移動、拡大・縮小、回転、シャーリングを行う変換です。ということは、今までプログラム作っているから分かっているって。そりゃ、ごもっとも。 これらの変換を数式であらわすとどうなるでしょう。(x, y) の点が変換されて (x', y') になるとします。詳しくは高校の数学の教科書を引っ張り出してもらうか、Computer Graphics の本などを読んでもらうとして、ここでは簡単に説明を加えておきます。
このようにそれぞれの変換は 3×3 の行列で表すことができます。それも一番下の行は常に 0, 0, 1 なので、実質的には上の 2 つの行の 6 個の要素だけで表せます。この行列を使用した座標変換をアフィン変換とよびます。式で書くと
となります。 AffineTransform オブジェクトを生成するには static なメソッドを使っていましたが、この行列の 6 個の要素を指定して生成することもできます。また、後から行列をセットすることも可能です。
この 3 種類の方法を用いて同じ変換を行ってみました。どれも同じ結果になることが分かると思います。
AffineTransform オブジェクトを生成する部分を抜き出してみると次のようになります。 RotateTest1.java
RotateTest2.java
RotateTest3.java
RotateTest4.java
|
実験 1 変換の組み合わせ |
||||||||||||||||||||
まずは単純に AffineTransform クラスで座標系の変換をしてみましょう。ここでは座標軸を回転させてみます。
AffineTransorm クラスは普通にコンストラクタを使用して生成することもできますが、生成のための static メソッドも用意されています。今回はそれを使ってみました。AffintTransform
オブジェクトも四角形と同じように init メソッドで生成します。
この AffineTransform オブジェクトは (0, 0) を中心にして 45°の回転を行うものです。このほかにも次のような生成のためのメソッドがあります。
それでは描画してみましょう。座標変換を行うには Graphics2D#setTransform メソッドを使用します。
実行させるとどうなりましたか。長方形が回転して描画されているのが確認できたでしょうか。 ユーザ空間を回転させるということがどういうことかを図 2 で示してみました。
デバイス空間というのぞき窓の位置は変わらないため、ユーザ空間とデバイス空間が回転によってずれてしまうわけです。
|
実験 2 複数のユーザ空間 |
|||||||
次の実験は、複数のユーザ空間を設定できるかどうかについてです。実験 1 と同様に回転変換で試してみます。
長方形 rect1 オブジェクトはデフォルトのユーザ空間、rect2 が回転変換をほどこされるユーザ空間に描画します。
これを実行すると、rect1 はそのまま描画され、rect2 は回転した形で描画されます。 ということは、次のようなことがいえます。
|
実験 3 ユーザ空間にほどこされた変換をもとにもどす |
||||||||
座標変換されてしまったユーザ空間は元に戻せるかやってみましょう。
ユーザ空間を元に戻すには、g2D オブジェクトにセットされた AffineTransform オブジェクトをチャラにしてしまえばいいと考えられます。そこで、ためしに setTransform メソッドの引数に null を入れてみましょう。
これを実行すると、g2D.setTransform(null) のところで NullPointerException が発生してしまいました。 null がだめだとすると、なにもしない AffineTransform オブジェクトを引数にしてみましょう。
引数がないコンストラクタを使用して、AffineTransform オブジェクトを生成すると、なにも変換しないオブジェクトが生成されます。これを setTransform の引数にしてみました。 実行してみると、期待通りユーザ空間は元に戻りました。 この実験からは、次のようなことがわかりました。
|
実験 4 AffineTransform を使わない座標変換 |
|||||||||||||||||||
Graphics2D の API を見ていると、下に示したようなメソッドがあります。これらのメソッドを用いても座標変換ができそうです。
さっそく、試してみましょう。
これまで、AffineTransform オブジェクトを生成していましたが、直接 Graphics2D オブジェクトに対して回転変換をセットします。
この実験からは、次のようなことがわかりました。
|
|