package org.jwildfire.create.tina.variation;
/*
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.
*/
import static org.jwildfire.base.mathlib.MathLib.M_2PI;
import static org.jwildfire.base.mathlib.MathLib.M_PI;
import static org.jwildfire.base.mathlib.MathLib.acos;
import static org.jwildfire.base.mathlib.MathLib.atan;
import static org.jwildfire.base.mathlib.MathLib.cos;
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.create.tina.base.Layer;
import org.jwildfire.create.tina.base.XForm;
import org.jwildfire.create.tina.base.XYZPoint;
/**
* @author Branden Brown, a.k.a. zephyrtronium, transcribed by Nic Anderson, chronologicaldot
* @date July 19, 2014 (transcribe)
*/
public class PostHeatFunc extends VariationFunc {
private static final long serialVersionUID = 1L;
private static final String PARAM_THETA_PERIOD = "theta_period";
private static final String PARAM_THETA_PHASE = "theta_phase";
private static final String PARAM_THETA_AMPLITUDE = "theta_amp";
private static final String PARAM_PHI_PERIOD = "phi_period";
private static final String PARAM_PHI_PHASE = "phi_phase";
private static final String PARAM_PHI_AMPLITUDE = "phi_amp";
private static final String PARAM_R_PERIOD = "r_period";
private static final String PARAM_R_PHASE = "r_phase";
private static final String PARAM_R_AMPLITUDE = "r_amp";
private static final String[] paramNames = { PARAM_THETA_PERIOD, PARAM_THETA_PHASE, PARAM_THETA_AMPLITUDE, PARAM_PHI_PERIOD, PARAM_PHI_PHASE, PARAM_PHI_AMPLITUDE, PARAM_R_PERIOD, PARAM_R_PHASE, PARAM_R_AMPLITUDE };
double theta_period = 0.0;
double theta_phase = 0.0;
double theta_amp = 0.0;
double phi_period = 0.0;
double phi_phase = 0.0;
double phi_amp = 0.0;
double r_period = 0.0;
double r_phase = 0.0;
double r_amp = 0.0;
double at, bt, ct, ap, bp, cp, ar, br, cr;
@Override
public void init(FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double pAmount) {
}
@Override
public void transform(FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) {
double tx = theta_period == 0 ? 0.0 : 1.0 / theta_period;
double px = phi_period == 0 ? 0.0 : 1.0 / phi_period;
double rx = r_period == 0 ? 0.0 : 1.0 / r_period;
at = pAmount * theta_amp;
bt = M_2PI * tx;
ct = theta_phase * tx;
ap = pAmount * phi_amp;
bp = M_2PI * px;
cp = phi_phase * px;
ar = pAmount * r_amp;
br = M_2PI * rx;
cr = r_phase * rx;
double r = sqrt(sqr(pVarTP.x) + sqr(pVarTP.y) + sqr(pVarTP.z));
double sint, cost, sinp, cosp, atant, acosp;
// avoid dividing by zero
if (pVarTP.x != 0) {
atant = atan(pVarTP.y / pVarTP.x);
}
else {
atant = M_PI / 2.0;
}
r += ar * sin(br * r + cr);
sint = at * sin(bt * r + ct) + atant;
cost = cos(sint);
sint = sin(sint);
if (r != 0) {
acosp = pVarTP.z / r;
}
else {
acosp = 0; //pVarTP.z >= 0? 10000 : -10000;
}
sinp = ap * sin(bp * r + cp) + acos(acosp);
cosp = cos(sinp);
sinp = sin(sinp);
pVarTP.x += r * cost * sinp;
pVarTP.y += r * sint * sinp;
pVarTP.z += r * cosp;
}
@Override
public String getName() {
return "post_heat";
}
@Override
public String[] getParameterNames() {
return paramNames;
}
@Override
public Object[] getParameterValues() {
return new Object[] {
theta_period, theta_phase, theta_amp,
phi_period, phi_phase, phi_amp,
r_period, r_phase, r_amp };
}
@Override
public void setParameter(String pName, double pValue) {
if (pName.equalsIgnoreCase(PARAM_THETA_PERIOD)) {
theta_period = pValue;
}
else if (pName.equalsIgnoreCase(PARAM_THETA_PHASE)) {
theta_phase = pValue;
}
else if (pName.equalsIgnoreCase(PARAM_THETA_AMPLITUDE)) {
theta_amp = pValue;
}
else if (pName.equalsIgnoreCase(PARAM_PHI_PERIOD)) {
phi_period = pValue;
}
else if (pName.equalsIgnoreCase(PARAM_PHI_PHASE)) {
phi_phase = pValue;
}
else if (pName.equalsIgnoreCase(PARAM_PHI_AMPLITUDE)) {
phi_amp = pValue;
}
else if (pName.equalsIgnoreCase(PARAM_R_PERIOD)) {
r_period = pValue;
}
else if (pName.equalsIgnoreCase(PARAM_R_PHASE)) {
r_phase = pValue;
}
else if (pName.equalsIgnoreCase(PARAM_R_AMPLITUDE)) {
r_amp = pValue;
}
else
throw new IllegalArgumentException(pName);
}
@Override
public int getPriority() {
return 1;
}
}