/** * Returns this transform as an affine transform matrix. */ @Override public Matrix getMatrix() { return new Matrix2(scale, offset, 0, 1); }
/** * Returns this transform as an affine transform matrix. */ @Override public Matrix getMatrix() { return new Matrix2(scale, offset, 0, 1); }
/** * {@inheritDoc} */ @Override public Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, final boolean derivate) throws ProjectionException { final double φ = srcPts[srcOff+1]; if (dstPts != null) { dstPts[dstOff ] = srcPts[srcOff]; dstPts[dstOff+1] = sin(φ); } return derivate ? new Matrix2(1, 0, 0, cos(φ)) : null; }
/** * {@inheritDoc} */ @Override public Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, final boolean derivate) throws ProjectionException { final double φ = srcPts[srcOff+1]; if (dstPts != null) { dstPts[dstOff ] = srcPts[srcOff]; dstPts[dstOff+1] = sin(φ); } return derivate ? new Matrix2(1, 0, 0, cos(φ)) : null; }
/** * Converts a single coordinate and optionally computes the derivative. */ @Override public Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, final boolean derivate) { final double r = srcPts[srcOff ]; final double θ = srcPts[srcOff+1]; final double cosθ = cos(θ); final double sinθ = sin(θ); if (dstPts != null) { dstPts[dstOff ] = r*cosθ; dstPts[dstOff+1] = r*sinθ; } if (!derivate) { return null; } return new Matrix2(cosθ, -r*sinθ, sinθ, r*cosθ); }
/** * Converts a single coordinate and optionally computes the derivative. */ @Override public Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, final boolean derivate) { final double x = srcPts[srcOff ]; final double y = srcPts[srcOff+1]; final double r = hypot(x, y); if (dstPts != null) { dstPts[dstOff ] = r; dstPts[dstOff+1] = atan2(y, x); } if (!derivate) { return null; } final double r2 = r*r; return new Matrix2(x/r, y/r, -y/r2, x/r2); }
/** * Converts a single coordinate and optionally computes the derivative. */ @Override public Matrix transform(final double[] srcPts, final int srcOff, final double[] dstPts, final int dstOff, final boolean derivate) { final double r = srcPts[srcOff ]; final double θ = srcPts[srcOff+1]; final double cosθ = cos(θ); final double sinθ = sin(θ); if (dstPts != null) { dstPts[dstOff ] = r*cosθ; dstPts[dstOff+1] = r*sinθ; } if (!derivate) { return null; } return new Matrix2(cosθ, -r*sinθ, sinθ, r*cosθ); }
/** * Computes the inverse of projection derivative. * * @param θp {@code 2 * asin(y)} * @param sinφ {@code (θp + sin(θp)) / PI} * * @see <a href="https://issues.apache.org/jira/browse/SIS-428">SIS-428</a> */ private static Matrix inverseDerivate(final double x, final double y, final double θp, final double sinφ) { final double cosφ = sqrt(1 - (sinφ * sinφ)); final double ym1 = 1 - y*y; final double dλ_dx = 1 / sqrt(ym1); final double dλ_dy = (x*y) * dλ_dx / ym1; final double dφ_dy = 2*dλ_dx*(1 + cos(θp)) / (PI*cosφ); return new Matrix2(dλ_dx, dλ_dy, 0, dφ_dy); } }
/** * Returns a linear transform created using the given factory. * This method is used only when the user specify explicitly a factory to use. * * @param factory the factory to use. * @param withScale {@code true} for using {@link #scale}, or {@code false} for replacing the scale by zero. */ private MathTransform createAffineTransform(final MathTransformFactory factory, final boolean withScale) throws FactoryException { return factory.createAffineTransform(new Matrix2(withScale ? scale : 0, offset, 0, 1)); }
/** * Casts or copies the given matrix to a {@code Matrix2} implementation. If the given {@code matrix} * is already an instance of {@code Matrix2}, then it is returned unchanged. Otherwise this method * verifies the matrix size, then copies all elements in a new {@code Matrix2} object. * * @param matrix the matrix to cast or copy, or {@code null}. * @return the matrix argument if it can be safely casted (including {@code null} argument), * or a copy of the given matrix otherwise. * @throws MismatchedMatrixSizeException if the size of the given matrix is not {@value #SIZE}×{@value #SIZE}. */ public static Matrix2 castOrCopy(final Matrix matrix) throws MismatchedMatrixSizeException { if (matrix == null || matrix instanceof Matrix2) { return (Matrix2) matrix; } ensureSizeMatch(SIZE, SIZE, matrix); return new Matrix2(matrix); }
/** * Casts or copies the given matrix to a {@code Matrix2} implementation. If the given {@code matrix} * is already an instance of {@code Matrix2}, then it is returned unchanged. Otherwise this method * verifies the matrix size, then copies all elements in a new {@code Matrix2} object. * * @param matrix the matrix to cast or copy, or {@code null}. * @return the matrix argument if it can be safely casted (including {@code null} argument), * or a copy of the given matrix otherwise. * @throws MismatchedMatrixSizeException if the size of the given matrix is not {@value #SIZE}×{@value #SIZE}. */ public static Matrix2 castOrCopy(final Matrix matrix) throws MismatchedMatrixSizeException { if (matrix == null || matrix instanceof Matrix2) { return (Matrix2) matrix; } ensureSizeMatch(SIZE, SIZE, matrix); return new Matrix2(matrix); }
/** * Creates a transform from the specified group of parameter values. * The parameter value is unconditionally converted to metres. * * @param factory ignored (can be null). * @param values the group of parameter values. * @return the created math transform. * @throws ParameterNotFoundException if a required parameter was not found. */ @Override public MathTransform createMathTransform(final MathTransformFactory factory, final ParameterValueGroup values) throws ParameterNotFoundException { final Parameters pv = Parameters.castOrWrap(values); final Matrix2 t = new Matrix2(); t.m01 = pv.doubleValue(TZ); return MathTransforms.linear(t); }
/** * Gets the derivative of this transform at a point. * For an affine transform, the derivative is the same everywhere. */ @Override public final Matrix derivative(final Point2D point) { return new Matrix2(getScaleX(), getShearX(), getShearY(), getScaleY()); }
/** * Gets the derivative of this transform at a point. * For an affine transform, the derivative is the same everywhere. */ @Override public final Matrix derivative(final Point2D point) { return new Matrix2(getScaleX(), getShearX(), getShearY(), getScaleY()); }
/** * Creates a square identity matrix of size {@code size} × {@code size}. * Elements on the diagonal (<var>j</var> == <var>i</var>) are set to 1. * * <div class="note"><b>Implementation note:</b> * For sizes between {@value org.apache.sis.referencing.operation.matrix.Matrix1#SIZE} and * {@value org.apache.sis.referencing.operation.matrix.Matrix4#SIZE} inclusive, the matrix * is guaranteed to be an instance of one of {@link Matrix1} … {@link Matrix4} subtypes.</div> * * @param size numbers of row and columns. For an affine transform matrix, this is the number of * {@linkplain MathTransform#getSourceDimensions() source} and * {@linkplain MathTransform#getTargetDimensions() target} dimensions + 1. * @return an identity matrix of the given size. */ public static MatrixSIS createIdentity(final int size) { switch (size) { case 1: return new Matrix1(); case 2: return new Matrix2(); case 3: return new Matrix3(); case 4: return new Matrix4(); default: return new GeneralMatrix(size, size, true, 1); } }
/** * Tests {@link GeneralMatrix#getExtendedElements(Matrix, int, int, boolean)}. * This test is a copy of {@link GeneralMatrixTest#testGetExtendedElements()}, * but on a {@link Matrix2} instance instead of {@link GeneralMatrix}. */ @Test public void testGetExtendedElements() { GeneralMatrixTest.testGetExtendedElements(new Matrix2( StrictMath.PI / 180, // Degrees to radians 180 / StrictMath.PI, // Radians to degrees 0.9, // Grads to degrees 0.1234567)); // Random value with no special meaning. } }
/** * Computes the derivative of the given transform at the given location, and returns the result * as a 2×2 matrix. This method invokes the {@link MathTransform2D#derivative(Point2D)} * and convert or cast the result to a {@link Matrix2} instance. * <p> * In the Geotk implementation, the matrix returned by the {@code derivative(Point2D)} methods * are already instances of {@link Matrix2}. Consequently in most cases this method will just * cast the result. * * @param transform The transform for which to compute the derivative. * @param point The location where to compute the derivative. * @return The derivative at the given location as a 2×2 matrix. * @throws TransformException If the derivative can not be computed. */ private static Matrix2 derivative(final MathTransform2D transform, final Point2D point) throws TransformException { final Matrix matrix = transform.derivative(point); return (matrix instanceof Matrix2) ? (Matrix2) matrix : new Matrix2( matrix.getElement(0,0), matrix.getElement(0,1), matrix.getElement(1,0), matrix.getElement(1,1)); }
/** * Test {@link DefaultMathTransformFactory#createFromWKT(String)}. We test only a very small WKT here because * it is not the purpose of this class to test the parser. The main purpose of this test is to verify that * {@link DefaultMathTransformFactory} has been able to instantiate the parser. * * @throws FactoryException if the parsing failed. */ @Test public void testCreateFromWKT() throws FactoryException { final MathTransform tr = factory().createFromWKT( "PARAM_MT[\"Affine\"," + "PARAMETER[\"num_row\",2]," + "PARAMETER[\"num_col\",2]," + "PARAMETER[\"elt_0_1\",7]]"); assertMatrixEquals("Affine", new Matrix2( 1, 7, 0, 1), MathTransforms.getMatrix(tr), STRICT); }
/** * Tests the {@link Matrix2#Matrix2(double, double, double, double)} constructor. * This constructor is specific to the implementation class. */ @Test public void testConstructor() { initialize(-8453835559080304420L); final double[] elements = createRandomPositiveValues(SIZE * SIZE); final Matrix2 matrix = new Matrix2( elements[0], elements[1], elements[2], elements[3]); validate(matrix); assertArrayEquals(elements, matrix.getElements(), STRICT); }
/** * Tests separation of a linear transform containing {@link Double#NaN} values. * * @throws FactoryException if an error occurred while creating a new transform. */ @Test public void testIncompleteTransform() throws FactoryException { Matrix matrix = new Matrix4( 1, 0, 0, 7, 0, 0, 1, 8, 0, NaN, 0, 6, 0, 0, 0, 1 ); TransformSeparator s = new TransformSeparator(MathTransforms.linear(matrix)); s.addSourceDimensions(1); assertMatrixEquals("transform", new Matrix2( NaN, 6, 0, 1 ), ((LinearTransform) s.separate()).getMatrix(), STRICT); assertArrayEquals(new int[] {2}, s.getTargetDimensions()); }