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).
*/