/* 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.variation; import static org.jwildfire.base.Tools.FTOI; import static org.jwildfire.base.mathlib.MathLib.M_2_PI; import static org.jwildfire.base.mathlib.MathLib.cos; import static org.jwildfire.base.mathlib.MathLib.fabs; import static org.jwildfire.base.mathlib.MathLib.fmod; import static org.jwildfire.base.mathlib.MathLib.pow; import static org.jwildfire.base.mathlib.MathLib.sin; import org.jwildfire.create.tina.base.Layer; import org.jwildfire.create.tina.base.XForm; import org.jwildfire.create.tina.base.XYZPoint; public class SuperShape3DFunc extends VariationFunc { private static final long serialVersionUID = 1L; private static final String PARAM_RHO = "rho"; private static final String PARAM_PHI = "phi"; private static final String PARAM_M1 = "m1"; private static final String PARAM_M2 = "m2"; private static final String PARAM_A1 = "a1"; private static final String PARAM_A2 = "a2"; private static final String PARAM_B1 = "b1"; private static final String PARAM_B2 = "b2"; private static final String PARAM_N1_1 = "n1_1"; private static final String PARAM_N1_2 = "n1_2"; private static final String PARAM_N2_1 = "n2_1"; private static final String PARAM_N2_2 = "n2_2"; private static final String PARAM_N3_1 = "n3_1"; private static final String PARAM_N3_2 = "n3_2"; private static final String PARAM_SPIRAL = "spiral"; private static final String PARAM_TOROIDMAP = "toroidmap"; private static final String[] paramNames = { PARAM_RHO, PARAM_PHI, PARAM_M1, PARAM_M2, PARAM_A1, PARAM_A2, PARAM_B1, PARAM_B2, PARAM_N1_1, PARAM_N1_2, PARAM_N2_1, PARAM_N2_2, PARAM_N3_1, PARAM_N3_2, PARAM_SPIRAL, PARAM_TOROIDMAP }; private double rho = 9.9; private double phi = 2.5; private double m1 = 6.0; private double m2 = 3.0; private double a1 = 1.0; private double a2 = 1.0; private double b1 = 1.0; private double b2 = 1.0; private double n1_1 = 1.0; private double n1_2 = 1.0; private double n2_1 = 1.0; private double n2_2 = 1.0; private double n3_1 = 1.0; private double n3_2 = 1.0; private double spiral = 0.0; private int toroidmap = 0; @Override public void transform(FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) { // SuperShape3d by David Young, http://fractal-resources.deviantart.com/gallery/24660058#/d1o8z8x double rho1 = pContext.random() * rho_pi; double phi1 = pContext.random() * phi_pi; int p = (int) fmod(pContext.random(Integer.MAX_VALUE), 2); if (p == 1) { phi1 = (-phi1); } double sinr = sin(rho1); double cosr = cos(rho1); double sinp = sin(phi1); double cosp = cos(phi1); double msinr, mcosr; { double a = m4_1 * rho1; msinr = sin(a); mcosr = cos(a); } double msinp, mcosp; { double a = m4_2 * phi1; msinp = sin(a); mcosp = cos(a); } double pr1 = an2_1 * pow(fabs(mcosr), n2_1) + bn3_1 * pow(fabs(msinr), n3_1); double pr2 = an2_2 * pow(fabs(mcosp), n2_2) + bn3_2 * pow(fabs(msinp), n3_2); double r1 = pow(pr1, n1n_1) + spiral * rho1; double r2 = pow(pr2, n1n_2); if (toroidmap == 1) { pVarTP.x += pAmount * cosr * (r1 + r2 * cosp); pVarTP.y += pAmount * sinr * (r1 + r2 * cosp); pVarTP.z += pAmount * r2 * sinp; } else { pVarTP.x += pAmount * r1 * cosr * r2 * cosp; pVarTP.y += pAmount * r1 * sinr * r2 * cosp; pVarTP.z += pAmount * r2 * sinp; } } @Override public String[] getParameterNames() { return paramNames; } @Override public Object[] getParameterValues() { return new Object[] { rho, phi, m1, m2, a1, a2, b1, b2, n1_1, n1_2, n2_1, n2_2, n3_1, n3_2, spiral, toroidmap }; } @Override public void setParameter(String pName, double pValue) { if (PARAM_RHO.equalsIgnoreCase(pName)) rho = pValue; else if (PARAM_PHI.equalsIgnoreCase(pName)) phi = pValue; else if (PARAM_M1.equalsIgnoreCase(pName)) m1 = pValue; else if (PARAM_M2.equalsIgnoreCase(pName)) m2 = pValue; else if (PARAM_A1.equalsIgnoreCase(pName)) a1 = pValue; else if (PARAM_A2.equalsIgnoreCase(pName)) a2 = pValue; else if (PARAM_B1.equalsIgnoreCase(pName)) b1 = pValue; else if (PARAM_B2.equalsIgnoreCase(pName)) b2 = pValue; else if (PARAM_N1_1.equalsIgnoreCase(pName)) n1_1 = pValue; else if (PARAM_N1_2.equalsIgnoreCase(pName)) n1_2 = pValue; else if (PARAM_N2_1.equalsIgnoreCase(pName)) n2_1 = pValue; else if (PARAM_N2_2.equalsIgnoreCase(pName)) n2_2 = pValue; else if (PARAM_N3_1.equalsIgnoreCase(pName)) n3_1 = pValue; else if (PARAM_N3_2.equalsIgnoreCase(pName)) n3_2 = pValue; else if (PARAM_SPIRAL.equalsIgnoreCase(pName)) spiral = pValue; else if (PARAM_TOROIDMAP.equalsIgnoreCase(pName)) { toroidmap = FTOI(pValue); if (toroidmap < 0) { toroidmap = 0; } else if (toroidmap > 1) { toroidmap = 1; } } else throw new IllegalArgumentException(pName); } @Override public String getName() { return "superShape3d"; } private double n1n_1, n1n_2, m4_1, m4_2; private double an2_1, an2_2, bn3_1, bn3_2; private double rho_pi, phi_pi; @Override public void init(FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double pAmount) { n1n_1 = (-1.0 / n1_1); n1n_2 = (-1.0 / n1_2); an2_1 = pow(fabs(1.0 / a1), n2_1); an2_2 = pow(fabs(1.0 / a2), n2_2); bn3_1 = pow(fabs(1.0 / b1), n3_1); bn3_2 = pow(fabs(1.0 / b2), n3_2); m4_1 = m1 / 4.0; m4_2 = m2 / 4.0; rho_pi = rho * M_2_PI; phi_pi = phi * M_2_PI; } }