New Frontier.

 An example image of the drawing with meaningless mixed up formulas.

Combined two creative coding works.

I combined my two works 'Cantina Band' and 'Johnny on the Monorail'.
It draws some interesting shapes with meaningless mixed up formulas. And then, it draws vertical, horizontal, and slanting lines on it.

 It draws various patterns of shape with the pair of formulas.

An example image that was combined my two works 'Cantina Band' and 'Johnny on the Monorail'.
An example image of some interesting shapes with meaningless mixed up formulas.
An example of various patterns of shape with the pair of formulas.

And also, parameters that are given to the formula varies the touch of drawing.

An example image with various parameters.
An example image with various parameters.

You may enjoy creating your own formulas.😉

An example source code of Processing.

Please feel free to use this example code. To see other works based on my code is my pleasure. And my honor.
This code does not display any images on the screen but generates image files in frames directory.


/**
 * New Frontier.
 * draws some interesting shapes with meaningless mixed up formulas.
 * 
 * Processing 3.5.3
 * @author @deconbatch
 * @version 0.1
 * created 0.1 2020.09.19
 */

public void setup() {
  size(980, 980, P2D);
  colorMode(HSB, 360, 100, 100, 100);
  rectMode(CENTER);
  smooth();
  noLoop();
}

public void draw() {

  int   frmMax = 4; // draw 4 images
  float hueBase = random(360.0);

  NiceCalculators ncs = new NiceCalculators();
  NiceParameters nps = new NiceParameters();

  for (int frmCnt = 0; frmCnt < frmMax; frmCnt++) {

    hueBase += 90.0;
    float boldBase  = random(2.0, 4.0);
    float canvasRot = floor(random(5.0)) * HALF_PI * 0.5;
  
    ncs.choose();
    Calculator calcX = ncs.getFirstPart();
    Calculator calcY = ncs.getSecondPart();

    nps.choose();
    int morphMax = nps.getMorph();
    int plotMax  = nps.getPlots();

    // calculate 3 different patterns and hold whole point
    ArrayList<PVector> pvs =  new ArrayList<PVector>();
    pvs = calcPoints(calcX, calcY, morphMax, plotMax);
    pvs.addAll(calcPoints(calcX, calcY, morphMax, plotMax));
    pvs.addAll(calcPoints(calcX, calcY, morphMax, plotMax));

    // calculate size parameter to adjust with the sketch size
    float minX = width;
    float minY = height;
    float maxX = 0.0;
    float maxY = 0.0;
    for (PVector p : pvs) {
      minX = min(minX, p.x);
      minY = min(minY, p.y);
      maxX = max(maxX, p.x);
      maxY = max(maxY, p.y);
    }
    float adjustSiz = 0.85 * min(width / (maxX - minX), height / (maxY - minY));

    // draw background
    blendMode(BLEND);
    strokeWeight(height / 100.0);
    for (int i = 0; i < 100; i++) {
      stroke((hueBase + 60.0) % 360.0, 90.0, 50.0 - i * 0.2, 100.0);
      line(0, i * height/ 100.0, width, i * height/ 100.0);
    }

    blendMode(SCREEN);
    pushMatrix();
    translate(width * 0.5, height * 0.5);
    rotate(canvasRot);
    translate(
              -(maxX + minX) * adjustSiz * 0.5,
              -(maxY + minY) * adjustSiz * 0.5
              );

    // draw main shape
    noFill();
    strokeCap(SQUARE);
    strokeJoin(ROUND);
    beginShape();
    for (int i = 0; i < pvs.size(); i++) {
      float iRatio = map(i, 0, pvs.size(), 0.0, 1.0);
      float lHue = (hueBase + iRatio * 120.0) % 360.0;
      float lSat = 60.0 + 20.0 * iRatio;
      float lBri = 30.0 - iRatio * 20.0;
      strokeWeight(map(iRatio, 0.0, 1.0, boldBase, boldBase * 0.1));
      stroke(lHue, lSat, lBri, 100.0 * iRatio);
      curveVertex(pvs.get(i).x * adjustSiz, pvs.get(i).y * adjustSiz);
    }
    endShape();

    // draw sub lines
    for (int i = 0; i < pvs.size() - 1; i++) {
      int   cons = 0;
      float iRatio = map(i, 0, pvs.size() - 1, 0.0, 1.0);
      float lHue = (hueBase + iRatio * 120.0) % 360.0;
      float lSat = 90.0;
      float lBri = 60 * iRatio;
      noFill();
      stroke(lHue, lSat, lBri, 80.0);
      // vertical, horizontal lines
      for (int j = i + 1; j < pvs.size(); j++) {
        if(abs(pvs.get(i).x - pvs.get(j).x) * adjustSiz < 0.02 ||
           abs(pvs.get(i).y - pvs.get(j).y) * adjustSiz < 0.02) {
          float d = dist(pvs.get(i).x, pvs.get(i).y, pvs.get(j).x, pvs.get(j).y) * adjustSiz;
          if (d > 50.0 && d < 250.0) {
            strokeWeight(boldBase * 0.5);
            line(pvs.get(i).x * adjustSiz, pvs.get(i).y * adjustSiz,
                 pvs.get(j).x * adjustSiz, pvs.get(j).y * adjustSiz);
            cons++;
          }
        }
        // slanting lines
        float slant = atan2(pvs.get(i).y - pvs.get(j).y, pvs.get(i).x - pvs.get(j).x);
        if (abs(slant - HALF_PI * 0.5) < 0.01 || abs(slant - HALF_PI * 1.5) < 0.01) {
          float d = dist(pvs.get(i).x, pvs.get(i).y, pvs.get(j).x, pvs.get(j).y) * adjustSiz;
          if (d > 150.0 && d < 151.0) {
            strokeWeight(boldBase * 0.3);
            line(pvs.get(i).x * adjustSiz, pvs.get(i).y * adjustSiz,
                 pvs.get(j).x * adjustSiz, pvs.get(j).y * adjustSiz);
            cons++;
          }
        }
      }

      // terminal objects
      if (cons > 0 && cons < 10) {
        float fAlp = random(30.0, 90.0);
        float fSiz = cons * 240.0 / fAlp;
        noStroke();
        fill(lHue, lSat * 2.0, lBri, fAlp);
        if (cons % 2 == 0) {
          rect(pvs.get(i).x * adjustSiz, pvs.get(i).y * adjustSiz, fSiz, fSiz, 4);
        } else {
          ellipse(pvs.get(i).x * adjustSiz, pvs.get(i).y * adjustSiz, fSiz, fSiz);
        }
      }
    }
    popMatrix();
  
    // draw casing
    blendMode(BLEND);
    casing();

    saveFrame("frames/" + String.format("%04d", frmCnt + 1) + ".png");
  }
  exit();
}

/**
 * calcPoints calculate whole points location and return PVectors.
 */
public ArrayList<PVector> calcPoints(Calculator _calcX, Calculator _calcY, int _morphMax, int _plotMax) {

  float radStart = random(TWO_PI);
  float fX       = random(1.0);
  float fY       = random(1.0);
 
  ArrayList<PVector> pvs = new ArrayList<PVector>();
	for (int morphCnt = 0; morphCnt < _morphMax; morphCnt++) {
  
    float morphRatio = easeInOutCubic(map(morphCnt, 0, _morphMax, 0.0, 1.0));

    // moving factor
    float radVal = radStart + morphRatio * TWO_PI;

    for (int i = 0; i < _plotMax; i++) {
      float plotRatio = map(i, 0, _plotMax, 0.0, 1.0);
      // meaningless wave formula
      fX += _calcX.calc(plotRatio, radVal) * _calcX.mult;
      fY += _calcY.calc(plotRatio, radVal) * _calcY.mult;
      fX %= width * _calcX.mod;
      fY %= height * _calcY.mod;
    
      // wave shape in normal coordinate
      float nX = (fX - 0.5);
      float nY = (fY - 0.5);

      // wave shape in polar coordinate
      float pX = fY * cos(fX) * 0.5;
      float pY = fY * sin(fX) * 0.5;

      // morphing
      float x = nX * (1.0 - morphRatio) + pX * morphRatio;
      float y = nY * (1.0 - morphRatio) + pY * morphRatio;

      pvs.add(new PVector(x, y));
    }
  }
  return pvs;
}


/**
 * casing : draw fancy casing
 */
public void casing() {
  fill(0.0, 0.0, 0.0, 0.0);
  strokeWeight(30.0);
  stroke(0.0, 0.0, 0.0, 100.0);
  rect(width * 0.5, height * 0.5, width, height);
  strokeWeight(26.0);
  stroke(0.0, 0.0, 90.0, 100.0);
  rect(width * 0.5, height * 0.5, width, height);
}

/**
 * easeInOutCubic easing function.
 * @param  _t    0.0 - 1.0 : linear value.
 * @return float 0.0 - 1.0 : eased value.
 */
public float easeInOutCubic(float _t) {
  _t *= 2.0;
  if (_t < 1.0) {
    return pow(_t, 3) / 2.0;
  }
  _t -= 2.0;
  return (pow(_t, 3) + 2.0) / 2.0;
}

/**
 * NiceCalculators
 * choose a pair of Calculators that create a nice result.
 *
 */
public class NiceCalculators {
  private Calculator cFirst, cSecond;
  private ArrayList<Pair> pairs = new ArrayList<Pair>();

  NiceCalculators() {
    pairs.add(new Pair(new JustATwoOfUs(), new PieceOfMyHeart()));
    pairs.add(new Pair(new JustATwoOfUs(), new AndThen()));
    pairs.add(new Pair(new JustATwoOfUs(), new Mountains()));
    pairs.add(new Pair(new JustATwoOfUs(), new SeeSaw()));
    pairs.add(new Pair(new PieceOfMyHeart(), new JustATwoOfUs()));
    pairs.add(new Pair(new PieceOfMyHeart(), new Mountains()));
    pairs.add(new Pair(new Mountains(), new BigWave()));
    pairs.add(new Pair(new Mountains(), new TwistedSister()));
    pairs.add(new Pair(new SeeSaw(), new AndThen()));
    pairs.add(new Pair(new SeeSaw(), new Mountains()));
    pairs.add(new Pair(new TwistedSister(), new BigWave()));
    pairs.add(new Pair(new ThreeStars(), new Mountains()));

    choose();
  }

  public Calculator getFirstPart() {
    return cFirst;
  }

  public Calculator getSecondPart() {
    return cSecond;
  }

  public void choose() {
    Pair choice = pairs.get(floor(random(pairs.size())));
    cFirst = choice.cFirst;
    cSecond = choice.cSecond;
  }

  /**
   * Pair
   * holds pair of Calculators.
   */
  private class Pair {
    public Calculator cFirst, cSecond;
    Pair(Calculator _a, Calculator _b) {
      cFirst = _a;
      cSecond = _b;
    }
  }
}


/**
 * NiceParameters
 * choose a pair of parameters to create a nice result.
 *
 */
public class NiceParameters {
  private int pMorph, pPlots;
  private ArrayList<Pair> pairs = new ArrayList<Pair>();

  NiceParameters() {
    pairs.add(new Pair(5, 1000));
    pairs.add(new Pair(30, 50));
    pairs.add(new Pair(125, 17));
    pairs.add(new Pair(200, 5));
    pairs.add(new Pair(500, 3));
    choose();
  }

  public int getMorph() {
    return pMorph;
  }

  public int getPlots() {
    return pPlots;
  }

  public void choose() {
    Pair choice = pairs.get(floor(random(pairs.size())));
    pMorph = choice.pMorph;
    pPlots = choice.pPlots;
  }

  /**
   * Pair
   * holds pair of parameters.
   */
  private class Pair {
    public int pMorph, pPlots;
    Pair(int _a, int _b) {
      pMorph = _a;
      pPlots = _b;
    }
  }
}

/**
 * Calculator
 * collection of mixed up functions.
 */
public abstract class Calculator {

  public float mod;
  public float mult;

  Calculator() {
    mod  = random(0.2, 1.0);
    mult = random(0.1, 1.0);
  }
  
  public float calc(float _a, float _b) {
    return 0.0;
  };
}

class Mountains extends Calculator {
  Mountains() {
    super();
  }
  public float calc(float _a, float _b) {
    return cos(_a * _b) * sin(_a + _b * 0.5);
  }
}


class SeeSaw extends Calculator {
  SeeSaw() {
    super();
  }
  public float calc(float _a, float _b) {
    return cos(_b) * cos(_a * PI);
  }
}

class ThreeStars extends Calculator {
  ThreeStars() {
    super();
  }
  public float calc(float _a, float _b) {
    return sin(_a * TWO_PI + _b);
  }
}

class BigWave extends Calculator {
  BigWave() {
    super();
  }
  public float calc(float _a, float _b) {
    return sin(_a * TWO_PI + _b) * (cos(_b) + cos(_a * PI));
  }
}

class JustATwoOfUs extends Calculator {
  JustATwoOfUs() {
    super();
  }
  public float calc(float _a, float _b) {
    return sin(_a * TWO_PI) * sin(_b);
  }
}

class PieceOfMyHeart extends Calculator {
  PieceOfMyHeart() {
    super();
  }
  public float calc(float _a, float _b) {
    return sin(0.05 * _a * sin(_b));
  }
}

class AndThen extends Calculator {
  AndThen() {
    super();
  }
  public float calc(float _a, float _b) {
    return log(1.0 + _a + pow(sin(_b), 2)) * 0.1;
  }
}

class TwistedSister extends Calculator {
  TwistedSister() {
    super();
  }
  public float calc(float _a, float _b) {
    return (sin((_a * TWO_PI) % _b) * cos(_b % sqrt(_b))) * log(1.0 + _a);
  }
}

/*
Copyright (C) 2020- deconbatch

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>
*/




No comments :

Post a Comment