com.vividsolutions.jump.geom
Class AffineTransformation

java.lang.Object
  extended by com.vividsolutions.jump.geom.AffineTransformation
All Implemented Interfaces:
com.vividsolutions.jts.geom.CoordinateFilter, java.lang.Cloneable

public class AffineTransformation
extends java.lang.Object
implements java.lang.Cloneable, com.vividsolutions.jts.geom.CoordinateFilter

This class represents a affine transformation on the 2D Cartesian plane. It can be used to transform a Coordinate or Geometry. An affine transformation is a mapping of the 2D plane into itself via a series of transformations of the following basic types:

In general, affine transformations preserve straightness and parallel lines, but do not preserve distance or shape.

An affine transformation can be represented by a 3x3 matrix in the following form:

 T = | m00 m01 m02 |
     | m10 m11 m12 |
     |  0   0   1  |
 
A coordinate P = (x, y) can be transformed to a new coordinate P' = (x', y') by representing it as a 3x1 matrix and using matrix multiplication to compute:
 | x' |  = T x | x |
 | y' |        | y |
 | 1  |        | 1 |
 
Affine transformations can be composed using the compose(com.vividsolutions.jump.geom.AffineTransformation) method. Composition is not commutative. Composition is computed via multiplication of the transformation matrices as follows:
 A.compose(B) = TB x TA
 
This produces a transformation whose effect is that of A followed by B. The methods reflect(double, double, double, double), rotate(double), scale(double, double), shear(double, double), and translate(double, double) have the effect of composing a transformation of that type with the transformation they are applied to.

Author:
Martin Davis

Constructor Summary
AffineTransformation()
          Constructs a new identity transformation
AffineTransformation(AffineTransformation trans)
          Constructs a transformation which is a copy of the given one.
AffineTransformation(com.vividsolutions.jts.geom.Coordinate src0, com.vividsolutions.jts.geom.Coordinate src1, com.vividsolutions.jts.geom.Coordinate src2, com.vividsolutions.jts.geom.Coordinate dest0, com.vividsolutions.jts.geom.Coordinate dest1, com.vividsolutions.jts.geom.Coordinate dest2)
          Constructs a transformation which maps the given source points into the given destination points.
AffineTransformation(double[] matrix)
          Constructs a new transformation whose matrix has the specified values.
AffineTransformation(double m00, double m01, double m02, double m10, double m11, double m12)
          Constructs a new transformation whose matrix has the specified values.
 
Method Summary
 java.lang.Object clone()
          Clones this transformation
 AffineTransformation compose(AffineTransformation trans)
          Composes the given AffineTransformation with this transformation.
 AffineTransformation composeBefore(AffineTransformation trans)
          Composes this transformation with the given AffineTransformation.
 boolean equals(java.lang.Object obj)
          Tests if an object is an AffineTransformation and has the same matrix as this transformation.
 void filter(com.vividsolutions.jts.geom.Coordinate pt)
           
 double getDeterminant()
          Computes the determinant of the transformation matrix.
 AffineTransformation getInverse()
          Computes the inverse of this transformation, if one exists.
 double[] getMatrixEntries()
          Gets an array containing the entries of the transformation matrix.
 boolean isIdentity()
          Tests if this transformation is the identity transformation.
 AffineTransformation reflect(double x, double y)
          Updates the value of this transformation to that of a reflection transformation composed with the current value.
 AffineTransformation reflect(double x0, double y0, double x1, double y1)
          Updates the value of this transformation to that of a reflection transformation composed with the current value.
static AffineTransformation reflectionInstance(double x, double y)
          Creates a transformation for a reflection about the line (0,0) - (x,y).
static AffineTransformation reflectionInstance(double x0, double y0, double x1, double y1)
          Creates a transformation for a reflection about the line (x0,y0) - (x1,y1).
 AffineTransformation rotate(double theta)
          Updates the value of this transformation to that of a rotation transformation composed with the current value.
 AffineTransformation rotate(double sinTheta, double cosTheta)
          Updates the value of this transformation to that of a rotation transformation composed with the current value.
static AffineTransformation rotationInstance(double theta)
          Creates a transformation for a rotation about the origin by an angle theta.
static AffineTransformation rotationInstance(double sinTheta, double cosTheta)
          Creates a transformation for a rotation by an angle theta, specified by the sine and cosine of the angle.
 AffineTransformation scale(double xScale, double yScale)
          Updates the value of this transformation to that of a scale transformation composed with the current value.
static AffineTransformation scaleInstance(double xScale, double yScale)
           
 AffineTransformation setToIdentity()
          Sets this transformation to be the identity transformation.
 AffineTransformation setToReflection(double x, double y)
          Sets this transformation to be a reflection about the line defined by vector (x,y).
 AffineTransformation setToReflection(double x0, double y0, double x1, double y1)
           
 AffineTransformation setToReflectionBasic(double x0, double y0, double x1, double y1)
          Explicitly computes the math for a reflection.
 AffineTransformation setToRotation(double sinTheta, double cosTheta)
          Sets this transformation to be a rotation by specifying the sin and cos of the rotation angle directly.
 AffineTransformation setToScale(double xScale, double yScale)
          Sets this transformation to be a scaling.
 AffineTransformation setToShear(double xShear, double yShear)
          Sets this transformation to be a shear.
 AffineTransformation setToTranslation(double dx, double dy)
          Sets this transformation to be a translation.
 AffineTransformation setTransformation(AffineTransformation trans)
          Sets this transformation to be a copy of the given one
 AffineTransformation setTransformation(double m00, double m01, double m02, double m10, double m11, double m12)
          Sets this transformation's matrix to have the given values.
 AffineTransformation shear(double xShear, double yShear)
          Updates the value of this transformation to that of a shear transformation composed with the current value.
static AffineTransformation shearInstance(double xShear, double yShear)
           
 java.lang.String toString()
          Gets a text representation of this transformation.
 com.vividsolutions.jts.geom.Coordinate transform(com.vividsolutions.jts.geom.Coordinate src, com.vividsolutions.jts.geom.Coordinate dest)
           
 com.vividsolutions.jts.geom.CoordinateSequence transform(com.vividsolutions.jts.geom.CoordinateSequence seq)
           
 AffineTransformation translate(double x, double y)
          Updates the value of this transformation to that of a translation transformation composed with the current value.
static AffineTransformation translationInstance(double x, double y)
           
 
Methods inherited from class java.lang.Object
getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

AffineTransformation

public AffineTransformation()
Constructs a new identity transformation


AffineTransformation

public AffineTransformation(double[] matrix)
Constructs a new transformation whose matrix has the specified values.

Parameters:
matrix - an array containing the 6 values { m00, m01, m02, m10, m11, m12 }
Throws:
java.lang.NullPointerException - if matrix is null
java.lang.ArrayIndexOutOfBoundsException - if matrix is too small

AffineTransformation

public AffineTransformation(double m00,
                            double m01,
                            double m02,
                            double m10,
                            double m11,
                            double m12)
Constructs a new transformation whose matrix has the specified values.

Parameters:
m00 - the entry for the [0, 0] element in the transformation matrix
m01 - the entry for the [0, 1] element in the transformation matrix
m02 - the entry for the [0, 2] element in the transformation matrix
m10 - the entry for the [1, 0] element in the transformation matrix
m11 - the entry for the [1, 1] element in the transformation matrix
m12 - the entry for the [1, 2] element in the transformation matrix

AffineTransformation

public AffineTransformation(AffineTransformation trans)
Constructs a transformation which is a copy of the given one.

Parameters:
trans - the transformation to copy

AffineTransformation

public AffineTransformation(com.vividsolutions.jts.geom.Coordinate src0,
                            com.vividsolutions.jts.geom.Coordinate src1,
                            com.vividsolutions.jts.geom.Coordinate src2,
                            com.vividsolutions.jts.geom.Coordinate dest0,
                            com.vividsolutions.jts.geom.Coordinate dest1,
                            com.vividsolutions.jts.geom.Coordinate dest2)
Constructs a transformation which maps the given source points into the given destination points.

Parameters:
src0 - source point 0
src1 - source point 1
src2 - source point 2
dest0 - the mapped point for source point 0
dest1 - the mapped point for source point 1
dest2 - the mapped point for source point 2
Method Detail

reflectionInstance

public static AffineTransformation reflectionInstance(double x0,
                                                      double y0,
                                                      double x1,
                                                      double y1)
Creates a transformation for a reflection about the line (x0,y0) - (x1,y1).

Parameters:
x0 - the x-ordinate of a point on the reflection line
y0 - the y-ordinate of a point on the reflection line
x1 - the x-ordinate of a another point on the reflection line
y1 - the y-ordinate of a another point on the reflection line
Returns:
a transformation for the reflection

reflectionInstance

public static AffineTransformation reflectionInstance(double x,
                                                      double y)
Creates a transformation for a reflection about the line (0,0) - (x,y).

Parameters:
x - the x-ordinate of a point on the reflection line
y - the y-ordinate of a point on the reflection line
Returns:
a transformation for the reflection

rotationInstance

public static AffineTransformation rotationInstance(double theta)
Creates a transformation for a rotation about the origin by an angle theta. Positive angles correspond to a rotation in the counter-clockwise direction.

Parameters:
theta - the rotation angle, in radians
Returns:
a transformation for the rotation

rotationInstance

public static AffineTransformation rotationInstance(double sinTheta,
                                                    double cosTheta)
Creates a transformation for a rotation by an angle theta, specified by the sine and cosine of the angle. This allows providing exact values for sin(theta) and cos(theta) for the common case of rotations of multiples of quarter-circles.

Parameters:
sinTheta - the sine of the rotation angle
cosTheta - the cosine of the rotation angle
Returns:
a transformation for the rotation

scaleInstance

public static AffineTransformation scaleInstance(double xScale,
                                                 double yScale)

shearInstance

public static AffineTransformation shearInstance(double xShear,
                                                 double yShear)

translationInstance

public static AffineTransformation translationInstance(double x,
                                                       double y)

setToIdentity

public AffineTransformation setToIdentity()
Sets this transformation to be the identity transformation. The identity transformation has the matrix:
 | 1 0 0 |
 | 0 1 0 |
 | 0 0 1 |
 

Returns:
this transformation, with an updated matrix

setTransformation

public AffineTransformation setTransformation(double m00,
                                              double m01,
                                              double m02,
                                              double m10,
                                              double m11,
                                              double m12)
Sets this transformation's matrix to have the given values.

Parameters:
m00 - the entry for the [0, 0] element in the transformation matrix
m01 - the entry for the [0, 1] element in the transformation matrix
m02 - the entry for the [0, 2] element in the transformation matrix
m10 - the entry for the [1, 0] element in the transformation matrix
m11 - the entry for the [1, 1] element in the transformation matrix
m12 - the entry for the [1, 2] element in the transformation matrix
Returns:
this transformation, with an updated matrix

setTransformation

public AffineTransformation setTransformation(AffineTransformation trans)
Sets this transformation to be a copy of the given one

Parameters:
trans - a transformation to copy
Returns:
this transformation, with an updated matrix

getMatrixEntries

public double[] getMatrixEntries()
Gets an array containing the entries of the transformation matrix. Only the 6 non-trivial entries are returned, in the sequence:
 m00, m01, m02, m10, m11, m12
 

Returns:
an array of length 6

getDeterminant

public double getDeterminant()
Computes the determinant of the transformation matrix. The determinant is computed as:
 | m00 m01 m02 |
 | m10 m11 m12 | = m00 * m11 - m01 * m10
 |  0   0   1  |
 
If the determinant is zero, the transform is singular (not invertible), and operations which attempt to compute an inverse will throw a NoninvertibleTransformException.

Returns:
the determinant of the transformation
See Also:
getInverse()

getInverse

public AffineTransformation getInverse()
                                throws NoninvertibleTransformationException
Computes the inverse of this transformation, if one exists. The inverse is the transformation which when composed with this one produces the identity transformation. A transformation has an inverse if and only if it is not singular (i.e. its determinant is non-zero). Geometrically, an transformation is non-invertible if it maps the plane to a line or a point. If no inverse exists this method will throw a NoninvertibleTransformationException.

The matrix of the inverse is equal to the inverse of the matrix for the transformation. It is computed as follows:

  
                 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               |

 

Returns:
a new inverse transformation
Throws:
NoninvertibleTransformationException
See Also:
getDeterminant()

setToReflectionBasic

public AffineTransformation setToReflectionBasic(double x0,
                                                 double y0,
                                                 double x1,
                                                 double y1)
Explicitly computes the math for a reflection. May not work.

Parameters:
x0 -
y0 -
x1 -
y1 -
Returns:

setToReflection

public AffineTransformation setToReflection(double x0,
                                            double y0,
                                            double x1,
                                            double y1)

setToReflection

public AffineTransformation setToReflection(double x,
                                            double y)
Sets this transformation to be a reflection about the line defined by vector (x,y). The transformation for a reflection is computed by:
 d = sqrt(x2 + y2)  
 sin = x / d;
 cos = x / d;
 
 Tref = Trot(sin, cos) x Tscale(1, -1) x Trot(-sin, cos)

Parameters:
x - the x-component of the reflection line vector
y - the y-component of the reflection line vector
Returns:
this transformation, with an updated matrix

setToRotation

public AffineTransformation setToRotation(double sinTheta,
                                          double cosTheta)
Sets this transformation to be a rotation by specifying the sin and cos of the rotation angle directly. The transformation matrix for the rotation has the value:
  
 |  cosTheta  -sinTheta   0 |
 |  sinTheta   cosTheta   0 |
 |         0          0   1 |
 

Parameters:
sinTheta - the sine of the rotation angle
cosTheta - the cosine of the rotation angle
Returns:
this transformation, with an updated matrix

setToScale

public AffineTransformation setToScale(double xScale,
                                       double yScale)
Sets this transformation to be a scaling. The transformation matrix for a scale has the value:
  
 |  xScale      0  dx |
 |  1      yScale  dy |
 |  0           0   1 |
 

Parameters:
xScale - the amount to scale x-ordinates by
yScale - the amount to scale y-ordinates by
Returns:
this transformation, with an updated matrix

setToShear

public AffineTransformation setToShear(double xShear,
                                       double yShear)
Sets this transformation to be a shear. The transformation matrix for a shear has the value:
  
 |  1      xShear  0 |
 |  yShear      1  0 |
 |  0           0  1 |
 
Note that a shear of (1, 1) is not equal to shear(1, 0) composed with shear(0, 1). Instead, shear(1, 1) corresponds to a mapping onto the line x = y.

Parameters:
xShear - the x component to shear by
yShear - the y component to shear by
Returns:
this transformation, with an updated matrix

setToTranslation

public AffineTransformation setToTranslation(double dx,
                                             double dy)
Sets this transformation to be a translation. For a translation by the vector (x, y) the transformation matrix has the value:
  
 |  1  0  dx |
 |  1  0  dy |
 |  0  0   1 |
 

Parameters:
dx - the x component to translate by
dy - the y component to translate by
Returns:
this transformation, with an updated matrix

reflect

public AffineTransformation reflect(double x0,
                                    double y0,
                                    double x1,
                                    double y1)
Updates the value of this transformation to that of a reflection transformation composed with the current value.

Parameters:
x0 - the x-ordinate of a point on the line to reflect around
y0 - the y-ordinate of a point on the line to reflect around
x1 - the x-ordinate of a point on the line to reflect around
y1 - the y-ordinate of a point on the line to reflect around
Returns:
this transformation, with an updated matrix

reflect

public AffineTransformation reflect(double x,
                                    double y)
Updates the value of this transformation to that of a reflection transformation composed with the current value.

Parameters:
x - the x-ordinate of the line to reflect around
y - the y-ordinate of the line to reflect around
Returns:
this transformation, with an updated matrix

rotate

public AffineTransformation rotate(double theta)
Updates the value of this transformation to that of a rotation transformation composed with the current value.

Parameters:
theta - the angle to rotate by
Returns:
this transformation, with an updated matrix

rotate

public AffineTransformation rotate(double sinTheta,
                                   double cosTheta)
Updates the value of this transformation to that of a rotation transformation composed with the current value.

Parameters:
sinTheta - the sine of the angle to rotate by
cosTheta - the cosine of the angle to rotate by
Returns:
this transformation, with an updated matrix

scale

public AffineTransformation scale(double xScale,
                                  double yScale)
Updates the value of this transformation to that of a scale transformation composed with the current value.

Parameters:
xScale - the value to scale by in the x direction
yScale - the value to scale by in the y direction
Returns:
this transformation, with an updated matrix

shear

public AffineTransformation shear(double xShear,
                                  double yShear)
Updates the value of this transformation to that of a shear transformation composed with the current value.

Parameters:
xShear - the value to shear by in the x direction
yShear - the value to shear by in the y direction
Returns:
this transformation, with an updated matrix

translate

public AffineTransformation translate(double x,
                                      double y)
Updates the value of this transformation to that of a translation transformation composed with the current value.

Parameters:
x - the value to translate by in the x direction
y - the value to translate by in the y direction
Returns:
this transformation, with an updated matrix

compose

public AffineTransformation compose(AffineTransformation trans)
Composes the given AffineTransformation with this transformation. This produces a transformation whose effect is equal to applying this transformation followed by the argument transformation. Mathematically,
 A.compose(B) = TB x TA
 

Parameters:
trans - an affine transformation
Returns:
this transformation, with an updated matrix

composeBefore

public AffineTransformation composeBefore(AffineTransformation trans)
Composes this transformation with the given AffineTransformation. This produces a transformation whose effect is equal to applying the argument transformation followed by this transformation. Mathematically,
 A.composeBefore(B) = TA x TB
 

Parameters:
trans - an affine transformation
Returns:
this transformation, with an updated matrix

transform

public com.vividsolutions.jts.geom.Coordinate transform(com.vividsolutions.jts.geom.Coordinate src,
                                                        com.vividsolutions.jts.geom.Coordinate dest)

transform

public com.vividsolutions.jts.geom.CoordinateSequence transform(com.vividsolutions.jts.geom.CoordinateSequence seq)

filter

public void filter(com.vividsolutions.jts.geom.Coordinate pt)
Specified by:
filter in interface com.vividsolutions.jts.geom.CoordinateFilter

isIdentity

public boolean isIdentity()
Tests if this transformation is the identity transformation.

Returns:
true if this is the identity transformation

equals

public boolean equals(java.lang.Object obj)
Tests if an object is an AffineTransformation and has the same matrix as this transformation.

Overrides:
equals in class java.lang.Object
Parameters:
obj - an object to test
Returns:
true if the given object is equal to this object

toString

public java.lang.String toString()
Gets a text representation of this transformation. The string is of the form:
 AffineTransformation[[m00, m01, m02], [m10, m11, m12]]
 

Overrides:
toString in class java.lang.Object
Returns:
a string representing this transformation

clone

public java.lang.Object clone()
Clones this transformation

Overrides:
clone in class java.lang.Object
Returns:
a copy of this transformation