package mikera.transformz; import mikera.matrixx.AMatrix; import mikera.vectorz.AVector; /** * Abstract base class for affine transformations * * @author Mike */ public abstract class AAffineTransform extends ATransform { // =========================================== // Abstract interface public abstract AMatrix getMatrix(); public abstract ATranslation getTranslation(); // =========================================== // Standard implementation /** * Returns a deep copy of the translation vector for this affine transform */ public AVector copyOfTranslationVector() { return getTranslation().getTranslationVector().clone(); } /** * Returns a deep copy of the transformation matrix for this affine transform */ public AMatrix copyOfMatrix() { return getMatrix().clone(); } public MatrixTransform getMatrixTransform() { return new MatrixTransform(getMatrix()); } public AVector getTranslationVector() { return getTranslation().getTranslationVector(); } @Override public boolean isIdentity() { return getMatrix().isIdentity() && getTranslation().isIdentity(); } @Override public ATransform compose(ATransform a) { if (a instanceof AAffineTransform) return compose((AAffineTransform)a); return super.compose(a); } public ATransform compose(AAffineTransform a) { AVector v=a.copyOfTranslationVector(); AMatrix thisM=getMatrix(); thisM.transformInPlace(v); v.add(getTranslation().getTranslationVector()); AMatrix m=thisM.compose(a.getMatrix()); return Transformz.createAffineTransform(m, v); } @Override public void transform(AVector source, AVector dest) { getMatrix().transform(source,dest); getTranslation().transformInPlace(dest); } public void transformNormal(AVector source, AVector dest) { getMatrix().transform(source,dest); dest.normalise(); } @Override public double calculateElement(int i, AVector v) { return getMatrix().calculateElement(i,v) +getTranslation().getTranslationComponent(i); } @Override public void transformInPlace(AVector v) { getMatrix().transformInPlace(v); getTranslation().transformInPlace(v); } public AAffineTransform toAffineTransform() { return new AffineMN(this); } @Override public int hashCode() { return getMatrix().hashCode()+getTranslation().hashCode(); } @Override public boolean equals(Object o) { if (!(o instanceof AAffineTransform)) return false; return equals((AAffineTransform)o); } public boolean equals(AAffineTransform a) { return a.getMatrix().equals(getMatrix()) && a.getTranslation().equals(getTranslation()); } @Override public AAffineTransform inverse() { AMatrix m=getMatrix().inverse(); AVector v=getTranslation().getTranslationVector().clone(); v.negate(); m.transformInPlace(v); return Transformz.createAffineTransform(m, v); } @Override public boolean isLinear() { return true; } @Override public boolean isInvertible() { return getMatrix().isInvertible(); } }