Cantina Band : Interesting figures with meaningless formulas.

How I wrote this creative coding.

It's a derived version of the work that draws some figure with meaningless mixed up formulas like 'Twist in the Dark' and 'Sultans of Swing'.

I changed the way to calculate the coordinates from '=' to '+=' in 'Sultans of Swing'. And this is the big change, I started to calculate the x coordinate with mixed up formula also. (And I wonder why I've not tried it till now)

// meaningless wave formula
fX += calcX.calc(plotRatio, radVal) * calcX.mult;
fY += calcY.calc(plotRatio, radVal) * calcY.mult;

It worked and it created various interesting figures. But also it created various sizes, too small to see, bigger than canvas. So I tuned the size to fit the canvas.

adjustSiz = 0.8 * min(width / (maxX - minX), height / (maxY - minY));
~
  curveVertex(pvs.get(i).x * adjustSiz, pvs.get(i).y * adjustSiz);

And also it creates too thin things in rare cases. I excluded these cases.

// exclude thin thing
if (abs((maxX - minX) / (maxY - minY)) < 3.0 &&
    abs((maxY - minY) / (maxX - minX)) < 3.0) {
  break;
}

Too thin thing.

I drew the calculation results with curveVertex() simply this time. I tried various ways to draw but I couldn't decide which was the best way. It will be a future task.

Yet another presentation example.Yet another presentation example.

It must be fun to draw a 3D figure with a z coordinate that is calculated with another mixed up function. 😀

Processing example code.

Please feel free to use this example code.
To see other works based on my code is my pleasure. And my honor.



/**
 * Cantina Band.
 * draws some interesting shapes with meaningless mixed up formulas.
 * 
 * Processing 3.5.3
 * @author @deconbatch
 * @version 0.1
 * created 0.1 2020.08.08
 */

int ptnMax = 3; // pattern No. to draw

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

public void draw() {

  float canvasRot = floor(random(5.0)) * HALF_PI * 0.5;
  float hueBase   = random(360.0);
  float boldBase  = random(2.0);

  float adjustSiz = 0.0;
  float minX = 0.0;
  float minY = 0.0;
  float maxX = 0.0;
  float maxY = 0.0;

  // calculate and hold whole point
  ArrayList<PVector> pvs =  new ArrayList<PVector>();
  for (int i = 0; i < 10; i++) {

    pvs = calcPoints();

    minX = width;
    minY = height;
    maxX = 0.0;
    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);
    }

    // exclude thin thing
    if (abs((maxX - minX) / (maxY - minY)) < 3.0 &&
        abs((maxY - minY) / (maxX - minX)) < 3.0) {
      break;
    }

  }
  
  adjustSiz = 0.8 * min(width / (maxX - minX), height / (maxY - minY));
  
  // draw shape
  background((hueBase + 60.0) % 360.0, 5.0, 90.0, 100.0);
  noFill();

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

  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 - 40.0 * iRatio;
    float lBri = 80.0;
    float lWgt = boldBase + noise(iRatio) * 3.0;
    strokeWeight(lWgt);
    stroke(lHue, lSat, lBri, 50.0);
    curveVertex(pvs.get(i).x * adjustSiz, pvs.get(i).y * adjustSiz);
  }
  endShape();

  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 = 40.0 - 20.0 * iRatio;
    float lBri = map(abs(lHue - 240.0), 0.0, 240.0, 40.0, 30.0); // makes blue bright a little
    float lWgt = boldBase + 1.0;
    strokeWeight(lWgt);
    stroke(lHue, lSat, lBri, 100.0);
    curveVertex(pvs.get(i).x * adjustSiz, pvs.get(i).y * adjustSiz);
  }
  endShape();

  popMatrix();
  
  // draw casing
  casing();

  saveFrame("frames/" + String.format("%04d", frameCount) + ".png");
  if (frameCount >= ptnMax) {
    exit();
  }
  
}

/**
 * calcPoints calculate whole points location and return PVectors.
 */
public ArrayList<PVector> calcPoints() {

  Calculator calcX = getCalculator();
  Calculator calcY = getCalculator();

  int   frmMax   = floor(random(50.0, 200.0));
  int   plotMax  = floor(random(5.0, 30.0));
  float radStart = random(TWO_PI);
  float fX       = random(1.0);
  float fY       = random(1.0);

  ArrayList<PVector> pvs = new ArrayList<PVector>();
	for (int frmCnt = 0; frmCnt < frmMax; frmCnt++) {
  
    float frmRatio = easeInOutCosine(map(frmCnt, 0, frmMax, 0.0, 1.0));

    // moving factor
    float radVal = radStart + frmRatio * 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 - frmRatio) + pX * frmRatio;
      float y = nY * (1.0 - frmRatio) + pY * frmRatio;

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

/**
 * getCalculator returns random calculator.
 */
public Calculator getCalculator() {
  int calcNum = 10;
  float r = random(1.0);

  if (r < 1.0 / calcNum) {
    return new MagicWand();
  } else if (r < 2.0 / calcNum) {
    return new Mountains();
  } else if (r < 3.0 / calcNum) {
    return new WindBlow(); // imaichi?
  } else if (r < 4.0 / calcNum) {
    return new SeeSaw();
  } else if (r < 5.0 / calcNum) {
    return new ThreeStars();
  } else if (r < 6.0 / calcNum) {
    return new BigWave();
  } else if (r < 7.0 / calcNum) {
    return new JustATwoOfUs();
  } else if (r < 8.0 / calcNum) {
    return new PieceOfMyHeart();
  } else if (r < 9.0 / calcNum) {
    return new AndThen();
  } else if (r < 10.0 / calcNum) {
    return new TwistedSister();
  }

  // fail safe
  return new MagicWand();

}

/**
 * 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(0.0, 0.0, width, height);
  strokeWeight(26.0);
  stroke(0.0, 0.0, 100.0, 100.0);
  rect(0.0, 0.0, width, height);
}

/**
 * easeInOutCosine easing function.
 * @param  _t    0.0 - 1.0 : linear value.
 * @return float 0.0 - 1.0 : eased value.
 */
public float easeInOutCosine(float _t) {
  return 0.5 - cos(PI * _t) * 0.5;
}

/**
 * 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 MagicWand extends Calculator {
  MagicWand() {
    super();
  }
  public float calc(float _a, float _b) {
    return _a * (sin(_b) + cos(_b));
  }
}

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

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

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/>
*/


 

Yet another example images.

It draws some figure with meaningless mixed up formulas.

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

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

It draws some figure with meaningless mixed up formulas.

 

 

 

 

 

No comments :

Post a Comment