/* JWildfire - an image and animation processor written in Java Copyright (C) 1995-2011 Andreas Maschke This is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this software; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jwildfire.create.tina.transform; import org.jwildfire.base.mathlib.MathLib; import org.jwildfire.create.tina.base.XForm; public class XFormTransformService { public static Matrix3x3 multiply(Matrix3x3 pMatrix1, Matrix3x3 pMatrix2) { Matrix3x3 res = new Matrix3x3(); res.val[0][0] = pMatrix1.val[0][0] * pMatrix2.val[0][0] + pMatrix1.val[0][1] * pMatrix2.val[1][0] + pMatrix1.val[0][2] * pMatrix2.val[2][0]; res.val[0][1] = pMatrix1.val[0][0] * pMatrix2.val[0][1] + pMatrix1.val[0][1] * pMatrix2.val[1][1] + pMatrix1.val[0][2] * pMatrix2.val[2][1]; res.val[0][2] = pMatrix1.val[0][0] * pMatrix2.val[0][2] + pMatrix1.val[0][1] * pMatrix2.val[1][2] + pMatrix1.val[0][2] * pMatrix2.val[2][2]; res.val[1][0] = pMatrix1.val[1][0] * pMatrix2.val[0][0] + pMatrix1.val[1][1] * pMatrix2.val[1][0] + pMatrix1.val[1][2] * pMatrix2.val[2][0]; res.val[1][1] = pMatrix1.val[1][0] * pMatrix2.val[0][1] + pMatrix1.val[1][1] * pMatrix2.val[1][1] + pMatrix1.val[1][2] * pMatrix2.val[2][1]; res.val[1][2] = pMatrix1.val[1][0] * pMatrix2.val[0][2] + pMatrix1.val[1][1] * pMatrix2.val[1][2] + pMatrix1.val[1][2] * pMatrix2.val[2][2]; res.val[2][0] = pMatrix1.val[2][0] * pMatrix2.val[0][0] + pMatrix1.val[2][1] * pMatrix2.val[1][0] + pMatrix1.val[2][2] * pMatrix2.val[2][0]; res.val[2][0] = pMatrix1.val[2][0] * pMatrix2.val[0][1] + pMatrix1.val[2][1] * pMatrix2.val[1][1] + pMatrix1.val[2][2] * pMatrix2.val[2][1]; res.val[2][0] = pMatrix1.val[2][0] * pMatrix2.val[0][2] + pMatrix1.val[2][1] * pMatrix2.val[1][2] + pMatrix1.val[2][2] * pMatrix2.val[2][2]; return res; } public static void rotate(XForm pXForm, double pAngle) { rotate(pXForm, pAngle, false); } public static void rotate(XForm pXForm, double pAngle, boolean pPostTransform) { if (Math.abs(pAngle) < MathLib.SMALL_EPSILON) return; double alpha = pAngle * Math.PI / 180.0; Matrix3x3 m1 = new Identity3x3(); m1.val[0][0] = Math.cos(alpha); m1.val[0][1] = -Math.sin(alpha); m1.val[1][0] = Math.sin(alpha); m1.val[1][1] = Math.cos(alpha); Matrix3x3 m2 = new Identity3x3(); if (pPostTransform) { m2.val[0][0] = pXForm.getPostCoeff00(); m2.val[0][1] = pXForm.getPostCoeff01(); m2.val[1][0] = pXForm.getPostCoeff10(); m2.val[1][1] = pXForm.getPostCoeff11(); m2.val[0][2] = pXForm.getPostCoeff20(); m2.val[1][2] = pXForm.getPostCoeff21(); } else { m2.val[0][0] = pXForm.getCoeff00(); m2.val[0][1] = pXForm.getCoeff01(); m2.val[1][0] = pXForm.getCoeff10(); m2.val[1][1] = pXForm.getCoeff11(); m2.val[0][2] = pXForm.getCoeff20(); m2.val[1][2] = pXForm.getCoeff21(); } m2 = multiply(m2, m1); if (pPostTransform) { pXForm.setPostCoeff00(m2.val[0][0]); pXForm.setPostCoeff01(m2.val[0][1]); pXForm.setPostCoeff10(m2.val[1][0]); pXForm.setPostCoeff11(m2.val[1][1]); pXForm.setPostCoeff20(m2.val[0][2]); pXForm.setPostCoeff21(m2.val[1][2]); } else { pXForm.setCoeff00(m2.val[0][0]); pXForm.setCoeff01(m2.val[0][1]); pXForm.setCoeff10(m2.val[1][0]); pXForm.setCoeff11(m2.val[1][1]); pXForm.setCoeff20(m2.val[0][2]); pXForm.setCoeff21(m2.val[1][2]); } } public static void globalTranslate(XForm pXForm, double pDeltaX, double pDeltaY) { globalTranslate(pXForm, pDeltaX, pDeltaY, false); } public static void localTranslate(XForm pXForm, double pDeltaX, double pDeltaY) { localTranslate(pXForm, pDeltaX, pDeltaY, false); } public static void globalTranslate(XForm pXForm, double pDeltaX, double pDeltaY, boolean pPostTransform) { if (Math.abs(pDeltaX) < MathLib.SMALL_EPSILON && Math.abs(pDeltaY) < MathLib.SMALL_EPSILON) return; if (pPostTransform) { pXForm.setPostCoeff20(pDeltaX + pXForm.getPostCoeff20()); pXForm.setPostCoeff21(pDeltaY + pXForm.getPostCoeff21()); } else { pXForm.setCoeff20(pDeltaX + pXForm.getCoeff20()); pXForm.setCoeff21(pDeltaY + pXForm.getCoeff21()); } } public static void localTranslate(XForm pXForm, double pDeltaX, double pDeltaY, boolean pPostTransform) { if (Math.abs(pDeltaX) < MathLib.SMALL_EPSILON && Math.abs(pDeltaY) < MathLib.SMALL_EPSILON) return; Matrix3x3 m1 = new Identity3x3(); m1.val[0][2] = pDeltaX; m1.val[1][2] = pDeltaY; Matrix3x3 m2 = new Identity3x3(); if (pPostTransform) { m2.val[0][0] = pXForm.getPostCoeff00(); m2.val[0][1] = pXForm.getPostCoeff01(); m2.val[1][0] = pXForm.getPostCoeff10(); m2.val[1][1] = pXForm.getPostCoeff11(); m2.val[0][2] = pXForm.getPostCoeff20(); m2.val[1][2] = pXForm.getPostCoeff21(); } else { m2.val[0][0] = pXForm.getCoeff00(); m2.val[0][1] = pXForm.getCoeff01(); m2.val[1][0] = pXForm.getCoeff10(); m2.val[1][1] = pXForm.getCoeff11(); m2.val[0][2] = pXForm.getCoeff20(); m2.val[1][2] = pXForm.getCoeff21(); } m2 = multiply(m2, m1); if (pPostTransform) { pXForm.setPostCoeff00(m2.val[0][0]); pXForm.setPostCoeff01(m2.val[0][1]); pXForm.setPostCoeff10(m2.val[1][0]); pXForm.setPostCoeff11(m2.val[1][1]); pXForm.setPostCoeff20(m2.val[0][2]); pXForm.setPostCoeff21(m2.val[1][2]); } else { pXForm.setCoeff00(m2.val[0][0]); pXForm.setCoeff01(m2.val[0][1]); pXForm.setCoeff10(m2.val[1][0]); pXForm.setCoeff11(m2.val[1][1]); pXForm.setCoeff20(m2.val[0][2]); pXForm.setCoeff21(m2.val[1][2]); } } public static void scale(XForm pXForm, double pScale, boolean pXScale, boolean pYScale) { scale(pXForm, pScale, pXScale, pYScale, false); } public static void scale(XForm pXForm, double pScale, boolean pXScale, boolean pYScale, boolean pPostTransform) { if (Math.abs(pScale - 1.0) < MathLib.SMALL_EPSILON) { return; } if (pXScale) { if (pPostTransform) { pXForm.setPostCoeff00(pXForm.getPostCoeff00() * pScale); pXForm.setPostCoeff01(pXForm.getPostCoeff01() * pScale); } else { pXForm.setCoeff00(pXForm.getCoeff00() * pScale); pXForm.setCoeff01(pXForm.getCoeff01() * pScale); } } if (pYScale) { if (pPostTransform) { pXForm.setPostCoeff10(pXForm.getPostCoeff10() * pScale); pXForm.setPostCoeff11(pXForm.getPostCoeff11() * pScale); } else { pXForm.setCoeff10(pXForm.getCoeff10() * pScale); pXForm.setCoeff11(pXForm.getCoeff11() * pScale); } } // Matrix3x3 m1 = new Identity3x3(); // m1.val[0][0] = pScale; // m1.val[1][1] = pScale; // Matrix3x3 m2 = new Identity3x3(); // if (pPostTransform) { // m2.val[0][0] = pXForm.getPostCoeff00(); // m2.val[0][1] = pXForm.getPostCoeff01(); // m2.val[1][0] = pXForm.getPostCoeff10(); // m2.val[1][1] = pXForm.getPostCoeff11(); // m2.val[0][2] = pXForm.getPostCoeff20(); // m2.val[1][2] = pXForm.getPostCoeff21(); // } // else { // m2.val[0][0] = pXForm.getCoeff00(); // m2.val[0][1] = pXForm.getCoeff01(); // m2.val[1][0] = pXForm.getCoeff10(); // m2.val[1][1] = pXForm.getCoeff11(); // m2.val[0][2] = pXForm.getCoeff20(); // m2.val[1][2] = pXForm.getCoeff21(); // } // m2 = multiply(m2, m1); // if (pPostTransform) { // pXForm.setPostCoeff00(m2.val[0][0]); // pXForm.setPostCoeff01(m2.val[0][1]); // pXForm.setPostCoeff10(m2.val[1][0]); // pXForm.setPostCoeff11(m2.val[1][1]); // pXForm.setPostCoeff20(m2.val[0][2]); // pXForm.setPostCoeff21(m2.val[1][2]); // } // else { // pXForm.setCoeff00(m2.val[0][0]); // pXForm.setCoeff01(m2.val[0][1]); // pXForm.setCoeff10(m2.val[1][0]); // pXForm.setCoeff11(m2.val[1][1]); // pXForm.setCoeff20(m2.val[0][2]); // pXForm.setCoeff21(m2.val[1][2]); // } } public static void reset(XForm pXForm, boolean pPostTransform) { if (pPostTransform) { pXForm.setPostCoeff00(1.0); pXForm.setPostCoeff01(0.0); pXForm.setPostCoeff10(0.0); pXForm.setPostCoeff11(1.0); pXForm.setPostCoeff20(0.0); pXForm.setPostCoeff21(0.0); } else { pXForm.setCoeff00(1.0); pXForm.setCoeff01(0.0); pXForm.setCoeff10(0.0); pXForm.setCoeff11(1.0); pXForm.setCoeff20(0.0); pXForm.setCoeff21(0.0); } } public static void flipVertical(XForm pXForm, boolean pPostTransform) { if (pPostTransform) { pXForm.setPostCoeff01(-pXForm.getPostCoeff01()); pXForm.setPostCoeff11(-pXForm.getPostCoeff11()); } else { pXForm.setCoeff01(-pXForm.getCoeff01()); pXForm.setCoeff11(-pXForm.getCoeff11()); } } public static void flipHorizontal(XForm pXForm, boolean pPostTransform) { if (pPostTransform) { pXForm.setPostCoeff00(-pXForm.getPostCoeff00()); pXForm.setPostCoeff10(-pXForm.getPostCoeff10()); } else { pXForm.setCoeff00(-pXForm.getCoeff00()); pXForm.setCoeff10(-pXForm.getCoeff10()); } } }