/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2005-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotools.referencing.operation.matrix; import javax.vecmath.Matrix3d; import java.awt.geom.AffineTransform; import org.opengis.referencing.operation.Matrix; import org.geotools.resources.i18n.Errors; import org.geotools.resources.i18n.ErrorKeys; /** * A matrix of fixed {@value #SIZE}×{@value #SIZE} size. This specialized matrix provides * better accuracy than {@link GeneralMatrix} for matrix inversion and multiplication. * * @since 2.2 * * @source $URL$ * @version $Id$ * @author Martin Desruisseaux (IRD) */ public class Matrix3 extends Matrix3d implements XMatrix { /** * Serial number for interoperability with different versions. */ private static final long serialVersionUID = 8902061778871586611L; /** * The matrix size, which is {@value}. */ public static final int SIZE = 3; /** * Creates a new identity matrix. */ public Matrix3() { setIdentity(); } /** * Creates a new matrix initialized to the specified values. */ public Matrix3(double m00, double m01, double m02, double m10, double m11, double m12, double m20, double m21, double m22) { super(m00, m01, m02, m10, m11, m12, m20, m21, m22); } /** * Constructs a 3×3 matrix from the specified affine transform. */ public Matrix3(final AffineTransform transform) { setMatrix(transform); } /** * Creates a new matrix initialized to the same value than the specified one. * The specified matrix size must be {@value #SIZE}×{@value #SIZE}. */ public Matrix3(final Matrix matrix) { if (matrix.getNumRow()!=SIZE || matrix.getNumCol()!=SIZE) { throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_MATRIX_SIZE)); } for (int j=0; j<SIZE; j++) { for (int i=0; i<SIZE; i++) { setElement(j,i, matrix.getElement(j,i)); } } } /** * Returns the number of rows in this matrix, which is always {@value #SIZE} * in this implementation. */ public final int getNumRow() { return SIZE; } /** * Returns the number of colmuns in this matrix, which is always {@value #SIZE} * in this implementation. */ public final int getNumCol() { return SIZE; } /** * {@inheritDoc} */ public final boolean isIdentity() { for (int j=0; j<SIZE; j++) { for (int i=0; i<SIZE; i++) { if (getElement(j,i) != ((i==j) ? 1 : 0)) { return false; } } } return true; } /** * {@inheritDoc} */ public final boolean isIdentity(double tolerance) { return GeneralMatrix.isIdentity(this, tolerance); } /** * {@inheritDoc} */ public final boolean isAffine() { return m20==0 && m21==0 && m22==1; } /** * Returns {@code true} if at least one value is {@code NaN}. * * @since 2.3 */ public final boolean isNaN() { return Double.isNaN(m00) || Double.isNaN(m01) || Double.isNaN(m02) || Double.isNaN(m10) || Double.isNaN(m11) || Double.isNaN(m12) || Double.isNaN(m20) || Double.isNaN(m21) || Double.isNaN(m22); } /** * {@inheritDoc} */ public final void multiply(final Matrix matrix) { final Matrix3d m; if (matrix instanceof Matrix3d) { m = (Matrix3d) matrix; } else { m = new Matrix3(matrix); } mul(m); } /** * Sets this matrix to the specified affine transform. * * @since 2.3 */ public void setMatrix(final AffineTransform transform) { m00=transform.getScaleX(); m01=transform.getShearX(); m02=transform.getTranslateX(); m10=transform.getShearY(); m11=transform.getScaleY(); m12=transform.getTranslateY(); m20=0; m21=0; m22=1; } /** * Returns {@code true} if this matrix is equals to the specified affine transform. * * @since 2.3 */ public boolean equalsAffine(final AffineTransform transform) { return m00==transform.getScaleX() && m01==transform.getShearX() && m02==transform.getTranslateX() && m10==transform.getShearY() && m11==transform.getScaleY() && m12==transform.getTranslateY() && m20==0 && m21==0 && m22==1; } /** * {@inheritDoc} */ public boolean equals(final Matrix matrix, final double tolerance) { return GeneralMatrix.epsilonEquals(this, matrix, tolerance); } /** * Returns a string representation of this matrix. The returned string is implementation * dependent. It is usually provided for debugging purposes only. */ @Override public String toString() { return GeneralMatrix.toString(this); } /** * Returns a clone of this matrix. */ @Override public Matrix3 clone() { return (Matrix3) super.clone(); } }