/* JAI-Ext - OpenSource Java Advanced Image Extensions Library * http://www.geo-solutions.it/ * Copyright 2014 GeoSolutions * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package it.geosolutions.jaiext.piecewise; /** * {@link MathTransformation} implementation for single-dimensional operations * * @author Nicola Lagomarsini geosolutions * */ public class SingleDimensionTransformation implements MathTransformation { public static final SingleDimensionTransformation IDENTITY = new SingleDimensionTransformation( 1, 0); protected SingleDimensionTransformation(double scale, double offset) { this.scale = scale; this.offset = offset; } public double getScale() { return scale; } public void setScale(double scale) { this.scale = scale; } public double getOffset() { return offset; } public void setOffset(double offset) { this.offset = offset; } /** Scale transformation parameter*/ protected double scale; /** Offset transformation parameter*/ protected double offset; private MathTransformation inverse; public double transform(double value) { return offset + scale * value; } public double derivative(double value) { return scale; } public int getSourceDimensions() { return 1; } public int getTargetDimensions() { return 1; } public MathTransformation inverseTransform() { if (inverse == null) { if (isIdentity()) { inverse = this; } else if (scale != 0) { final SingleDimensionTransformation inverse; inverse = create(1 / scale, -offset / scale); inverse.inverse = this; this.inverse = inverse; } else { throw new UnsupportedOperationException("Unable to invert such transformation"); } } return inverse; } public boolean isIdentity() { return isIdentity(0); } /** * Returns true if the transformation is an identity, with a tolerance value */ public boolean isIdentity(double tolerance) { tolerance = Math.abs(tolerance); return Math.abs(offset) <= tolerance && Math.abs(scale - 1) <= tolerance; } /** * Creates a {@link SingleDimensionTransformation} instance based on the input scale and offset * * @param scale * @param offset * @return */ public static SingleDimensionTransformation create(double scale, double offset) { if (scale == 0) { return new ConstantTransform(offset); } if (scale == 1 && offset == 0) { return IDENTITY; } return new SingleDimensionTransformation(scale, offset); } public Position transform(Position ptSrc, Position ptDst) { if (ptDst == null) { ptDst = new Position(); } ptDst.setOrdinatePosition(transform(ptSrc.getOrdinatePosition())); return ptDst; } /** * {@link SingleDimensionTransformation} extension defining Constant transformations */ public static class ConstantTransform extends SingleDimensionTransformation { protected ConstantTransform(double offset) { super(0, offset); } public double transform(double value) { return offset; } } }