/** * After a call to {@code transform}, applies the <em>inverse</em> transform on {@code dstPts} and * compares the result with {@code srcPts}. The maximal difference (in absolute value) is * returned. This method is used for assertions. */ private float maxError( final float[] srcPts1, final double[] srcPts2, int srcOff, final float[] dstPts1, final double[] dstPts2, int dstOff, int numPts) { float max = 0f; if (inverse == null) { inverse(); if (inverse == null) { return max; // Custom user's subclass; can't do the test. } } final int sourceDim = getSourceDimensions(); final float[] tmp = new float[numPts * sourceDim]; inverse.transform(dstPts1, dstPts2, dstOff, tmp, null, 0, numPts); for (int i = 0; i < tmp.length; i++, srcOff++) { final float expected = (srcPts2 != null) ? (float) srcPts2[srcOff] : srcPts1[srcOff]; float error = abs(tmp[i] - expected); switch (i % sourceDim) { case 0: error -= 360 * floor(error / 360); break; // Rool Longitude case 2: continue; // Ignore height because inacurate. } if (error > max) { max = error; } } return max; }
/** * Transforms a list of coordinate point ordinal values. This method is provided for efficiently * transforming many points. The supplied array of ordinal values will contain packed ordinal * values. For example, if the source dimension is 3, then the ordinals will be packed in this * order: * * <p>(<var>x<sub>0</sub></var>,<var>y<sub>0</sub></var>,<var>z<sub>0</sub></var>, * <var>x<sub>1</sub></var>,<var>y<sub>1</sub></var>,<var>z<sub>1</sub></var> ...). * * @param srcPts the array containing the source point coordinates. * @param srcOff the offset to the first point to be transformed in the source array. * @param dstPts the array into which the transformed point coordinates are returned. May be the * same than {@code srcPts}. * @param dstOff the offset to the location of the first transformed point that is stored in the * destination array. * @param numPts the number of point objects to be transformed. */ public void transform(double[] srcPts, int srcOff, double[] dstPts, int dstOff, int numPts) { transform(null, srcPts, srcOff, null, dstPts, dstOff, numPts); /* * Assertions: computes the inverse transform in the 3D-case only * (otherwise the transform is too approximative). * * NOTE: The somewhat complicated expression below executes 'maxError' *only* if * 1) assertions are enabled and 2) the conditions before 'maxError' are meet. Do * not factor the call to 'maxError' outside the 'assert' statement, otherwise it * would be executed everytime and would hurt performance for normal operations * (instead of slowing down during debugging only). */ assert !(target3D && srcPts != dstPts && (maxError(null, srcPts, srcOff, null, dstPts, dstOff, numPts)) > EPS); }