/* AffineTransform.java -- transform coordinates between two 2-D spaces
   Copyright (C) 2000, 2001, 2002 Free Software Foundation

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.awt.geom;

import java.awt.Shape;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;

/**
 * This class represents an affine transformation between two coordinate
 * spaces in 2 dimensions. Such a transform preserves the "straightness"
 * and "parallelness" of lines. The transform is built from a sequence of
 * translations, scales, flips, rotations, and shears.
 *
 * <p>The transformation can be represented using matrix math on a 3x3 array.
 * Given (x,y), the transformation (x',y') can be found by:
 * <pre>
 * [ x']   [ m00 m01 m02 ] [ x ]   [ m00*x + m01*y + m02 ]
 * [ y'] = [ m10 m11 m12 ] [ y ] = [ m10*x + m11*y + m12 ]
 * [ 1 ]   [  0   0   1  ] [ 1 ]   [          1          ]
 * </pre>
 * The bottom row of the matrix is constant, so a transform can be uniquely
 * represented (as in toString) by "[[m00, m01, m02], [m10, m11, m12]]".
 *
 * @author Tom Tromey <tromey@cygnus.com>
 * @author Eric Blake <ebb9@email.byu.edu>
 * @since 1.2
 * @status partially updated to 1.4, still has some problems
 */
public class AffineTransform implements Cloneable, Serializable
{
  /**
   * Compatible with JDK 1.2+.
   */
  private static final long serialVersionUID = 1330973210523860834L;

  /**
   * The transformation is the identity (x' = x, y' = y). All other transforms
   * have either a combination of the appropriate transform flag bits for
   * their type, or the type GENERAL_TRANSFORM.
   *
   * @see #TYPE_TRANSLATION
   * @see #TYPE_UNIFORM_SCALE
   * @see #TYPE_GENERAL_SCALE
   * @see #TYPE_FLIP
   * @see #TYPE_QUADRANT_ROTATION
   * @see #TYPE_GENERAL_ROTATION
   * @see #TYPE_GENERAL_TRANSFORM
   * @see #getType()
   */
  public static final int TYPE_IDENTITY = 0;

  /**
   * The transformation includes a translation - shifting in the x or y
   * direction without changing length or angles.
   *
   * @see #TYPE_IDENTITY
   * @see #TYPE_UNIFORM_SCALE
   * @see #TYPE_GENERAL_SCALE
   * @see #TYPE_FLIP
   * @see #TYPE_QUADRANT_ROTATION
   * @see #TYPE_GENERAL_ROTATION
   * @see #TYPE_GENERAL_TRANSFORM
   * @see #getType()
   */
  public static final int TYPE_TRANSLATION = 1;

  /**
   * The transformation includes a uniform scale - length is scaled in both
   * the x and y directions by the same amount, without affecting angles.
   * This is mutually exclusive with TYPE_GENERAL_SCALE.
   *
   * @see #TYPE_IDENTITY
   * @see #TYPE_TRANSLATION
   * @see #TYPE_GENERAL_SCALE
   * @see #TYPE_FLIP
   * @see #TYPE_QUADRANT_ROTATION
   * @see #TYPE_GENERAL_ROTATION
   * @see #TYPE_GENERAL_TRANSFORM
   * @see #TYPE_MASK_SCALE
   * @see #getType()
   */
  public static final int TYPE_UNIFORM_SCALE = 2;

  /**
   * The transformation includes a general scale - length is scaled in either
   * or both the x and y directions, but by different amounts; without
   * affecting angles. This is mutually exclusive with TYPE_UNIFORM_SCALE.
   *
   * @see #TYPE_IDENTITY
   * @see #TYPE_TRANSLATION
   * @see #TYPE_UNIFORM_SCALE
   * @see #TYPE_FLIP
   * @see #TYPE_QUADRANT_ROTATION
   * @see #TYPE_GENERAL_ROTATION
   * @see #TYPE_GENERAL_TRANSFORM
   * @see #TYPE_MASK_SCALE
   * @see #getType()
   */
  public static final int TYPE_GENERAL_SCALE = 4;

  /**
   * This constant checks if either variety of scale transform is performed.
   *
   * @see #TYPE_UNIFORM_SCALE
   * @see #TYPE_GENERAL_SCALE
   */
  public static final int TYPE_MASK_SCALE = 6;

  /**
   * The transformation includes a flip about an axis, swapping between
   * right-handed and left-handed coordinate systems. In a right-handed
   * system, the positive x-axis rotates counter-clockwise to the positive
   * y-axis; in a left-handed system it rotates clockwise.
   *
   * @see #TYPE_IDENTITY
   * @see #TYPE_TRANSLATION
   * @see #TYPE_UNIFORM_SCALE
   * @see #TYPE_GENERAL_SCALE
   * @see #TYPE_QUADRANT_ROTATION
   * @see #TYPE_GENERAL_ROTATION
   * @see #TYPE_GENERAL_TRANSFORM
   * @see #getType()
   */
  public static final int TYPE_FLIP = 64;

  /**
   * The transformation includes a rotation of a multiple of 90 degrees (PI/2
   * radians). Angles are rotated, but length is preserved. This is mutually
   * exclusive with TYPE_GENERAL_ROTATION.
   *
   * @see #TYPE_IDENTITY
   * @see #TYPE_TRANSLATION
   * @see #TYPE_UNIFORM_SCALE
   * @see #TYPE_GENERAL_SCALE
   * @see #TYPE_FLIP
   * @see #TYPE_GENERAL_ROTATION
   * @see #TYPE_GENERAL_TRANSFORM
   * @see #TYPE_MASK_ROTATION
   * @see #getType()
   */
  public static final int TYPE_QUADRANT_ROTATION = 8;

  /**
   * The transformation includes a rotation by an arbitrary angle. Angles are
   * rotated, but length is preserved. This is mutually exclusive with
   * TYPE_QUADRANT_ROTATION.
   *
   * @see #TYPE_IDENTITY
   * @see #TYPE_TRANSLATION
   * @see #TYPE_UNIFORM_SCALE
   * @see #TYPE_GENERAL_SCALE
   * @see #TYPE_FLIP
   * @see #TYPE_QUADRANT_ROTATION
   * @see #TYPE_GENERAL_TRANSFORM
   * @see #TYPE_MASK_ROTATION
   * @see #getType()
   */
  public static final int TYPE_GENERAL_ROTATION = 16;

  /**
   * This constant checks if either variety of rotation is performed.
   *
   * @see #TYPE_QUADRANT_ROTATION
   * @see #TYPE_GENERAL_ROTATION
   */
  public static final int TYPE_MASK_ROTATION = 24;

  /**
   * The transformation is an arbitrary conversion of coordinates which
   * could not be decomposed into the other TYPEs.
   *
   * @see #TYPE_IDENTITY
   * @see #TYPE_TRANSLATION
   * @see #TYPE_UNIFORM_SCALE
   * @see #TYPE_GENERAL_SCALE
   * @see #TYPE_FLIP
   * @see #TYPE_QUADRANT_ROTATION
   * @see #TYPE_GENERAL_ROTATION
   * @see #getType()
   */
  public static final int TYPE_GENERAL_TRANSFORM = 32;

  /**
   * The X coordinate scaling element of the transform matrix.
   *
   * @serial matrix[0,0]
   */
  private double m00;

  /**
   * The Y coordinate scaling element of the transform matrix.
   *
   * @serial matrix[1,0]
   */
  private double m10;

  /**
   * The X coordinate shearing element of the transform matrix.
   *
   * @serial matrix[0,1]
   */
  private double m01;

  /**
   * The Y coordinate shearing element of the transform matrix.
   *
   * @serial matrix[1,1]
   */
  private double m11;

  /**
   * The X coordinate translation element of the transform matrix.
   *
   * @serial matrix[0,2]
   */
  private double m02;

  /**
   * The Y coordinate translation element of the transform matrix.
   *
   * @serial matrix[1,2]
   */
  private double m12;

  /** The type of this transform. */
  private transient int type;

  /**
   * Construct a new identity transform:
   * <pre>
   * [ 1 0 0 ]
   * [ 0 1 0 ]
   * [ 0 0 1 ]
   * </pre>
   */
  public AffineTransform()
  {
    m00 = m11 = 1;
  }

  /**
   * Create a new transform which copies the given one.
   *
   * @param tx the transform to copy
   * @throws NullPointerException if tx is null
   */
  public AffineTransform(AffineTransform tx)
  {
    setTransform(tx);
  }

  /**
   * Construct a transform with the given matrix entries:
   * <pre>
   * [ m00 m01 m02 ]
   * [ m10 m11 m12 ]
   * [  0   0   1  ]
   * </pre>
   *
   * @param m00 the x scaling component
   * @param m10 the y shearing component
   * @param m01 the x shearing component
   * @param m11 the y scaling component
   * @param m02 the x translation component
   * @param m12 the y translation component
   */
  public AffineTransform(float m00, float m10,
                         float m01, float m11,
                         float m02, float m12)
  {
    this.m00 = m00;
    this.m10 = m10;
    this.m01 = m01;
    this.m11 = m11;
    this.m02 = m02;
    this.m12 = m12;
    updateType();
  }

  /**
   * Construct a transform from a sequence of float entries. The array must
   * have at least 4 entries, which has a translation factor of 0; or 6
   * entries, for specifying all parameters:
   * <pre>
   * [ f[0] f[2] (f[4]) ]
   * [ f[1] f[3] (f[5]) ]
   * [  0     0    1    ]
   * </pre>
   *
   * @param f the matrix to copy from, with at least 4 (6) entries
   * @throws NullPointerException if f is null
   * @throws ArrayIndexOutOfBoundsException if f is too small
   */
  public AffineTransform(float[] f)
  {
    m00 = f[0];
    m10 = f[1];
    m01 = f[2];
    m11 = f[3];
    if (f.length >= 6)
      {
        m02 = f[4];
        m12 = f[5];
      }
    updateType();
  }

  /**
   * Construct a transform with the given matrix entries:
   * <pre>
   * [ m00 m01 m02 ]
   * [ m10 m11 m12 ]
   * [  0   0   1  ]
   * </pre>
   *
   * @param m00 the x scaling component
   * @param m10 the y shearing component
   * @param m01 the x shearing component
   * @param m11 the y scaling component
   * @param m02 the x translation component
   * @param m12 the y translation component
   */
  public AffineTransform(double m00, double m10, double m01,
                         double m11, double m02, double m12)
  {
    this.m00 = m00;
    this.m10 = m10;
    this.m01 = m01;
    this.m11 = m11;
    this.m02 = m02;
    this.m12 = m12;
    updateType();
  }

  /**
   * Construct a transform from a sequence of double entries. The array must
   * have at least 4 entries, which has a translation factor of 0; or 6
   * entries, for specifying all parameters:
   * <pre>
   * [ d[0] d[2] (d[4]) ]
   * [ d[1] d[3] (d[5]) ]
   * [  0     0    1    ]
   * </pre>
   *
   * @param d the matrix to copy from, with at least 4 (6) entries
   * @throws NullPointerException if d is null
   * @throws ArrayIndexOutOfBoundsException if d is too small
   */
  public AffineTransform(double[] d)
  {
    m00 = d[0];
    m10 = d[1];
    m01 = d[2];
    m11 = d[3];
    if (d.length >= 6)
      {
        m02 = d[4];
        m12 = d[5];
      }
    updateType();
  }

  /**
   * Returns a translation transform:
   * <pre>
   * [ 1 0 tx ]
   * [ 0 1 ty ]
   * [ 0 0 1  ]
   * </pre>
   *
   * @param tx the x translation distance
   * @param ty the y translation distance
   * @return the translating transform
   */
  public static AffineTransform getTranslateInstance(double tx, double ty)
  {
    AffineTransform t = new AffineTransform();
    t.setToTranslation(tx, ty);
    return t;
  }

  /**
   * Returns a rotation transform. A positive angle (in radians) rotates
   * the positive x-axis to the positive y-axis:
   * <pre>
   * [ cos(theta) -sin(theta) 0 ]
   * [ sin(theta)  cos(theta) 0 ]
   * [     0           0      1 ]
   * </pre>
   *
   * @param theta the rotation angle
   * @return the rotating transform
   */
  public static AffineTransform getRotateInstance(double theta)
  {
    AffineTransform t = new AffineTransform();
    t.setToRotation(theta);
    return t;
  }

  /**
   * Returns a rotation transform about a point. A positive angle (in radians)
   * rotates the positive x-axis to the positive y-axis. This is the same
   * as calling:
   * <pre>
   * AffineTransform tx = new AffineTransform();
   * tx.setToTranslation(x, y);
   * tx.rotate(theta);
   * tx.translate(-x, -y);
   * </pre>
   *
   * <p>The resulting matrix is: 
   * <pre>
   * [ cos(theta) -sin(theta) x-x*cos+y*sin ]
   * [ sin(theta)  cos(theta) y-x*sin-y*cos ]
   * [     0           0            1       ]
   * </pre>
   *
   * @param theta the rotation angle
   * @param x the x coordinate of the pivot point
   * @param y the y coordinate of the pivot point
   * @return the rotating transform
   */
  public static AffineTransform getRotateInstance(double theta,
                                                  double x, double y)
  {
    AffineTransform t = new AffineTransform();
    t.setToTranslation(x, y);
    t.rotate(theta);
    t.translate(-x, -y);
    return t;
  }

  /**
   * Returns a scaling transform:
   * <pre>
   * [ sx 0  0 ]
   * [ 0  sy 0 ]
   * [ 0  0  1 ]
   * </pre>
   *
   * @param sx the x scaling factor
   * @param sy the y scaling factor
   * @return the scaling transform
   */
  public static AffineTransform getScaleInstance(double sx, double sy)
  {
    AffineTransform t = new AffineTransform();
    t.setToScale(sx, sy);
    return t;
  }

  /**
   * Returns a shearing transform (points are shifted in the x direction based
   * on a factor of their y coordinate, and in the y direction as a factor of
   * their x coordinate):
   * <pre>
   * [  1  shx 0 ]
   * [ shy  1  0 ]
   * [  0   0  1 ]
   * </pre>
   *
   * @param shx the x shearing factor
   * @param shy the y shearing factor
   * @return the shearing transform
   */
  public static AffineTransform getShearInstance(double shx, double shy)
  {
    AffineTransform t = new AffineTransform();
    t.setToShear(shx, shy);
    return t;
  }

  /**
   * Returns the type of this transform. The result is always valid, although
   * it may not be the simplest interpretation (in other words, there are
   * sequences of transforms which reduce to something simpler, which this
   * does not always detect). The result is either TYPE_GENERAL_TRANSFORM,
   * or a bit-wise combination of TYPE_TRANSLATION, the mutually exclusive
   * TYPE_*_ROTATIONs, and the mutually exclusive TYPE_*_SCALEs.
   *
   * @see #TYPE_IDENTITY
   * @see #TYPE_TRANSLATION
   * @see #TYPE_UNIFORM_SCALE
   * @see #TYPE_GENERAL_SCALE
   * @see #TYPE_QUADRANT_ROTATION
   * @see #TYPE_GENERAL_ROTATION
   * @see #TYPE_GENERAL_TRANSFORM
   */
  public int getType()
  {
    return type;
  }

  /**
   * Return the determinant of this transform matrix. If the determinant is
   * non-zero, the transform is invertible; otherwise operations which require
   * an inverse throw a NoninvertibleTransformException. A result very near
   * zero, due to rounding errors, may indicate that inversion results do not
   * carry enough precision to be meaningful.
   *
   * <p>If this is a uniform scale transformation, the determinant also
   * represents the squared value of the scale. Otherwise, it carries little
   * additional meaning. The determinant is calculated as:
   * <pre>
   * | m00 m01 m02 |
   * | m10 m11 m12 | = m00 * m11 - m01 * m10
   * |  0   0   1  |
   * </pre>
   *
   * @return the determinant
   * @see #createInverse()
   */
  public double getDeterminant()
  {
    return m00 * m11 - m01 * m10;
  }

  /**
   * Return the matrix of values used in this transform. If the matrix has
   * fewer than 6 entries, only the scale and shear factors are returned;
   * otherwise the translation factors are copied as well. The resulting
   * values are:
   * <pre>
   * [ d[0] d[2] (d[4]) ]
   * [ d[1] d[3] (d[5]) ]
   * [  0     0    1    ]
   * </pre>
   *
   * @param d the matrix to store the results into; with 4 (6) entries
   * @throws NullPointerException if d is null
   * @throws ArrayIndexOutOfBoundsException if d is too small
   */
  public void getMatrix(double[] d)
  {
    d[0] = m00;
    d[1] = m10;
    d[2] = m01;
    d[3] = m11;
    if (d.length >= 6)
      {
        d[4] = m02;
        d[5] = m12;
      }
  }

  /**
   * Returns the X coordinate scaling factor of the matrix.
   *
   * @return m00
   * @see #getMatrix(double[])
   */
  public double getScaleX()
  {
    return m00;
  }

  /**
   * Returns the Y coordinate scaling factor of the matrix.
   *
   * @return m11
   * @see #getMatrix(double[])
   */
  public double getScaleY()
  {
    return m11;
  }

  /**
   * Returns the X coordinate shearing factor of the matrix.
   *
   * @return m01
   * @see #getMatrix(double[])
   */
  public double getShearX()
  {
    return m01;
  }

  /**
   * Returns the Y coordinate shearing factor of the matrix.
   *
   * @return m10
   * @see #getMatrix(double[])
   */
  public double getShearY()
  {
    return m10;
  }

  /**
   * Returns the X coordinate translation factor of the matrix.
   *
   * @return m02
   * @see #getMatrix(double[])
   */
  public double getTranslateX()
  {
    return m02;
  }

  /**
   * Returns the Y coordinate translation factor of the matrix.
   *
   * @return m12
   * @see #getMatrix(double[])
   */
  public double getTranslateY()
  {
    return m12;
  }

  /**
   * Concatenate a translation onto this transform. This is equivalent, but
   * more efficient than
   * <code>concatenate(AffineTransform.getTranslateInstance(tx, ty))</code>.
   *
   * @param tx the x translation distance
   * @param ty the y translation distance
   * @see #getTranslateInstance(double, double)
   * @see #concatenate(AffineTransform)
   */
  public void translate(double tx, double ty)
  {
    m02 += tx * m00 + ty * m01;
    m12 += tx * m10 + ty * m11;
    updateType();
  }

  /**
   * Concatenate a rotation onto this transform. This is equivalent, but
   * more efficient than
   * <code>concatenate(AffineTransform.getRotateInstance(theta))</code>.
   *
   * @param theta the rotation angle
   * @see #getRotateInstance(double)
   * @see #concatenate(AffineTransform)
   */
  public void rotate(double theta)
  {
    double c = Math.cos(theta);
    double s = Math.sin(theta);
    double n00 = m00 *  c + m01 * s;
    double n01 = m00 * -s + m01 * c;
    double n10 = m10 *  c + m11 * s;
    double n11 = m10 * -s + m11 * c;
    m00 = n00;
    m01 = n01;
    m10 = n10;
    m11 = n11;
    updateType();
  }

  /**
   * Concatenate a rotation about a point onto this transform. This is
   * equivalent, but more efficient than
   * <code>concatenate(AffineTransform.getRotateInstance(theta, x, y))</code>.
   *
   * @param theta the rotation angle
   * @param x the x coordinate of the pivot point
   * @param y the y coordinate of the pivot point
   * @see #getRotateInstance(double, double, double)
   * @see #concatenate(AffineTransform)
   */
  public void rotate(double theta, double x, double y)
  {
    translate(x, y);
    rotate(theta);
    translate(-x, -y);
  }

  /**
   * Concatenate a scale onto this transform. This is equivalent, but more
   * efficient than
   * <code>concatenate(AffineTransform.getScaleInstance(sx, sy))</code>.
   *
   * @param sx the x scaling factor
   * @param sy the y scaling factor
   * @see #getScaleInstance(double, double)
   * @see #concatenate(AffineTransform)
   */
  public void scale(double sx, double sy)
  {
    m00 *= sx;
    m01 *= sy;
    m10 *= sx;
    m11 *= sy;
    updateType();
  }

  /**
   * Concatenate a shearing onto this transform. This is equivalent, but more
   * efficient than
   * <code>concatenate(AffineTransform.getShearInstance(sx, sy))</code>.
   *
   * @param shx the x shearing factor
   * @param shy the y shearing factor
   * @see #getShearInstance(double, double)
   * @see #concatenate(AffineTransform)
   */
  public void shear(double shx, double shy)
  {
    double n00 = m00 + shx * m01;
    double n01 = shx * m00 + m01;
    double n10 = m10 * shy + m11;
    double n11 = shx * m10 + m11;
    m00 = n00;
    m01 = n01;
    m10 = n10;
    m11 = n11;
    updateType();
  }

  /**
   * Reset this transform to the identity (no transformation):
   * <pre>
   * [ 1 0 0 ]
   * [ 0 1 0 ]
   * [ 0 0 1 ]
   * </pre>
   */
  public void setToIdentity()
  {
    m00 = m11 = 1;
    m01 = m02 = m10 = m12 = 0;
    type = TYPE_IDENTITY;
  }

  /**
   * Set this transform to a translation:
   * <pre>
   * [ 1 0 tx ]
   * [ 0 1 ty ]
   * [ 0 0 1  ]
   * </pre>
   *
   * @param tx the x translation distance
   * @param ty the y translation distance
   */
  public void setToTranslation(double tx, double ty)
  {
    m00 = m11 = 1;
    m01 = m10 = 0;
    m02 = tx;
    m12 = ty;
    type = (tx == 0 && ty == 0) ? TYPE_UNIFORM_SCALE : TYPE_TRANSLATION;
  }

  /**
   * Set this transform to a rotation. A positive angle (in radians) rotates
   * the positive x-axis to the positive y-axis:
   * <pre>
   * [ cos(theta) -sin(theta) 0 ]
   * [ sin(theta)  cos(theta) 0 ]
   * [     0           0      1 ]
   * </pre>
   *
   * @param theta the rotation angle
   */
  public void setToRotation(double theta)
  {
    double c = Math.cos(theta);
    double s = Math.sin(theta);
    m00 = c;
    m01 = -s;
    m02 = 0;
    m10 = s;
    m11 = c;
    m12 = 0;
    type = (c == 1 ? TYPE_IDENTITY
            : c == 0 || c == -1 ? TYPE_QUADRANT_ROTATION
            : TYPE_GENERAL_ROTATION);
  }

  /**
   * Set this transform to a rotation about a point. A positive angle (in
   * radians) rotates the positive x-axis to the positive y-axis. This is the
   * same as calling:
   * <pre>
   * tx.setToTranslation(x, y);
   * tx.rotate(theta);
   * tx.translate(-x, -y);
   * </pre>
   *
   * <p>The resulting matrix is: 
   * <pre>
   * [ cos(theta) -sin(theta) x-x*cos+y*sin ]
   * [ sin(theta)  cos(theta) y-x*sin-y*cos ]
   * [     0           0            1       ]
   * </pre>
   *
   * @param theta the rotation angle
   * @param x the x coordinate of the pivot point
   * @param y the y coordinate of the pivot point
   */
  public void setToRotation(double theta, double x, double y)
  {
    double c = Math.cos(theta);
    double s = Math.sin(theta);
    m00 = c;
    m01 = -s;
    m02 = x - x * c + y * s;
    m10 = s;
    m11 = c;
    m12 = y - x * s - y * c;
    updateType();
  }

  /**
   * Set this transform to a scale:
   * <pre>
   * [ sx 0  0 ]
   * [ 0  sy 0 ]
   * [ 0  0  1 ]
   * </pre>
   *
   * @param sx the x scaling factor
   * @param sy the y scaling factor
   */
  public void setToScale(double sx, double sy)
  {
    m00 = sx;
    m01 = m02 = m10 = m12 = 0;
    m11 = sy;
    type = (sx != sy ? TYPE_GENERAL_SCALE
            : sx == 1 ? TYPE_IDENTITY : TYPE_UNIFORM_SCALE);
  }

  /**
   * Set this transform to a shear (points are shifted in the x direction based
   * on a factor of their y coordinate, and in the y direction as a factor of
   * their x coordinate):
   * <pre>
   * [  1  shx 0 ]
   * [ shy  1  0 ]
   * [  0   0  1 ]
   * </pre>
   *
   * @param shx the x shearing factor
   * @param shy the y shearing factor
   */
  public void setToShear(double shx, double shy)
  {
    m00 = m11 = 1;
    m01 = shx;
    m10 = shy;
    m02 = m12 = 0;
    updateType();
  }

  /**
   * Set this transform to a copy of the given one.
   *
   * @param tx the transform to copy
   * @throws NullPointerException if tx is null
   */
  public void setTransform(AffineTransform tx)
  {
    m00 = tx.m00;
    m01 = tx.m01;
    m02 = tx.m02;
    m10 = tx.m10;
    m11 = tx.m11;
    m12 = tx.m12;
    type = tx.type;
  }

  /**
   * Set this transform to the given values:
   * <pre>
   * [ m00 m01 m02 ]
   * [ m10 m11 m12 ]
   * [  0   0   1  ]
   * </pre>
   *
   * @param m00 the x scaling component
   * @param m10 the y shearing component
   * @param m01 the x shearing component
   * @param m11 the y scaling component
   * @param m02 the x translation component
   * @param m12 the y translation component
   */
  public void setTransform(double m00, double m10, double m01,
                           double m11, double m02, double m12)
  {
    this.m00 = m00;
    this.m10 = m10;
    this.m01 = m01;
    this.m11 = m11;
    this.m02 = m02;
    this.m12 = m12;
    updateType();
  }

  /**
   * Set this transform to the result of performing the original version of
   * this followed by tx. This is commonly used when chaining transformations
   * from one space to another. In matrix form:
   * <pre>
   * [ this ] = [ this ] x [ tx ]
   * </pre>
   *
   * @param tx the transform to concatenate
   * @throws NullPointerException if tx is null
   * @see #preConcatenate(AffineTransform)
   */
  public void concatenate(AffineTransform tx)
  {
    double n00 = m00 * tx.m00 + m01 * tx.m10;
    double n01 = m00 * tx.m01 + m01 * tx.m11;
    double n02 = m00 * tx.m02 + m01 * tx.m12 + m02;
    double n10 = m10 * tx.m00 + m11 * tx.m10;
    double n11 = m10 * tx.m01 + m11 * tx.m11;
    double n12 = m10 * tx.m02 + m11 * tx.m12 + m12;
    m00 = n00;
    m01 = n01;
    m02 = n02;
    m10 = n10;
    m11 = n11;
    m12 = n12;
    updateType();
  }

  /**
   * Set this transform to the result of performing tx followed by the
   * original version of this. This is less common than normal concatenation,
   * but can still be used to chain transformations from one space to another.
   * In matrix form:
   * <pre>
   * [ this ] = [ tx ] x [ this ]
   * </pre>
   *
   * @param tx the transform to concatenate
   * @throws NullPointerException if tx is null
   * @see #concatenate(AffineTransform)
   */
  public void preConcatenate(AffineTransform tx)
  {
    double n00 = tx.m00 * m00 + tx.m01 * m10;
    double n01 = tx.m00 * m01 + tx.m01 * m11;
    double n02 = tx.m00 * m02 + tx.m01 * m12 + tx.m02;
    double n10 = tx.m10 * m00 + tx.m11 * m10;
    double n11 = tx.m10 * m01 + tx.m11 * m11;
    double n12 = tx.m10 * m02 + tx.m11 * m12 + tx.m12;
    m00 = n00;
    m01 = n01;
    m02 = n02;
    m10 = n10;
    m11 = n11;
    m12 = n12;
    updateType();
  }

  /**
   * Returns a transform, which if concatenated to this one, will result in
   * the identity transform. This is useful for undoing transformations, but
   * is only possible if the original transform has an inverse (ie. does not
   * map multiple points to the same line or point). A transform exists only
   * if getDeterminant() has a non-zero value.
   *
   * @return a new inverse transform
   * @throws NoninvertibleTransformException if inversion is not possible
   * @see #getDeterminant()
   */
  public AffineTransform createInverse()
    throws NoninvertibleTransformException
  {
    double det = getDeterminant();
    if (det == 0)
      throw new NoninvertibleTransformException("can't invert transform");
    return new AffineTransform(m11 / det, -m10 / det, m01 / det, -m00 / det,
                               -m02, -m12);
  }

  /**
   * Perform this transformation on the given source point, and store the
   * result in the destination (creating it if necessary). It is safe for
   * src and dst to be the same.
   *
   * @param src the source point
   * @param dst the destination, or null
   * @return the transformation of src, in dst if it was non-null
   * @throws NullPointerException if src is null
   */
  public Point2D transform(Point2D src, Point2D dst)
  {
    if (dst == null)
      dst = new Point2D.Double();
    double x = src.getX();
    double y = src.getY();
    double nx = m00 * x + m01 * y + m02;
    double ny = m10 * x + m11 * y + m12;
    dst.setLocation(nx, ny);
    return dst;
  }

  /**
   * Perform this transformation on an array of points, storing the results
   * in another (possibly same) array. This will not create a destination
   * array, but will create points for the null entries of the destination.
   * The transformation is done sequentially. While having a single source
   * and destination point be the same is safe, you should be aware that
   * duplicate references to the same point in the source, and having the
   * source overlap the destination, may result in your source points changing
   * from a previous transform before it is their turn to be evaluated.
   *
   * @param src the array of source points
   * @param srcOff the starting offset into src
   * @param dst the array of destination points (may have null entries)
   * @param dstOff the starting offset into dst
   * @param num the number of points to transform
   * @throws NullPointerException if src or dst is null, or src has null
   *         entries
   * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
   * @throws ArrayStoreException if new points are incompatible with dst
   */
  public void transform(Point2D[] src, int srcOff,
                        Point2D[] dst, int dstOff, int num)
  {
    while (--num >= 0)
      dst[dstOff] = transform(src[srcOff++], dst[dstOff++]);
  }

  /**
   * Perform this transformation on an array of points, in (x,y) pairs,
   * storing the results in another (possibly same) array. This will not
   * create a destination array. All sources are copied before the
   * transformation, so that no result will overwrite a point that has not yet
   * been evaluated.
   *
   * @param src the array of source points
   * @param srcOff the starting offset into src
   * @param dst the array of destination points
   * @param dstOff the starting offset into dst
   * @param num the number of points to transform
   * @throws NullPointerException if src or dst is null
   * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
   */
  public void transform(float[] srcPts, int srcOff,
                        float[] dstPts, int dstOff, int num)
  {
    if (srcPts == dstPts && dstOff > srcOff
        && num > 1 && srcOff + 2 * num > dstOff)
      {
        float[] f = new float[2 * num];
        System.arraycopy(srcPts, srcOff, f, 0, 2 * num);
        srcPts = f;
      }
    while (--num >= 0)
      {
        float x = srcPts[srcOff++];
        float y = srcPts[srcOff++];
        dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02);
        dstPts[dstOff++] = (float) (m10 * x + m11 * y + m12);
      }
  }

  /**
   * Perform this transformation on an array of points, in (x,y) pairs,
   * storing the results in another (possibly same) array. This will not
   * create a destination array. All sources are copied before the
   * transformation, so that no result will overwrite a point that has not yet
   * been evaluated.
   *
   * @param src the array of source points
   * @param srcOff the starting offset into src
   * @param dst the array of destination points
   * @param dstOff the starting offset into dst
   * @param num the number of points to transform
   * @throws NullPointerException if src or dst is null
   * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
   */
  public void transform(double[] srcPts, int srcOff,
                        double[] dstPts, int dstOff, int num)
  {
    if (srcPts == dstPts && dstOff > srcOff
        && num > 1 && srcOff + 2 * num > dstOff)
      {
        double[] d = new double[2 * num];
        System.arraycopy(srcPts, srcOff, d, 0, 2 * num);
        srcPts = d;
      }
    while (--num >= 0)
      {
        double x = srcPts[srcOff++];
        double y = srcPts[srcOff++];
        dstPts[dstOff++] = m00 * x + m01 * y + m02;
        dstPts[dstOff++] = m10 * x + m11 * y + m12;
      }
  }

  /**
   * Perform this transformation on an array of points, in (x,y) pairs,
   * storing the results in another array. This will not create a destination
   * array.
   *
   * @param src the array of source points
   * @param srcOff the starting offset into src
   * @param dst the array of destination points
   * @param dstOff the starting offset into dst
   * @param num the number of points to transform
   * @throws NullPointerException if src or dst is null
   * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
   */
  public void transform(float[] srcPts, int srcOff,
                        double[] dstPts, int dstOff, int num)
  {
    while (--num >= 0)
      {
        float x = srcPts[srcOff++];
        float y = srcPts[srcOff++];
        dstPts[dstOff++] = m00 * x + m01 * y + m02;
        dstPts[dstOff++] = m10 * x + m11 * y + m12;
      }
  }

  /**
   * Perform this transformation on an array of points, in (x,y) pairs,
   * storing the results in another array. This will not create a destination
   * array.
   *
   * @param src the array of source points
   * @param srcOff the starting offset into src
   * @param dst the array of destination points
   * @param dstOff the starting offset into dst
   * @param num the number of points to transform
   * @throws NullPointerException if src or dst is null
   * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
   */
  public void transform(double[] srcPts, int srcOff,
                        float[] dstPts, int dstOff, int num)
  {
    while (--num >= 0)
      {
        double x = srcPts[srcOff++];
        double y = srcPts[srcOff++];
        dstPts[dstOff++] = (float) (m00 * x + m01 * y + m02);
        dstPts[dstOff++] = (float) (m10 * x + m11 * y + m12);
      }
  }

  /**
   * Perform the inverse of this transformation on the given source point,
   * and store the result in the destination (creating it if necessary). It
   * is safe for src and dst to be the same.
   *
   * @param src the source point
   * @param dst the destination, or null
   * @return the inverse transformation of src, in dst if it was non-null
   * @throws NullPointerException if src is null
   * @throws NoninvertibleTransformException if the inverse does not exist
   * @see #getDeterminant()
   */
  public Point2D inverseTransform(Point2D src, Point2D dst)
    throws NoninvertibleTransformException
  {
    double det = getDeterminant();
    if (det == 0)
      throw new NoninvertibleTransformException("couldn't invert transform");
    if (dst == null)
      dst = new Point2D.Double();
    double x = src.getX();
    double y = src.getY();
    double nx = (m11 * x + -m10 * y) / det - m02;
    double ny = (m01 * x + -m00 * y) / det - m12;
    dst.setLocation(nx, ny);
    return dst;
  }

  /**
   * Perform the inverse of this transformation on an array of points, in
   * (x,y) pairs, storing the results in another (possibly same) array. This
   * will not create a destination array. All sources are copied before the
   * transformation, so that no result will overwrite a point that has not yet
   * been evaluated.
   *
   * @param src the array of source points
   * @param srcOff the starting offset into src
   * @param dst the array of destination points
   * @param dstOff the starting offset into dst
   * @param num the number of points to transform
   * @throws NullPointerException if src or dst is null
   * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
   * @throws NoninvertibleTransformException if the inverse does not exist
   * @see #getDeterminant()
   */
  public void inverseTransform(double[] srcPts, int srcOff,
                               double[] dstPts, int dstOff, int num)
    throws NoninvertibleTransformException
  {
    double det = getDeterminant();
    if (det == 0)
      throw new NoninvertibleTransformException("couldn't invert transform");
    if (srcPts == dstPts && dstOff > srcOff
        && num > 1 && srcOff + 2 * num > dstOff)
      {
        double[] d = new double[2 * num];
        System.arraycopy(srcPts, srcOff, d, 0, 2 * num);
        srcPts = d;
      }
    while (--num >= 0)
      {
        double x = srcPts[srcOff++];
        double y = srcPts[srcOff++];
        dstPts[dstOff++] = (m11 * x + -m10 * y) / det - m02;
        dstPts[dstOff++] = (m01 * x + -m00 * y) / det - m12;
      }
  }

  /**
   * Perform this transformation, less any translation, on the given source
   * point, and store the result in the destination (creating it if
   * necessary). It is safe for src and dst to be the same. The reduced
   * transform is equivalent to:
   * <pre>
   * [ x' ] = [ m00 m01 ] [ x ] = [ m00 * x + m01 * y ]
   * [ y' ]   [ m10 m11 ] [ y ] = [ m10 * x + m11 * y ]
   * </pre>
   *
   * @param src the source point
   * @param dst the destination, or null
   * @return the delta transformation of src, in dst if it was non-null
   * @throws NullPointerException if src is null
   */
  public Point2D deltaTransform(Point2D src, Point2D dst)
  {
    if (dst == null)
      dst = new Point2D.Double();
    double x = src.getX();
    double y = src.getY();
    double nx = m00 * x + m01 * y;
    double ny = m10 * x + m11 * y;
    dst.setLocation(nx, ny);
    return dst;
  }

  /**
   * Perform this transformation, less any translation, on an array of points,
   * in (x,y) pairs, storing the results in another (possibly same) array.
   * This will not create a destination array. All sources are copied before
   * the transformation, so that no result will overwrite a point that has
   * not yet been evaluated. The reduced transform is equivalent to:
   * <pre>
   * [ x' ] = [ m00 m01 ] [ x ] = [ m00 * x + m01 * y ]
   * [ y' ]   [ m10 m11 ] [ y ] = [ m10 * x + m11 * y ]
   * </pre>
   *
   * @param src the array of source points
   * @param srcOff the starting offset into src
   * @param dst the array of destination points
   * @param dstOff the starting offset into dst
   * @param num the number of points to transform
   * @throws NullPointerException if src or dst is null
   * @throws ArrayIndexOutOfBoundsException if array bounds are exceeded
   */
  public void deltaTransform(double[] srcPts, int srcOff,
                              double[] dstPts, int dstOff,
                              int num)
  {
    if (srcPts == dstPts && dstOff > srcOff
        && num > 1 && srcOff + 2 * num > dstOff)
      {
        double[] d = new double[2 * num];
        System.arraycopy(srcPts, srcOff, d, 0, 2 * num);
        srcPts = d;
      }
    while (--num >= 0)
      {
        double x = srcPts[srcOff++];
        double y = srcPts[srcOff++];
        dstPts[dstOff++] = m00 * x + m01 * y;
        dstPts[dstOff++] = m10 * x + m11 * y;
      }
  }

  /**
   * Return a new Shape, based on the given one, where the path of the shape
   * has been transformed by this transform. Notice that this uses GeneralPath,
   * which only stores points in float precision.
   *
   * @param src the shape source to transform
   * @return the shape, transformed by this
   * @throws NullPointerException if src is null
   * @see GeneralPath#transform(AffineTransform)
   */
  public Shape createTransformedShape(Shape src)
  {
    GeneralPath p = new GeneralPath(src);
    p.transform(this);
    return p;
  }

  /**
   * Returns a string representation of the transform, in the format:
   * <code>"AffineTransform[[" + m00 + ", " + m01 + ", " + m02 + "], ["
   *   + m10 + ", " + m11 + ", " + m12 + "]]"</code>.
   *
   * @return the string representation
   */
  public String toString()
  {
    return "AffineTransform[[" + m00 + ", " + m01 + ", " + m02 + "], ["
      + m10 + ", " + m11 + ", " + m12 + "]]";
  }

  /**
   * Tests if this transformation is the identity:
   * <pre>
   * [ 1 0 0 ]
   * [ 0 1 0 ]
   * [ 0 0 1 ]
   * </pre>
   *
   * @return true if this is the identity transform
   */
  public boolean isIdentity()
  {
    // Rather than rely on type, check explicitly.
    return (m00 == 1 && m01 == 0 && m02 == 0
            && m10 == 0 && m11 == 1 && m12 == 0);
  }

  /**
   * Create a new transform of the same run-time type, with the same
   * transforming properties as this one.
   *
   * @return the clone
   */
  public Object clone()
  {
    try
      {
        return super.clone();
      }
    catch (CloneNotSupportedException e)
      {
        throw (Error) new InternalError().initCause(e); // Impossible
      }
  }

  /**
   * Return the hashcode for this transformation. The formula is not
   * documented, but appears to be the same as:
   * <pre>
   * long l = Double.doubleToLongBits(getScaleX());
   * l = l * 31 + Double.doubleToLongBits(getShearY());
   * l = l * 31 + Double.doubleToLongBits(getShearX());
   * l = l * 31 + Double.doubleToLongBits(getScaleY());
   * l = l * 31 + Double.doubleToLongBits(getTranslateX());
   * l = l * 31 + Double.doubleToLongBits(getTranslateY());
   * return (int) ((l >> 32) ^ l);
   * </pre>
   *
   * @return the hashcode
   */
  public int hashCode()
  {
    long l = Double.doubleToLongBits(m00);
    l = l * 31 + Double.doubleToLongBits(m10);
    l = l * 31 + Double.doubleToLongBits(m01);
    l = l * 31 + Double.doubleToLongBits(m11);
    l = l * 31 + Double.doubleToLongBits(m02);
    l = l * 31 + Double.doubleToLongBits(m12);
    return (int) ((l >> 32) ^ l);
  }

  /**
   * Compares two transforms for equality. This returns true if they have the
   * same matrix values.
   *
   * @param o the transform to compare
   * @return true if it is equal
   */
  public boolean equals(Object obj)
  {
    if (! (obj instanceof AffineTransform))
      return false;
    AffineTransform t = (AffineTransform) obj;
    return (m00 == t.m00 && m01 == t.m01 && m02 == t.m02
            && m10 == t.m10 && m11 == t.m11 && m12 == t.m12);
  }

  /**
   * Helper to decode the type from the matrix. This is not guaranteed
   * to find the optimal type, but at least it will be valid.
   */
  private void updateType()
  {
    double det = getDeterminant();
    if (det == 0)
      {
        type = TYPE_GENERAL_TRANSFORM;
        return;
      }
    // Scale (includes rotation by PI) or translation.
    if (m01 == 0 && m10 == 0)
      {
        if (m00 == m11)
          type = m00 == 1 ? TYPE_IDENTITY : TYPE_UNIFORM_SCALE;
        else
          type = TYPE_GENERAL_SCALE;
        if (m02 != 0 || m12 != 0)
          type |= TYPE_TRANSLATION;
      }
    // Rotation.
    else if (m00 == m11 && m01 == -m10)
      {
        type = m00 == 0 ? TYPE_QUADRANT_ROTATION : TYPE_GENERAL_ROTATION;
        if (det != 1)
          type |= TYPE_UNIFORM_SCALE;
        if (m02 != 0 || m12 != 0)
          type |= TYPE_TRANSLATION;
      }
    else
      type = TYPE_GENERAL_TRANSFORM;
  }

  /**
   * Reads a transform from an object stream.
   *
   * @param s the stream to read from
   * @throws ClassNotFoundException if there is a problem deserializing
   * @throws IOException if there is a problem deserializing
   */
  private void readObject(ObjectInputStream s)
    throws ClassNotFoundException, IOException
  {
    s.defaultReadObject();
    updateType();
  }
} // class AffineTransform
