Search in sources :

Example 36 with DoubleDouble

use of org.apache.sis.internal.util.DoubleDouble in project sis by apache.

the class MatrixSIS method normalizeColumns.

/**
 * Normalizes all columns in-place. Each columns in this matrix is considered as a vector.
 * For each column (vector), this method computes the magnitude (vector length) as the square
 * root of the sum of all square values. Then, all values in the column are divided by that
 * magnitude.
 *
 * <p>This method is useful when the matrix is a
 * {@linkplain org.opengis.referencing.operation.MathTransform#derivative transform derivative}.
 * In such matrix, each column is a vector representing the displacement in target space when an
 * ordinate in the source space is increased by one. Invoking this method turns those vectors
 * into unitary vectors, which is useful for forming the basis of a new coordinate system.</p>
 *
 * @throws UnsupportedOperationException if this matrix is unmodifiable.
 */
public void normalizeColumns() {
    final int numRow = getNumRow();
    final int numCol = getNumCol();
    final DoubleDouble sum = new DoubleDouble();
    final DoubleDouble dot = new DoubleDouble();
    final DoubleDouble tmp = new DoubleDouble();
    for (int i = 0; i < numCol; i++) {
        sum.clear();
        for (int j = 0; j < numRow; j++) {
            get(j, i, dot);
            dot.square();
            sum.add(dot);
        }
        sum.sqrt();
        for (int j = 0; j < numRow; j++) {
            get(j, i, tmp);
            dot.setFrom(sum);
            dot.inverseDivide(tmp);
            set(j, i, dot);
        }
    }
}
Also used : DoubleDouble(org.apache.sis.internal.util.DoubleDouble)

Example 37 with DoubleDouble

use of org.apache.sis.internal.util.DoubleDouble in project sis by apache.

the class MatrixSIS method convertBefore.

/**
 * Assuming that this matrix represents an affine transform, concatenates a scale and a translation on the
 * given dimension. Converting a point with the resulting matrix is equivalent to first convert the point
 * with {@code ordinates[srcDim] = ordinates[srcDim] * scale + offset}, then apply the original matrix.
 *
 * <div class="section">Equivalence between this method and Java2D {@code AffineTransform} methods</div>
 * If this matrix was an instance of Java2D {@link AffineTransform}, then invoking this method would
 * be equivalent to invoke the following {@code AffineTransform} methods in the order shown below:
 *
 * <table class="sis" summary="Equivalence between this method and AffineTransform methods">
 *   <tr>
 *     <th>{@code MatrixSIS} method</th>
 *     <th class="sep">{@code AffineTransform} methods</th>
 *   </tr><tr>
 *     <td>{@code concatenate(0, scale, offset)}</td>
 *     <td class="sep"><code>at.{@linkplain AffineTransform#translate(double, double) translate}(offset, 0);
 *     at.{@linkplain AffineTransform#scale(double, double) scale}(scale, 1);</code></td>
 *   </tr><tr>
 *     <td class="hsep">{@code concatenate(1, scale, offset)}</td>
 *     <td class="hsep sep"><code>at.{@linkplain AffineTransform#translate(double, double) translate}(0, offset);
 *     at.{@linkplain AffineTransform#scale(double, double) scale}(1, scale);</code></td>
 *   </tr>
 * </table>
 *
 * @param  srcDim  the dimension of the ordinate to rescale in the source coordinates.
 * @param  scale   the amount by which to multiply the source ordinate value before to apply the transform, or {@code null} if none.
 * @param  offset  the amount by which to translate the source ordinate value before to apply the transform, or {@code null} if none.
 * @throws UnsupportedOperationException if this matrix is unmodifiable.
 *
 * @see AffineTransform#concatenate(AffineTransform)
 *
 * @since 0.6
 */
public void convertBefore(final int srcDim, final Number scale, final Number offset) {
    final int lastCol = getNumCol() - 1;
    ArgumentChecks.ensureValidIndex(lastCol, srcDim);
    final DoubleDouble s = new DoubleDouble();
    final DoubleDouble t = new DoubleDouble();
    for (int j = getNumRow(); --j >= 0; ) {
        if (offset != null) {
            // Scale factor
            get(j, srcDim, s);
            // Translation factor
            get(j, lastCol, t);
            s.multiply(offset);
            t.add(s);
            set(j, lastCol, t);
        }
        if (scale != null) {
            // Scale factor
            get(j, srcDim, s);
            s.multiply(scale);
            set(j, srcDim, s);
        }
    }
}
Also used : DoubleDouble(org.apache.sis.internal.util.DoubleDouble)

Example 38 with DoubleDouble

use of org.apache.sis.internal.util.DoubleDouble in project sis by apache.

the class MatrixSIS method convertAfter.

/**
 * Assuming that this matrix represents an affine transform, pre-concatenates a scale and a translation on the
 * given dimension. Converting a point with the resulting matrix is equivalent to first convert the point with
 * the original matrix, then convert the result with {@code ordinates[tgtDim] = ordinates[tgtDim] * scale + offset}.
 *
 * @param  tgtDim  the dimension of the ordinate to rescale in the target coordinates.
 * @param  scale   the amount by which to multiply the target ordinate value after this transform, or {@code null} if none.
 * @param  offset  the amount by which to translate the target ordinate value after this transform, or {@code null} if none.
 * @throws UnsupportedOperationException if this matrix is unmodifiable.
 *
 * @see AffineTransform#preConcatenate(AffineTransform)
 *
 * @since 0.6
 */
public void convertAfter(final int tgtDim, final Number scale, final Number offset) {
    final int lastRow = getNumRow() - 1;
    final int lastCol = getNumCol() - 1;
    ArgumentChecks.ensureValidIndex(lastRow, tgtDim);
    final DoubleDouble s = new DoubleDouble();
    if (scale != null) {
        for (int i = lastCol; i >= 0; i--) {
            get(tgtDim, i, s);
            s.multiply(scale);
            set(tgtDim, i, s);
        }
    }
    if (offset != null) {
        get(tgtDim, lastCol, s);
        s.add(offset);
        set(tgtDim, lastCol, s);
    }
}
Also used : DoubleDouble(org.apache.sis.internal.util.DoubleDouble)

Example 39 with DoubleDouble

use of org.apache.sis.internal.util.DoubleDouble in project sis by apache.

the class GridGeometry method setTranslationTerms.

/**
 * Computes translation terms in the given matrix from the (usually singleton) tie point.
 * This method is invoked when the GeoTIFF file has a {@link Tags#ModelPixelScaleTag} and
 * {@link Tags#ModelTiePoints}. The later should have a single record.
 *
 * @param  gridToCRS       the matrix to update. That matrix shall contain the scale factors before to invoke this method.
 * @param  modelTiePoints  the vector of model tie points. Only the first point will be used.
 * @return {@code true} if the given vector is non-null and contains at least one complete record.
 */
static boolean setTranslationTerms(final MatrixSIS gridToCRS, final Vector modelTiePoints) {
    if (modelTiePoints != null) {
        /*
             * The GeoTIFF specification recommends that the first point is located at grid indices (0,0).
             * But as a safety, we will nevertheless search in the grid for the point closest to origin.
             * If the grid is affine, using the corner closest to (0,0) reduces rounding errors compared
             * to using another corner. If the grid is not affine, then ModelPixelScaleTag should not have
             * been defined for that fileā€¦
             */
        // Index of the record nearest to origin.
        int nearest = 0;
        // Distance squared of the nearest record.
        double distance = Double.POSITIVE_INFINITY;
        final int size = modelTiePoints.size();
        for (int i = 0; i < size; i += RECORD_LENGTH) {
            double t;
            final double d = (t = modelTiePoints.doubleValue(i)) * t + (t = modelTiePoints.doubleValue(i + 1)) * t + (t = modelTiePoints.doubleValue(i + 2)) * t;
            if (d < distance) {
                distance = d;
                nearest = i;
                // Optimization for the standard case.
                if (d == 0)
                    break;
            }
        }
        if (distance != Double.POSITIVE_INFINITY) {
            final DoubleDouble t = new DoubleDouble();
            final int numDim = gridToCRS.getNumRow() - 1;
            final int trCol = gridToCRS.getNumCol() - 1;
            for (int j = 0; j < numDim; j++) {
                t.value = -modelTiePoints.doubleValue(nearest + j);
                t.error = DoubleDouble.errorForWellKnownValue(t.value);
                t.divide(gridToCRS.getNumber(j, j));
                t.add(modelTiePoints.doubleValue(nearest + j + RECORD_LENGTH / 2));
                gridToCRS.setNumber(j, trCol, t);
            }
            return true;
        }
    }
    return false;
}
Also used : DoubleDouble(org.apache.sis.internal.util.DoubleDouble)

Aggregations

DoubleDouble (org.apache.sis.internal.util.DoubleDouble)39 MatrixSIS (org.apache.sis.referencing.operation.matrix.MatrixSIS)5 Test (org.junit.Test)3 ExtendedPrecisionMatrix (org.apache.sis.internal.referencing.ExtendedPrecisionMatrix)2 DirectPosition (org.opengis.geometry.DirectPosition)2 AxisDirection (org.opengis.referencing.cs.AxisDirection)2 AffineTransform (java.awt.geom.AffineTransform)1 BigDecimal (java.math.BigDecimal)1 IncommensurableException (javax.measure.IncommensurableException)1 ParameterizedAffine (org.apache.sis.internal.referencing.j2d.ParameterizedAffine)1 Parameters (org.apache.sis.parameter.Parameters)1 Matrix4 (org.apache.sis.referencing.operation.matrix.Matrix4)1 ContextualParameters (org.apache.sis.referencing.operation.transform.ContextualParameters)1 DependsOnMethod (org.apache.sis.test.DependsOnMethod)1 MismatchedDimensionException (org.opengis.geometry.MismatchedDimensionException)1 CoordinateSystem (org.opengis.referencing.cs.CoordinateSystem)1 MathTransform (org.opengis.referencing.operation.MathTransform)1