Funny shapes 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;
}
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.
It must be fun to draw a 3D figure with a z coordinate that is calculated with another mixed up function.
The 'Processing' example code.
Please feel free to use this example code under the terms of the GPL. 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.