モジュール java.desktop
パッケージ java.awt.geom

クラスAffineTransform

java.lang.Object
java.awt.geom.AffineTransform
すべての実装されたインタフェース:
Serializable, Cloneable

public class AffineTransform extends Object implements Cloneable, Serializable
AffineTransformクラスは、線の直線性と平行性を保ったままで2次元座標間の線形マッピングを実行する2次元アフィン変換を表現します。 アフィン変換は、一連の平行移動、スケーリング、反転、回転、変形により構成されます。

このような座標変換は、暗黙に指定された[ 0 0 1 ]という最終行を持つ3行×3列の行列によって表現できます。 この行列は、次の処理に従って、座標を列ベクトルと見なし、座標ベクトルを行列で乗算することによって、転送元座標(x,y)を転送先座標(x',y')に変換します。

      [ x']   [  m00  m01  m02  ] [ x ]   [ m00x + m01y + m02 ]
      [ y'] = [  m10  m11  m12  ] [ y ] = [ m10x + m11y + m12 ]
      [ 1 ]   [   0    0    1   ] [ 1 ]   [         1         ]
 

90度回転の処理

AffineTransformクラスのrotateメソッドのバリエーションの中には、倍精度値の引数で回転角度(ラジアン)を指定するものがあります。 これらのメソッドには、約90度(および180度、270度、360度などの倍数)の回転に対して特殊な処理が用意されており、一般的な四分円回転はより効率的に処理されます。 この特殊な処理により、90度の倍数に近似的な角度を正確に90度の倍数として扱うことができます。 90度の数倍程度である場合、四分円回転として扱われる角度の範囲は約0.00000121度の幅です。 このセクションでは、このような特殊な処理が必要になる理由と、その実装方法について説明します。

90度はラジアンでPI/2と表され、かつPIは超越数(そのため無理数)であるため、90度の倍数をラジアンで測定された正確な倍精度値として厳密に表すことはできません。 そのため、有限の倍数度値を使用して四分円回転(90、180、270、360度)を表現することは理論的に不可能です。 倍精度浮動小数点値を使用すると、PI/2の0以外の倍数に非常に近い値を得ることができますが、正弦(sin)または余弦(cos)が正確に0.0、1.0、または -1.0になるだけの十分に近い値が得られるわけではありません。 そのため、Math.sin(0.0)以外のすべての場合について、Math.sin()およびMath.cos()の実装が0.0を返すことはありません。 ただし同様の実装であっても、90度の倍数ごとに一定範囲内の値については、ちょうど1.0および -1.0を返します。これは、正しい応答が1.0または -1.0に非常に近いため、倍精度の有効数字では、0.0に近い値の場合と同程度の正確さで差異を表すことができないためです。

これらの問題の最終結果として、これらのラジアン・ベースの回転操作中の行列変更の値を直接生成するためにMath.sin()メソッドやMath.cos()メソッドが使用される場合は、正弦や余弦で得られる0.0以外の値により発生する行列のわずかな変動のために、結果として得られる変形はrotate(Math.PI/2.0)のような単純な場合であっても厳密には四分円回転として分類できません。 これらの変形が四分円回転として分類されない場合、変形の種類に基づいて後続の操作を最適化しようとするそれ以降のコードは、もっとも汎用的な実装に委託されます。

四分円回転は非常によく行われる操作であるため、回転を変形に適用する場合と得られた変形を座標に適用する場合の両方で、このクラスは四分円回転をある程度早く処理できなければいけません。 このような最適化処理を実現するために、ラジアンで計測された回転角度を使用するメソッドでは、四分円回転を意図した角度を検出すると、四分円回転として扱います。 そのため、これらのメソッドでは、Math.sin(theta)またはMath.cos(theta)のどちらかが正確に1.0または -1.0を返す場合に角度thetaを四分円回転として扱います。 経験則として、このプロパティは、Math.PI/2.0の数倍程度の場合に約0.0000000211ラジアン(または0.00000121度)の範囲でtrueを保持します。

導入されたバージョン:
1.2
関連項目: