Class AffineTransform2D
- All Implemented Interfaces:
Serializable
,Cloneable
,LinearTransform2D
,Parameterized
,LinearTransform
,LenientComparable
,org.opengis.referencing.operation.MathTransform
,org.opengis.referencing.operation.MathTransform2D
- Direct Known Subclasses:
ParameterizedAffine
AffineTransform
and implements MathTransform2D
, so it can be used as a bridge
between Java2D and the referencing module. Note that this bridge role involves a tricky issue with
the equals
method, hopefully to occur only in exceptional corner cases.- Since:
- 0.5
- Version:
- 1.3
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionprivate AffineTransform2D
The inverse transform.private AffineMatrix
The matrix, ornull
if not yet computed.private static final long
Serial number for inter-operability with different versions.Fields inherited from class java.awt.geom.AffineTransform
TYPE_FLIP, TYPE_GENERAL_ROTATION, TYPE_GENERAL_SCALE, TYPE_GENERAL_TRANSFORM, TYPE_IDENTITY, TYPE_MASK_ROTATION, TYPE_MASK_SCALE, TYPE_QUADRANT_ROTATION, TYPE_TRANSLATION, TYPE_UNIFORM_SCALE
-
Constructor Summary
ConstructorsModifierConstructorDescriptionAffineTransform2D
(double[] elements) Creates a new transform from an array of values representing either the 4 non-translation entries or the 6 specifiable entries of the 3×3 matrix.AffineTransform2D
(double m00, double m10, double m01, double m11, double m02, double m12) Creates a newAffineTransform2D
from 6 values representing the 6 specifiable entries of the 3×3 transformation matrix.AffineTransform2D
(double m00, double m10, double m01, double m11, double m02, double m12, boolean modifiable) Creates a potentially modifiable transform initialized to the 6 specifiable entries.AffineTransform2D
(AffineTransform transform) Creates a new affine transform with the same coefficients than the specified transform.Creates a newAffineTransform2D
from the 9 or 18 values of the given matrix.private
AffineTransform2D
(ExtendedPrecisionMatrix m, double[] elements) Work around for RFE #4093999 in Sun's bug database ("Relax constraint on placement of this()/super() call in constructors"). -
Method Summary
Modifier and TypeMethodDescriptionprotected final void
Throws anUnsupportedOperationException
when a mutable method is invoked, sinceAffineTransform2D
must be immutable.clone()
Returns a new affine transform which is a modifiable copy of this transform.final Shape
createTransformedShape
(Shape shape) Transforms the specified shape.final org.opengis.referencing.operation.Matrix
derivative
(Point2D point) Gets the derivative of this transform at a point.final org.opengis.referencing.operation.Matrix
derivative
(org.opengis.geometry.DirectPosition point) Gets the derivative of this transform at a point.boolean
Compares this affine transform with the given object for equality.boolean
equals
(Object object, ComparisonMode mode) Compares this affine transform with the given object for equality.final void
freeze()
Ensures that this transform contains only positive zeros, then marks this transform as unmodifiable.final org.opengis.referencing.operation.Matrix
Returns this transform as an affine transform matrix.org.opengis.parameter.ParameterDescriptorGroup
Returns the parameter descriptors for this math transform.org.opengis.parameter.ParameterValueGroup
Returns the matrix elements as a group of parameter values.final int
Gets the dimension of input points, which is fixed to 2.final int
Gets the dimension of output points, which is fixed to 2.final AffineTransform2D
inverse()
Creates the inverse transform of this object.final boolean
isAffine()
Returnstrue
since this transform is affine.private static double
pz
(double value) Makes sure that the zero is positive.toString()
Returns a string representation of this transform as a matrix, for consistency with otherLinearTransform
implementations in Apache SIS.toWKT()
Returns the WKT for this transform.final org.opengis.geometry.DirectPosition
transform
(org.opengis.geometry.DirectPosition ptSrc, org.opengis.geometry.DirectPosition ptDst) Transforms the specifiedptSrc
and stores the result inptDst
.Methods inherited from class org.apache.sis.internal.referencing.j2d.ImmutableAffineTransform
concatenate, invert, preConcatenate, quadrantRotate, quadrantRotate, rotate, rotate, rotate, rotate, scale, setToIdentity, setToQuadrantRotation, setToQuadrantRotation, setToRotation, setToRotation, setToRotation, setToRotation, setToScale, setToShear, setToTranslation, setTransform, setTransform, shear, translate
Methods inherited from class java.awt.geom.AffineTransform
createInverse, deltaTransform, deltaTransform, getDeterminant, getMatrix, getQuadrantRotateInstance, getQuadrantRotateInstance, getRotateInstance, getRotateInstance, getRotateInstance, getRotateInstance, getScaleInstance, getScaleX, getScaleY, getShearInstance, getShearX, getShearY, getTranslateInstance, getTranslateX, getTranslateY, getType, hashCode, inverseTransform, inverseTransform, isIdentity, transform, transform, transform, transform, transform, transform
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
Methods inherited from interface org.apache.sis.referencing.operation.transform.LinearTransform
deltaTransform
Methods inherited from interface org.opengis.referencing.operation.MathTransform
isIdentity, transform, transform, transform, transform
Methods inherited from interface org.opengis.referencing.operation.MathTransform2D
transform
-
Field Details
-
serialVersionUID
private static final long serialVersionUIDSerial number for inter-operability with different versions.- See Also:
-
matrix
The matrix, ornull
if not yet computed.This field is also used for determining if the affine transform is mutable. If this field is
null
(which should be a temporary state), then this means that this affine transform is still under construction. This field must be set to a non-null value before anAffineTransform2D
instance is published.- See Also:
-
inverse
The inverse transform. This field will be computed only when needed.- See Also:
-
-
Constructor Details
-
AffineTransform2D
Creates a new affine transform with the same coefficients than the specified transform.- Parameters:
transform
- the affine transform to copy.
-
AffineTransform2D
public AffineTransform2D(double[] elements) Creates a new transform from an array of values representing either the 4 non-translation entries or the 6 specifiable entries of the 3×3 matrix.- Parameters:
elements
- the matrix elements in an array of length 4 or 6.
-
AffineTransform2D
Creates a newAffineTransform2D
from the 9 or 18 values of the given matrix.- Parameters:
matrix
- the matrix from which to get the (potentially extended) elements.
-
AffineTransform2D
@Workaround(library="JDK", version="1.7") private AffineTransform2D(ExtendedPrecisionMatrix m, double[] elements) Work around for RFE #4093999 in Sun's bug database ("Relax constraint on placement of this()/super() call in constructors"). -
AffineTransform2D
public AffineTransform2D(double m00, double m10, double m01, double m11, double m02, double m12) Creates a newAffineTransform2D
from 6 values representing the 6 specifiable entries of the 3×3 transformation matrix. Those values are given unchanged to thesuper class constructor
, except for negative zeros that are replaced by positive zeros.- Parameters:
m00
- the X coordinate scaling.m10
- the Y coordinate shearing.m01
- the X coordinate shearing.m11
- the Y coordinate scaling.m02
- the X coordinate translation.m12
- the Y coordinate translation.
-
AffineTransform2D
public AffineTransform2D(double m00, double m10, double m01, double m11, double m02, double m12, boolean modifiable) Creates a potentially modifiable transform initialized to the 6 specifiable entries. Caller shall invokefreeze()
before to publish this transform.- Parameters:
m00
- the X coordinate scaling.m10
- the Y coordinate shearing.m01
- the X coordinate shearing.m11
- the Y coordinate scaling.m02
- the X coordinate translation.m12
- the Y coordinate translation.modifiable
- whether the transform should be modifiable.
-
-
Method Details
-
pz
Makes sure that the zero is positive. We do that in order to workaround a JDK 6 to 8 bug, whereAffineTransform.hashCode()
is inconsistent withAffineTransform.equals(Object)
if there is zeros of opposite sign.The inconsistency is in the use of
JDK-8290973Double.doubleToLongBits(double)
for hash code and==
for testing equality. The former is sensitive to the sign of 0 while the latter is not. -
freeze
public final void freeze()Ensures that this transform contains only positive zeros, then marks this transform as unmodifiable. -
checkPermission
Throws anUnsupportedOperationException
when a mutable method is invoked, sinceAffineTransform2D
must be immutable.- Overrides:
checkPermission
in classImmutableAffineTransform
- Throws:
UnsupportedOperationException
- always thrown.
-
isAffine
public final boolean isAffine()Returnstrue
since this transform is affine.- Specified by:
isAffine
in interfaceLinearTransform
- Returns:
true
if this transform is affine.- See Also:
-
getParameterDescriptors
public org.opengis.parameter.ParameterDescriptorGroup getParameterDescriptors()Returns the parameter descriptors for this math transform.- Specified by:
getParameterDescriptors
in interfaceParameterized
- Returns:
- the parameter descriptors for this object, or
null
.
-
getParameterValues
public org.opengis.parameter.ParameterValueGroup getParameterValues()Returns the matrix elements as a group of parameter values. The number of parameters depends on the matrix size. Only matrix elements different from their default value will be included in this group.- Specified by:
getParameterValues
in interfaceParameterized
- Returns:
- the parameter values for this object, or
null
if unknown.
-
getSourceDimensions
public final int getSourceDimensions()Gets the dimension of input points, which is fixed to 2.- Specified by:
getSourceDimensions
in interfaceorg.opengis.referencing.operation.MathTransform
-
getTargetDimensions
public final int getTargetDimensions()Gets the dimension of output points, which is fixed to 2.- Specified by:
getTargetDimensions
in interfaceorg.opengis.referencing.operation.MathTransform
-
transform
public final org.opengis.geometry.DirectPosition transform(org.opengis.geometry.DirectPosition ptSrc, org.opengis.geometry.DirectPosition ptDst) Transforms the specifiedptSrc
and stores the result inptDst
.- Specified by:
transform
in interfaceorg.opengis.referencing.operation.MathTransform
-
createTransformedShape
Transforms the specified shape. This method creates a simpler shape then the default super-class implementation. For example if the given shape is a rectangle and this affine transform has no scale or shear, then the returned shape will be an instance ofRectangle2D
.- Specified by:
createTransformedShape
in interfaceorg.opengis.referencing.operation.MathTransform2D
- Overrides:
createTransformedShape
in classAffineTransform
- Parameters:
shape
- shape to transform.- Returns:
- transformed shape, or
shape
if this transform is the identity transform.
-
getMatrix
public final org.opengis.referencing.operation.Matrix getMatrix()Returns this transform as an affine transform matrix.- Specified by:
getMatrix
in interfaceLinearTransform
- Returns:
- the coefficients of this linear transform as a matrix.
- See Also:
-
derivative
Gets the derivative of this transform at a point. For an affine transform, the derivative is the same everywhere.- Specified by:
derivative
in interfaceorg.opengis.referencing.operation.MathTransform2D
-
derivative
public final org.opengis.referencing.operation.Matrix derivative(org.opengis.geometry.DirectPosition point) Gets the derivative of this transform at a point. For an affine transform, the derivative is the same everywhere.- Specified by:
derivative
in interfaceorg.opengis.referencing.operation.MathTransform
-
inverse
public final AffineTransform2D inverse() throws org.opengis.referencing.operation.NoninvertibleTransformExceptionCreates the inverse transform of this object.- Specified by:
inverse
in interfaceLinearTransform
- Specified by:
inverse
in interfaceLinearTransform2D
- Specified by:
inverse
in interfaceorg.opengis.referencing.operation.MathTransform
- Specified by:
inverse
in interfaceorg.opengis.referencing.operation.MathTransform2D
- Returns:
- the inverse transform.
- Throws:
org.opengis.referencing.operation.NoninvertibleTransformException
- if this transform cannot be inverted.- See Also:
-
equals
Compares this affine transform with the given object for equality. This method behaves as documented in theLenientComparable.equals(…)
method, except for the following case: if the given mode isComparisonMode.STRICT
, then this method delegates toequals(Object)
. The latter method has different rules than the ones documented in theLenientComparable
interface, because of theAffineTransform
inheritance.- Specified by:
equals
in interfaceLenientComparable
- Parameters:
object
- the object to compare tothis
.mode
- the strictness level of the comparison.- Returns:
true
if both objects are equal.- See Also:
-
equals
Compares this affine transform with the given object for equality. The comparison is performed in the same way thanAffineTransform.equals(Object)
with one additional rule: if the other object is also an instance ofAffineTransform2D
, then the two objects must be of the exact same class.Most SIS implementations require that the objects being compared are unconditionally of the same class in order to be considered equal. However, many JDK implementations, including
AffineTransform
, do not have this requirement. Consequently, the above condition (i.e. require the same class only if the given object is anAffineTransform2D
or a subclass) is necessary in order to preserve the symmetricity contract ofObject.equals(Object)
.A side-effect of this implementation is that the transitivity contract of
Object.equals(Object)
may be broken is some corner cases. This contract said:a.equals(b)
andb.equals(c)
impliesa.equals(c)
AffineTransform
(where "instance of T" means T or any subclass of T), then the transitivity contract is broken if and only if exactly two of those objects are instance ofAffineTransform2D
and those two objects are not of the same class. Note that this implies that at least one subclass ofAffineTransform2D
is used.In the vast majority of cases, the transitivity contract is not broken and the users can ignore this documentation. The transitivity contract is typically not broken either because we usually don't subclass
AffineTransform2D
, or because we don't mixAffineTransform
withAffineTransform2D
subclasses in the same collection.This special case exists in order to allow developers to attach additional information to their own subclass of
AffineTransform2D
, and still distinguish their specialized subclass from ordinary affine transforms in a pool ofMathTransform
instances. The main application is the Equirectangular map projection, which can be simplified to an affine transform but still needs to remember the projection parameters.- Specified by:
equals
in interfaceLenientComparable
- Overrides:
equals
in classAffineTransform
- Parameters:
object
- the object to compare with this affine transform for equality.- Returns:
true
if the given object is of appropriate class (as explained in the above documentation) and the affine transform coefficients are the same.- See Also:
-
clone
Returns a new affine transform which is a modifiable copy of this transform. This implementation always returns an instance ofAffineTransform
, notAffineTransform2D
, because the latter is unmodifiable and cloning it make little sense.- Overrides:
clone
in classAffineTransform
- Returns:
- a modifiable copy of this affine transform.
-
toWKT
Returns the WKT for this transform.- Specified by:
toWKT
in interfaceorg.opengis.referencing.operation.MathTransform
-
toString
Returns a string representation of this transform as a matrix, for consistency with otherLinearTransform
implementations in Apache SIS.- Overrides:
toString
in classAffineTransform
-