Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- 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.sin;
- import static org.jwildfire.base.mathlib.MathLib.cos;
- import static org.jwildfire.base.mathlib.MathLib.fmod;
- import static org.jwildfire.base.mathlib.MathLib.M_PI;
- import static org.jwildfire.base.mathlib.MathLib.M_2PI;
- 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;
- import org.jwildfire.create.tina.random.AbstractRandomGenerator;
- public class FiveFoldFunc extends VariationFunc {
- private static final long serialVersionUID = 1L;
- private static final String PARAM_T = "t";
- private static final String PARAM_COL1 = "col1";
- private static final String PARAM_COL2 = "col2";
- private static final String PARAM_ON = "on";
- private static final String PARAM_ITT = "itt";
- private static final String PARAM_EQ = "eq";
- private static final String PARAM_DEPTH = "depth";
- private static final String PARAM_ON1 = "on1";
- private static final String PARAM_ITT1 = "itt1";
- private static final String PARAM_EQ1 = "eq1";
- private static final String PARAM_DEPTH1 = "depth1";
- private static final String PARAM_ON2 = "on2";
- private static final String PARAM_ITT2 = "itt2";
- private static final String PARAM_EQ2 = "eq2";
- private static final String PARAM_DEPTH2 = "depth2";
- private static final String[] paramNames = { PARAM_T, PARAM_COL1, PARAM_COL2, PARAM_ON, PARAM_ITT, PARAM_EQ, PARAM_DEPTH,
- PARAM_ON1, PARAM_ITT1, PARAM_EQ1, PARAM_DEPTH1, PARAM_ON2, PARAM_ITT2, PARAM_EQ2, PARAM_DEPTH2 };
- private int t = 2;
- private double col1 = Math.round(Math.random() * 35 + 10) / 100.0, col2 = Math.round(Math.random() * 35 + 55) / 100.0;
- private double on = Math.round(Math.random()), on1 = Math.round(Math.random()), on2 = Math.round(Math.random());
- private int itt = (int) (Math.random() * 5 + 1), itt1 = (int) (Math.random() * 5), itt2 = (int) (Math.random() * 5);
- private int eq = (int) (Math.random() * 2 + 1), eq1 = (int) (Math.random() * 2 + 1), eq2 = (int) (Math.random() * 2 + 1);
- private int depth = (int) (Math.random() * 4), depth1 = (int) (Math.random() * 4), depth2 = (int) (Math.random() * 4);
- private class triangle {
- int type;
- double x1, y1, x2, y2, x3, y3;
- double col;
- public void assign(triangle t) {
- type = t.type; col = t.col;
- x1 = t.x1; y1 = t.y1;
- x2 = t.x2; y2 = t.y2;
- x3 = t.x3; y3 = t.y3;
- }
- private void triBlur(XYZPoint p) {
- double u, v, v1, v2, w, x, x0, x1, x2, x3, x4, x5, x6, y, y0, y1, y2, y3, y4, y5, y6;
- if (this.x1 <= this.x2 && this.x1 <= this.x3) {
- if (this.x2 <= this.x3) {
- x1 = this.x1; y1 = this.y1;
- x2 = this.x2; y2 = this.y2;
- x3 = this.x3; y3 = this.y3;
- }
- else {
- x1 = this.x1; y1 = this.y1;
- x2 = this.x3; y2 = this.y3;
- x3 = this.x2; y3 = this.y2;
- }
- }
- else if (this.x2 <= this.x1 && this.x2 <= this.x3){
- if (this.x1 <= this.x3) {
- x1 = this.x2; y1 = this.y2;
- x2 = this.x1; y2 = this.y1;
- x3 = this.x3; y3 = this.y3;
- }
- else {
- x1 = this.x2; y1 = this.y2;
- x2 = this.x3; y2 = this.y3;
- x3 = this.x1; y3 = this.y1;
- }
- }
- else {
- if (this.x1 <= this.x2) {
- x1 = this.x3; y1 = this.y3;
- x2 = this.x1; y2 = this.y1;
- x3 = this.x2; y3 = this.y2;
- }
- else {
- x1 = this.x3; y1 = this.y3;
- x2 = this.x2; y2 = this.y2;
- x3 = this.x1; y3 = this.y1;
- }
- }
- double r1 = genRand.random(), r2 = genRand.random();
- if (x1 == x2 && x2 == x3) {
- u = x1;
- if (y1 <= y2 && y1 <= y3) {
- v1 = y1;
- v2 = (y3 > y2) ? y2 : y3;
- }
- else if (y2 <= y1 && y2 <= y3) {
- v1 = y2;
- v2 = (y3 > y1) ? y1 : y3;
- }
- else {
- v1 = y3;
- v2 = (y2 > y1) ? y1 : y2;
- }
- v = v1 + r1 * (v2 - v1);
- }
- else if (x1 == x2) {
- x4 = (x1 + x3) / 2; y4 = (y1 + y3) / 2;
- x5 = x3 + x2 - x4; y5 = y3 + y2 - y4;
- x6 = x1 + x2 - x4; y6 = y1 + y2 - y4;
- x = x3 + r1 * (x4 - x3); y = y3 + r1 * (y4 - y3);
- x0 = x5 + r1 * (x2 - x5); y0 = y5 + r1 * (y2 - y5);
- u = x + r2 * (x0 - x); v = y + r2 * (y0 - y);
- w = y3 + (y2 - y3) / (x2 - x3) * (u - x3);
- if (y2 > y3 + (y3 - y1) / (x3 - x1) * (x2 - x3)) {
- if (v > w) {
- x = x4 + r1 * (x1 - x4); y = y4 + r1 * (y1 - y4);
- x0 = x2 + r1 * (x6 - x2); y0 = y2 + r1 * (y6 - y2);
- u = x0 + r2 * (x - x0); v = y0 + r2 * (y - y0);
- }
- }
- else {
- if (v < w) {
- x = x4 + r1 * (x1 - x4); y = y4 + r1 * (y1 - y4);
- x0 = x2 + r1 * (x6 - x2); y0 = y2 + r1 * (y6 - y2);
- u = x0 + r2 * (x - x0); v = y0 + r2 * (y - y0);
- }
- }
- }
- else {
- x4 = (x1 + x3) / 2; y4 = (y1 + y3) / 2;
- x5 = x1 + x2 - x4; y5 = y1 + y2 - y4;
- x6 = x3 + x2 - x4; y6 = y3 + y2 - y4;
- x = x1 + r1 * (x4 - x1); y = y1 + r1 * (y4 - y1);
- x0 = x5 + r1 * (x2 - x5); y0 = y5 + r1 * (y2 - y5);
- u = x + r2 * (x0 - x); v = y + r2 * (y0 - y);
- w = y1 + (y2 - y1) / (x2 - x1) * (u - x1);
- if (y2 > y1 + (y3 - y1) / (x3 - x1) * (x2 - x1)) {
- if (v > w) {
- x = x4 + r1 * (x3 - x4); y = y4 + r1 * (y3 - y4);
- x0 = x2 + r1 * (x6 - x2); y0 = y2 + r1 * (y6 - y2);
- u = x0 + r2 * (x - x0); v = y0 + r2 * (y - y0);
- }
- }
- else {
- if (v < w) {
- x = x4 + r1 * (x3 - x4); y = y4 + r1 * (y3 - y4);
- x0 = x2 + r1 * (x6 - x2); y0 = y2 + r1 * (y6 - y2);
- u = x0 + r2 * (x - x0); v = y0 + r2 * (y - y0);
- }
- }
- }
- if (x1 == x2 && y1 == y2) {
- u = x1 + r1 * (x3 - x1); v = y1 + r1 * (y3 - y1);
- }
- if (x1 == x3 && y1 == y3) {
- u = x1 + r1 * (x2 - x1); v = y1 + r1 * (y2 - y1);
- }
- if (x2 == x3 && y2 == y3) {
- u = x1 + r1 * (x2 - x1); v = y1 + r1 * (y2 - y1);
- }
- p.x = u;
- p.y = v;
- p.z = 0;
- }
- }
- private triangle orig, t1, t2;
- private XYZPoint p;
- private double alfa;
- AbstractRandomGenerator genRand;
- private double discretNoise(int x) {
- int n = x;
- n = (n << 13) ^ n;
- return ((n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / (double) 0x7fffffff;
- }
- private void fiveFoldDevis(triangle in, triangle out) {
- double x4, y4, x5, y5;
- double w;
- switch (in.type) {
- case 1:
- x4 = in.x2 + alfa * (in.x3 - in.x2); y4 = in.y2 + alfa * (in.y3 - in.y2);
- w = genRand.random();
- if (w < alfa*alfa) {
- out.type = 1; out.col = col1;
- out.x1 = in.x3; out.y1 = in.y3;
- out.x2 = in.x1; out.y2 = in.y1;
- out.x3 = x4; out.y3 = y4;
- }
- else {
- out.type = 2; out.col = col2;
- out.x1 = in.x2; out.y1 = in.y2;
- out.x2 = x4; out.y2 = y4;
- out.x3 = in.x1; out.y3 = in.y1;
- }
- break;
- case 2:
- x4 = in.x3 + alfa * (in.x1 - in.x3); y4 = in.y3 + alfa * (in.y1 - in.y3);
- x5 = in.x3 + alfa * (in.x2 - in.x3); y5 = in.y3 + alfa * (in.y2 - in.y3);
- w = genRand.random();
- if (w < alfa*alfa) {
- out.type = 2; out.col = col2;
- out.x1 = in.x2; out.y1 = in.y2;
- out.x2 = x4; out.y2 = y4;
- out.x3 = in.x1; out.y3 = in.y1;
- }
- else if (w < 2*alfa*alfa) {
- out.type = 2; out.col = col2;
- out.x1 = in.x3; out.y1 = in.y3;
- out.x2 = x5; out.y2 = y5;
- out.x3 = x4; out.y3 = y4;
- }
- else {
- out.type = 1; out.col = col1;
- out.x1 = in.x2; out.y1 = in.y2;
- out.x2 = x4; out.y2 = y4;
- out.x3 = x5; out.y3 = y5;
- }
- break;
- }
- }
- @Override
- public void init(FlameTransformationContext pContext, Layer pLayer, XForm pXForm, double pAmount) {
- orig = new triangle();
- switch (t) {
- case 1:
- orig.type = 1; orig.col = col1;
- orig.x1 = 0.0; orig.y1 = 0.0;
- orig.x2 = cos(M_2PI/5); orig.y2 = sin(M_2PI/5);
- orig.x3 = 2 * orig.x2; orig.y3 = 0.0;
- break;
- case 2:
- orig.type = 2; orig.col = col2;
- orig.x1 = 0.0; orig.y1 = 0.0;
- orig.x2 = cos(M_PI/5); orig.y2 = sin(M_PI/5);
- orig.x3 = 2 * orig.x2; orig.y3 = 0.0;
- break;
- }
- alfa = 2*cos(M_2PI/5);
- genRand = pContext.getRandGen();
- t1 = new triangle();
- t2 = new triangle();
- p = new XYZPoint();
- }
- @Override
- public void transform(FlameTransformationContext pContext, XForm pXForm, XYZPoint pAffineTP, XYZPoint pVarTP, double pAmount) {
- /* FiveFold by eralex61, https://eralex61.deviantart.com/art/Five-fold-example-of-finite-recurent-system-in-Apo-705813367 */
- t1.assign(orig);
- t2.assign(orig);
- int n = itt;
- int k = 1;
- while (n > 0) {
- fiveFoldDevis(t1, t2);
- t1.assign(t2);
- if (on < 0.5) {
- if ((k == itt) && (t1.type != eq)) n = n + depth;
- }
- else {
- if ((k >= itt) && (k < itt + depth) && (t1.type != eq)) n = n + 1;
- }
- n = n - 1;
- k = k + 1;
- }
- int m = 0;
- switch (t1.type) {
- case 1:
- n = itt1;
- k = 1;
- while (n > 0) {
- fiveFoldDevis(t1, t2);
- t1.assign(t2);
- m = 2 * m + t2.type - 1;
- if (on1 < 0.5) {
- if ((k == itt1) && (t1.type != eq1)) n = n + depth1;
- }
- else {
- if ((k >= itt1) && (k < itt1 + depth1) && (t1.type != eq1)) n = n + 1;
- }
- n = n - 1;
- k = k + 1;
- }
- t1.col = discretNoise(m+43);
- break;
- case 2:
- n = itt2;
- k = 1;
- while (n > 0) {
- fiveFoldDevis(t1, t2);
- t1.assign(t2);
- m = 2 * m + t2.type - 1;
- if (on2 < 0.5) {
- if ((k == itt2) && (t1.type != eq2)) n = n + depth2;
- }
- else {
- if ((k >= itt2) && (k < itt2 + depth2) && (t1.type != eq2)) n = n + 1;
- }
- n = n - 1;
- k = k + 1;
- }
- t1.col = discretNoise(m+31);
- break;
- }
- t2.triBlur(p);
- pVarTP.x += pAmount * p.x;
- pVarTP.y += pAmount * p.y;
- pVarTP.z += pAmount * p.z;
- pVarTP.color = fmod(t1.col + t2.col, 1.0);
- if (pVarTP.color < 0.0) pVarTP.color += 1.0;
- }
- @Override
- public String[] getParameterNames() {
- return paramNames;
- }
- @Override
- public Object[] getParameterValues() {
- return new Object[] { t, col1, col2, on, itt, eq, depth, on1, itt1, eq1, depth1, on2, itt2, eq2, depth2 };
- }
- @Override
- public String[] getParameterAlternativeNames() {
- return new String[] { "FiveFold_T", "FiveFold_Col1", "FiveFold_Col2", "FiveFold_On", "FiveFold_Itt", "FiveFold_Eq", "FiveFold_Depth", "FiveFold_On1", "FiveFold_Itt1", "FiveFold_Eq1", "FiveFold_Depth1", "FiveFold_On2", "FiveFold_Itt2", "FiveFold_Eq2", "FiveFold_Depth2" };
- }
- @Override
- public void setParameter(String pName, double pValue) {
- if (PARAM_ON.equalsIgnoreCase(pName))
- on = pValue;
- else if (PARAM_COL1.equalsIgnoreCase(pName))
- col1 = pValue;
- else if (PARAM_COL2.equalsIgnoreCase(pName))
- col2 = pValue;
- else if (PARAM_T.equalsIgnoreCase(pName))
- t = Tools.FTOI(pValue);
- else if (PARAM_ITT.equalsIgnoreCase(pName))
- itt = Tools.FTOI(pValue);
- else if (PARAM_EQ.equalsIgnoreCase(pName))
- eq = Tools.FTOI(pValue);
- else if (PARAM_DEPTH.equalsIgnoreCase(pName))
- depth = Tools.FTOI(pValue);
- else if (PARAM_ON1.equalsIgnoreCase(pName))
- on1 = pValue;
- else if (PARAM_ITT1.equalsIgnoreCase(pName))
- itt1 = Tools.FTOI(pValue);
- else if (PARAM_EQ1.equalsIgnoreCase(pName))
- eq1 = Tools.FTOI(pValue);
- else if (PARAM_DEPTH1.equalsIgnoreCase(pName))
- depth1 = Tools.FTOI(pValue);
- else if (PARAM_ON2.equalsIgnoreCase(pName))
- on2 = pValue;
- else if (PARAM_ITT2.equalsIgnoreCase(pName))
- itt2 = Tools.FTOI(pValue);
- else if (PARAM_EQ2.equalsIgnoreCase(pName))
- eq2 = Tools.FTOI(pValue);
- else if (PARAM_DEPTH2.equalsIgnoreCase(pName))
- depth2 = Tools.FTOI(pValue);
- else
- throw new IllegalArgumentException(pName);
- }
- @Override
- public String getName() {
- return "fiveFold";
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement