001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2006, GeoTools Project Managment Committee (PMC)
005: * (C) 2005, Institut de Recherche pour le Développement
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.referencing.operation.matrix;
018:
019: // J2SE dependencies and extensions
020: import javax.vecmath.Matrix3d;
021: import java.awt.geom.AffineTransform;
022:
023: // OpenGIS dependencies
024: import org.opengis.referencing.operation.Matrix;
025:
026: // Geotools dependencies
027: import org.geotools.resources.i18n.Errors;
028: import org.geotools.resources.i18n.ErrorKeys;
029:
030: /**
031: * A matrix of fixed {@value #SIZE}×{@value #SIZE} size. This specialized matrix provides
032: * better accuracy than {@link GeneralMatrix} for matrix inversion and multiplication.
033: *
034: * @since 2.2
035: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/operation/matrix/Matrix3.java $
036: * @version $Id: Matrix3.java 24493 2007-02-17 17:28:12Z desruisseaux $
037: * @author Martin Desruisseaux
038: */
039: public class Matrix3 extends Matrix3d implements XMatrix {
040: /**
041: * Serial number for interoperability with different versions.
042: */
043: private static final long serialVersionUID = 8902061778871586611L;
044:
045: /**
046: * The matrix size, which is {@value}.
047: */
048: public static final int SIZE = 3;
049:
050: /**
051: * Creates a new identity matrix.
052: */
053: public Matrix3() {
054: setIdentity();
055: }
056:
057: /**
058: * Creates a new matrix initialized to the specified values.
059: */
060: public Matrix3(double m00, double m01, double m02, double m10,
061: double m11, double m12, double m20, double m21, double m22) {
062: super (m00, m01, m02, m10, m11, m12, m20, m21, m22);
063: }
064:
065: /**
066: * Constructs a 3×3 matrix from the specified affine transform.
067: */
068: public Matrix3(final AffineTransform transform) {
069: setMatrix(transform);
070: }
071:
072: /**
073: * Creates a new matrix initialized to the same value than the specified one.
074: * The specified matrix size must be {@value #SIZE}×{@value #SIZE}.
075: */
076: public Matrix3(final Matrix matrix) {
077: if (matrix.getNumRow() != SIZE || matrix.getNumCol() != SIZE) {
078: throw new IllegalArgumentException(Errors
079: .format(ErrorKeys.ILLEGAL_MATRIX_SIZE));
080: }
081: for (int j = 0; j < SIZE; j++) {
082: for (int i = 0; i < SIZE; i++) {
083: setElement(j, i, matrix.getElement(j, i));
084: }
085: }
086: }
087:
088: /**
089: * Returns the number of rows in this matrix, which is always {@value #SIZE}
090: * in this implementation.
091: */
092: public final int getNumRow() {
093: return SIZE;
094: }
095:
096: /**
097: * Returns the number of colmuns in this matrix, which is always {@value #SIZE}
098: * in this implementation.
099: */
100: public final int getNumCol() {
101: return SIZE;
102: }
103:
104: /**
105: * {@inheritDoc}
106: */
107: public final boolean isIdentity() {
108: for (int j = 0; j < SIZE; j++) {
109: for (int i = 0; i < SIZE; i++) {
110: if (getElement(j, i) != ((i == j) ? 1 : 0)) {
111: return false;
112: }
113: }
114: }
115: return true;
116: }
117:
118: /**
119: * {@inheritDoc}
120: */
121: public final boolean isIdentity(double tolerance) {
122: return GeneralMatrix.isIdentity(this , tolerance);
123: }
124:
125: /**
126: * {@inheritDoc}
127: */
128: public final boolean isAffine() {
129: return m20 == 0 && m21 == 0 && m22 == 1;
130: }
131:
132: /**
133: * Returns {@code true} if at least one value is {@code NaN}.
134: *
135: * @since 2.3
136: */
137: public final boolean isNaN() {
138: return Double.isNaN(m00) || Double.isNaN(m01)
139: || Double.isNaN(m02) || Double.isNaN(m10)
140: || Double.isNaN(m11) || Double.isNaN(m12)
141: || Double.isNaN(m20) || Double.isNaN(m21)
142: || Double.isNaN(m22);
143: }
144:
145: /**
146: * {@inheritDoc}
147: */
148: public final void multiply(final Matrix matrix) {
149: final Matrix3d m;
150: if (matrix instanceof Matrix3d) {
151: m = (Matrix3d) matrix;
152: } else {
153: m = new Matrix3(matrix);
154: }
155: mul(m);
156: }
157:
158: /**
159: * Sets this matrix to the specified affine transform.
160: *
161: * @since 2.3
162: */
163: public void setMatrix(final AffineTransform transform) {
164: m00 = transform.getScaleX();
165: m01 = transform.getShearX();
166: m02 = transform.getTranslateX();
167: m10 = transform.getShearY();
168: m11 = transform.getScaleY();
169: m12 = transform.getTranslateY();
170: m20 = 0;
171: m21 = 0;
172: m22 = 1;
173: }
174:
175: /**
176: * Returns {@code true} if this matrix is equals to the specified affine transform.
177: *
178: * @since 2.3
179: */
180: public boolean equalsAffine(final AffineTransform transform) {
181: return m00 == transform.getScaleX()
182: && m01 == transform.getShearX()
183: && m02 == transform.getTranslateX()
184: && m10 == transform.getShearY()
185: && m11 == transform.getScaleY()
186: && m12 == transform.getTranslateY() && m20 == 0
187: && m21 == 0 && m22 == 1;
188: }
189:
190: /**
191: * Returns a string representation of this matrix. The returned string is implementation
192: * dependent. It is usually provided for debugging purposes only.
193: */
194: public String toString() {
195: return GeneralMatrix.toString(this);
196: }
197: }
|