package edu.stanford.rsl.conrad.geometry.transforms; import edu.stanford.rsl.conrad.fitting.LinearFunction; import edu.stanford.rsl.conrad.geometry.shapes.simple.PointND; import edu.stanford.rsl.conrad.numerics.SimpleMatrix; import edu.stanford.rsl.conrad.numerics.SimpleVector; /** * Affine Transform Class where y = T(x)= A(x)+ b and x = T^-1(y) = A^-1(y - b) * @author Rotimi X Ojo */ public class AffineTransform extends ComboTransform { private static final long serialVersionUID = -6509394061746644677L; /** * Creates a transform that scales the data from (point1Before, point2Before) to (point1After, point2After). No rotation is considered. Internally every dimension is * scaled individually:<br><br> * * point1After = transform(point1Before) * <br><br> * and * <br><br> * point2After = transform(point2Before) * * @param point1Before the minimum before the transform * @param point2Before the maximum before the transform * @param point1After the minimum after the transform * @param point2After the maximum after the transfrom */ public AffineTransform(PointND point1Before, PointND point2Before, PointND point1After, PointND point2After){ LinearFunction funcx = new LinearFunction(point1Before.get(0), point2Before.get(0), point1After.get(0), point2After.get(0)); LinearFunction funcy = new LinearFunction(point1Before.get(1), point2Before.get(1), point1After.get(1), point2After.get(1)); LinearFunction funcz = new LinearFunction(point1Before.get(2), point2Before.get(2), point1After.get(2), point2After.get(2)); SimpleMatrix scaleRotate = new SimpleMatrix(3, 3); scaleRotate.setElementValue(0, 0, funcx.getM()); scaleRotate.setElementValue(1, 1, funcy.getM()); scaleRotate.setElementValue(2, 2, funcz.getM()); SimpleVector translatorVec = new SimpleVector(funcx.getT(),funcy.getT(),funcz.getT()); super.init(new ScaleRotate(scaleRotate), new Translation(translatorVec)); } /** * Initialize a new Affine transform; * @param scaleRotate is the transformation matrix * @param translatorVec is the translation vector */ public AffineTransform(SimpleMatrix scaleRotate, SimpleVector translatorVec){ if(scaleRotate == null || translatorVec == null){ throw new RuntimeException("Null inputs are not supported"); } super.init(new ScaleRotate(scaleRotate), new Translation(translatorVec)); } /** * Initialize a new Affine transform * @param transform0 is the first transformation * @param transform1 is the second transformation */ public AffineTransform(Transform transform0, Transform transform1) { if(transform0 == null || transform1 == null){ throw new RuntimeException("Null inputs are not supported"); } super.init(transform0,transform1); } @Override public AffineTransform inverse(){ Transform t0 = transforms.get(1).inverse(); Transform t1 = transforms.get(0).inverse(); return new AffineTransform(t0,t1); } public AffineTransform clone(){ return new AffineTransform(transforms.get(0).clone(), transforms.get(1).clone()); } } /* * Copyright (C) 2010-2014 Andreas Maier, Rotimi X Ojo * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */