/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2001-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2009-2012, Geomatys * * 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.geotoolkit.referencing.operation.matrix; import java.awt.geom.AffineTransform; import org.apache.sis.referencing.operation.matrix.AffineTransforms2D; import static java.lang.Math.*; /** * Utility methods for affine transforms. */ @Deprecated public final class XAffineTransform { /** * Do not allow instantiation of this class. */ private XAffineTransform() { } /** * Returns {@code true} if the specified affine transform is an identity transform up to the * specified tolerance. This method is equivalent to computing the difference between this * matrix and an identity matrix (as created by {@link AffineTransform#AffineTransform() * new AffineTransform()}) and returning {@code true} if and only if all differences are * smaller than or equal to {@code tolerance}. * <p> * This method is used for working around rounding error in affine transforms resulting * from a computation, as in the example below: * * {@preformat text * ┌ ┐ * │ 1.0000000000000000001 0.0 0.0 │ * │ 0.0 0.999999999999999999999 0.0 │ * │ 0.0 0.0 1.0 │ * └ ┘ * } * * @param tr The affine transform to be checked for identity. * @param tolerance The tolerance value to use when checking for identity. * @return {@code true} if this transformation is close enough to the * identity, {@code false} otherwise. * * @since 2.3.1 */ // LGPL public static boolean isIdentity(final AffineTransform tr, double tolerance) { if (tr.isIdentity()) { return true; } tolerance = abs(tolerance); return abs(tr.getScaleX() - 1) <= tolerance && abs(tr.getScaleY() - 1) <= tolerance && abs(tr.getShearX()) <= tolerance && abs(tr.getShearY()) <= tolerance && abs(tr.getTranslateX()) <= tolerance && abs(tr.getTranslateY()) <= tolerance; } /** * Returns a global scale factor for the specified affine transform. This scale factor combines * {@link #getScaleX0 getScaleX0(tr)} and {@link #getScaleY0 getScaleY0(tr)}. The way to compute * such a "global" scale is somewhat arbitrary and may change in a future version. * * @param tr The affine transform to inspect. * @return The magnitude of scale factory. */ public static double getScale(final AffineTransform tr) { return 0.5 * (AffineTransforms2D.getScaleX0(tr) + AffineTransforms2D.getScaleY0(tr)); } /** * If scale and shear coefficients are close to integers, replaces their current values by * their rounded values. The scale and shear coefficients are handled in a "all or nothing" * way; either all of them are rounded, or either none of them. The translation terms are * handled separately, provided that the scale and shear coefficients has been rounded. * <p> * This rounding up is useful for example in order to speedup image displays. * * @param tr The matrix to round. Rounding will be applied in place. * @param tolerance The maximal departure from integers in order to allow rounding. * It is typically a small number like {@code 1E-6}. * * @see org.geotoolkit.image.io.metadata.MetadataHelper#adjustForRoundingError(double) * * @since 3.14 (derived from 2.3.1) */ // LGPL (only the 'tolerance' argument actually) public static void roundIfAlmostInteger(final AffineTransform tr, final double tolerance) { double r; final double m00, m01, m10, m11; if (abs((m00 = rint(r=tr.getScaleX())) - r) <= tolerance && abs((m01 = rint(r=tr.getShearX())) - r) <= tolerance && abs((m11 = rint(r=tr.getScaleY())) - r) <= tolerance && abs((m10 = rint(r=tr.getShearY())) - r) <= tolerance) { /* * At this point the scale and shear coefficients can been rounded to integers. * Continue only if this rounding doesn't lead to a non-invertible transform. */ if ((m00!=0 || m01!=0) && (m10!=0 || m11!=0)) { double m02, m12; if (abs((r = rint(m02=tr.getTranslateX())) - m02) <= tolerance) m02=r; if (abs((r = rint(m12=tr.getTranslateY())) - m12) <= tolerance) m12=r; tr.setTransform(m00, m10, m01, m11, m02, m12); } } } }