/*
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.mathlib.MathLib.M_2PI;
import static org.jwildfire.base.mathlib.MathLib.M_PI_2;
import static org.jwildfire.base.mathlib.MathLib.cos;
import static org.jwildfire.base.mathlib.MathLib.fabs;
import static org.jwildfire.base.mathlib.MathLib.sin;
import static org.jwildfire.base.mathlib.MathLib.sqr;
import static org.jwildfire.base.mathlib.MathLib.sqrt;
import org.jwildfire.base.Tools;
import org.jwildfire.create.tina.base.Layer;
import org.jwildfire.create.tina.base.XForm;
import org.jwildfire.create.tina.base.XYZPoint;
public class Loonie2Func extends VariationFunc {
private static final long serialVersionUID = 1L;
private static final String PARAM_SIDES = "sides";
private static final String PARAM_STAR = "star";
private static final String PARAM_CIRCLE = "circle";
private static final String[] paramNames = { PARAM_SIDES, PARAM_STAR, PARAM_CIRCLE };
private int sides = 4;
private double star = 0.0;
private double circle = 0.0;
@Override
public void transform(FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) {
/* loonie2 by dark-beam, http://dark-beam.deviantart.com/art/Loonie2-update-2-Loonie3-457414891 */
double xrt = pAffineTP.x, yrt = pAffineTP.y, swp;
// r2 = xrt; // normal
double r2 = xrt * _coss + fabs(yrt) * _sins; // +star
double circle = sqrt(sqr(xrt) + sqr(yrt));
int i;
for (i = 0; i < sides - 1; i++) {
// rotate around to get the the sides!!! :D
swp = xrt * _cosa - yrt * _sina;
yrt = xrt * _sina + yrt * _cosa;
xrt = swp;
// r2 = MAX(r2, xrt); // normal
r2 = Math.max(r2, xrt * _coss + fabs(yrt) * _sins); // +star
}
r2 = r2 * _cosc + circle * _sinc; // +circle
if (i > 1) {
r2 = sqr(r2); // we want it squared, for the pretty effect
}
else {
r2 = fabs(r2) * r2; // 2-faces effect JUST FOR i=1
}
if (r2 > 0 && (r2 < _sqrvvar)) {
double r = pAmount * sqrt(fabs(_sqrvvar / r2 - 1.0));
pVarTP.x += r * pAffineTP.x;
pVarTP.y += r * pAffineTP.y;
}
else if (r2 < 0) {// 2-faces effect JUST FOR i=1
double r = pAmount / sqrt(fabs(_sqrvvar / r2) - 1.0);
pVarTP.x += r * pAffineTP.x;
pVarTP.y += r * pAffineTP.y;
}
else {
pVarTP.x += pAmount * pAffineTP.x;
pVarTP.y += pAmount * pAffineTP.y;
}
if (pContext.isPreserveZCoordinate()) {
pVarTP.z += pAmount * pAffineTP.z;
}
}
@Override
public String[] getParameterNames() {
return paramNames;
}
@Override
public Object[] getParameterValues() {
return new Object[] { sides, star, circle };
}
@Override
public void setParameter(String pName, double pValue) {
if (PARAM_SIDES.equalsIgnoreCase(pName))
sides = limitIntVal(Tools.FTOI(pValue), 1, 50);
else if (PARAM_STAR.equalsIgnoreCase(pName))
star = limitVal(pValue, -1.0, 1.0);
else if (PARAM_CIRCLE.equalsIgnoreCase(pName))
circle = limitVal(pValue, -1.0, 1.0);
else
throw new IllegalArgumentException(pName);
}
@Override
public String getName() {
return "loonie2";
}
private double _sqrvvar, _sina, _cosa, _sins, _coss, _sinc, _cosc;
@Override
public void init(FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double pAmount) {
_sqrvvar = pAmount * pAmount;
double a = M_2PI / sides;
_sina = sin(a);
_cosa = cos(a);
a = -M_PI_2 * star;
_sins = sin(a);
_coss = cos(a);
a = M_PI_2 * circle;
_sinc = sin(a);
_cosc = cos(a);
}
}