/*
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 Scry2Func 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) {
/* scry2 by dark-beam */
double xrt = pAffineTP.x, yrt = pAffineTP.y, swp;
// r2 = xrt; // normal
double r2 = xrt * _coss + fabs(yrt) * _sins; // +star
double r1 = 0; // placeholder
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
r1 = r2;
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
}
// scry effect:
double d = (r1 * (r2 + 1.0 / pAmount));
if (d == 0) {
return;
}
double r = 1.0 / d;
pVarTP.x += pAffineTP.x * r;
pVarTP.y += pAffineTP.y * r;
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 "scry2";
}
private double _sina, _cosa, _sins, _coss, _sinc, _cosc;
@Override
public void init(FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double 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);
}
}