/* AffineTransform.java -- transform coordinates between two 2-D spaces
   Copyright (C) 2000, 2001, 2002, 2004 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., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 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 {@link #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 shearing 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 scaling 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.m02 = tx;
    t.m12 = ty;
    t.type = (tx == 0 && ty == 0) ? TYPE_UNIFORM_SCALE : TYPE_TRANSLATION;
    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.
   *
   * @return The type.
   * 
   * @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 + (shy * m01);
    double n01 = m01 + (shx * m00);
    double n10 = m10 + (shy * m11);
    double n11 = m11 + (shx * m10);
    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.
   *
   * The inverse is calculated as:
   * 
   * <pre>
   *
   * Let A be the matrix for which we want to find the inverse:
   *
   * A = [ m00 m01 m02 ]
   *     [ m10 m11 m12 ]
   *     [ 0   0   1   ] 
   *
   *
   *                 1    
   * inverse (A) =  ---   x  adjoint(A) 
   *                det 
   *
   *
   *
   *             =   1       [  m11  -m01   m01*m12-m02*m11  ]
   *                ---   x  [ -m10   m00  -m00*m12+m10*m02  ]
   *                det      [  0     0     m00*m11-m10*m01  ]
   *
   *
   *
   *             = [  m11/det  -m01/det   m01*m12-m02*m11/det ]
   *               [ -m10/det   m00/det  -m00*m12+m10*m02/det ]
   *               [   0           0          1               ]
   *
   *
   * </pre>
   *
   *
   *
   * @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");
    
    double im00 = m11 / det;
    double im10 = -m10 / det;
    double im01 = -m01 / det;
    double im11 = m00 / det;
    double im02 = (m01 * m12 - m02 * m11) / det;
    double im12 = (-m00 * m12 + m10 * m02) / det;
    
    return new AffineTransform (im00, im10, im01, im11, im02, im12);
  }

  /**
   * 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 srcPts the array of source points
   * @param srcOff the starting offset into src
   * @param dstPts 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 srcPts the array of source points
   * @param srcOff the starting offset into src
   * @param dstPts 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 srcPts the array of source points
   * @param srcOff the starting offset into src
   * @param dstPts 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 srcPts the array of source points
   * @param srcOff the starting offset into src
   * @param dstPts 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
  {
    return createInverse().transform(src, 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 srcPts the array of source points
   * @param srcOff the starting offset into src
   * @param dstPts 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
  {
    createInverse().transform(srcPts, srcOff, dstPts, dstOff, num);
  }

  /**
   * 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 srcPts the array of source points
   * @param srcOff the starting offset into src
   * @param dstPts 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, <code>null</code> if src is 
   * <code>null</code>.
   * @see GeneralPath#transform(AffineTransform)
   */
  public Shape createTransformedShape(Shape src)
  {
    if(src == null) 
      return null;
    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 obj 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
