# Adventures in Creative Coding.

## Can I show you how I make my work?

Let me show you how I usually do creative coding.

I usually start with some ideas (mathematical, algorithmic, etc). I never decide what I make at the start.

I started with the idea 'Equal distance angles and radii' this time.

## Freely play with the idea.

At first, I play with the idea as I like.

Put circles on the location that calculated with the Perlin noise or just randomly.

Wide interval or narrow interval.

Connecting circles with lines. etc.

Then, I thought it may be interesting if I moved connected circles with the Perlin noise.

## Grasp the feeling of interest.

When I feel it may be interesting, I stop free playing and pursue that interest.

I mean play hard toward the interest that I find.

I tried to make an animation of connected circles with the Perlin noise. I changed radius with the Perlin noise like this.

元はこれから始まった。🧐#processing #creativecoding pic.twitter.com/3pMFmD1qaJ

— deconbatch (@deconbatch) October 11, 2020

```
/**
* How I usually do creative coding.
* An animation of connected circles with the Perlin noise.
*
* @author @deconbatch
* @version 0.1
* @license GPL Version 3 http://www.gnu.org/licenses/
* Processing 3.5.3
* 2020.10.13
*/
void setup() {
size(640, 640);
colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
frameRate(24);
}
void draw() {
int thetaMax = 12;
int radiusMax = 20;
ArrayList<PVector> arcs = new ArrayList<PVector>();
// animation cycle
float frmRatio = map(frameCount % 120, 0, 120, 0.0, TWO_PI);
// calculate the locations with the cyclic Perlin noise
for (int thetaCnt = 0; thetaCnt < thetaMax; thetaCnt++) {
float noiseVal = noise(thetaCnt, 10.0 + 0.5 * cos(frmRatio), 10.0 + 0.5 * sin(frmRatio));
arcs.add(new PVector
(ceil(noiseVal * radiusMax) * min(width, height) * 0.5 / radiusMax,
thetaCnt * TWO_PI / thetaMax
));
}
background(0.0, 0.0, 90.0, 100.0);
translate(width * 0.5, height * 0.5);
stroke(0.0, 0.0, 30.0, 100.0);
// draw lines
noFill();
beginShape();
for (PVector a : arcs) {
vertex(a.x * cos(a.y), a.x * sin(a.y));
}
endShape(CLOSE);
// draw circles
fill(0.0, 0.0, 90.0, 100.0);
for (PVector a : arcs) {
ellipse(a.x * cos(a.y), a.x * sin(a.y), 20.0, 20.0);
}
}
```

Amusing!

I tried to use curveVertex() to connect points smoothly and omitted drawing circles.

Amoeba尊し🦠#processing #creativecoding pic.twitter.com/vSMNzGw0ek

— deconbatch (@deconbatch) October 5, 2020

Amoeba!

Ummm... not bad. But I felt it come to a dead end. So I tried to change the drawing style with the same algorithm.

When I used arc().

機械世界の Amoeba🤖#processing #creativecoding pic.twitter.com/Pr9w4LEH42

— deconbatch (@deconbatch) October 5, 2020

```
for (PVector a : arcs) {
cnt++;
arc(0.0, 0.0,
a.x, a.x,
a.y, a.y + TWO_PI / thetaMax,
PIE
);
}
```

Not bad! Not bad! I felt the interest be able to go further now.

I found that the arc() with noFill() and thick strokeWeight() makes a piece of Baumkuchen.

```
noFill();
strokeWeight(30);
strokeCap(SQUARE);
for (PVector a : arcs) {
cnt++;
arc(0.0, 0.0,
a.x, a.x,
a.y, a.y + TWO_PI / thetaMax
);
}
```

So I combined the color pieces and made an animation of three primary color mixing.

3原色で元気いっぱいの機械式 Amoeba ⚙️🦠#processing #creativecoding pic.twitter.com/BSGhDT6K1W

— deconbatch (@deconbatch) October 5, 2020

Interesting! I can play more!

And I made three different shapes and tried to rotate these.

これが、どこのご家庭にでもある一般的なシリンダー錠の構造をわかりやすく色付けして説明した図ではありません。🔑#processing #creativecoding pic.twitter.com/setAj3ldYN

— deconbatch (@deconbatch) October 6, 2020

回転にイージングをかけてみる。🙂#processing #creativecoding pic.twitter.com/GbRtao3v8B

— deconbatch (@deconbatch) October 6, 2020

And then now, I can see what I want to make.

## Decide what I make at last.

After playing with my interest, I wanted to make an animation of rotating color discs.

I thought it must be nice if the rotation had various rotate angles and each discs rotation timings were the same. And mixing the color of each disc would be beautiful.

I made trial product to verify the idea.

一所懸命に鍵を開けようと何度もトライしてる様子。🤨🔐#processing #creativecoding pic.twitter.com/aYH3sgkuNN

— deconbatch (@deconbatch) October 7, 2020

And made a goal!

雰囲気開いた気がする！🔓😀#processing #creativecoding pic.twitter.com/ymKmliXQhY

— deconbatch (@deconbatch) October 7, 2020

That's all.

- I just start with an idea how to calculate. I never start with what I want to make.
- I play with the idea as I like and try to find a special interest.
- When I find a special interest, I pursue that interest.
- Then, I realize what I want to make.
- Make it.

I've been able to make a goal this time. But not always.

If I can not find a special interest, it will come to a dead end and I do not make anything. But I'll satisfy that I played with creative coding much and had fun! 🙂

## An example source code of Processing.

```
/**
* You Can't Catch Me.
* An animation of rotating discs.
*
* @author @deconbatch
* @version 0.1
* @license GPL Version 3 http://www.gnu.org/licenses/
* Processing 3.5.3
* 2020.10.11
*/
int objMax = 4; // object number
int frmRate = 24; // animation fps
int turnMax = 5; // turn number
float speed = 0.5; // rotation speed : must be > 0.0
float baseHue = random(360.0); // object color
ArrayList<Disc> objs = new ArrayList<Disc>();
void setup() {
size(720, 720);
colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
rectMode(CENTER);
frameRate(frmRate);
// initialize object array
for (int objCnt = 0; objCnt < objMax; objCnt++) {
objs.add(new Disc());
}
}
void draw() {
if (frameCount > frmRate * turnMax / speed) {
exit();
}
background(0.0, 0.0, 90.0, 100.0);
translate(width * 0.5, height * 0.5);
noFill();
for (int objCnt = 0; objCnt < objMax; objCnt++) {
// reset object rotate information
if (!objs.get(objCnt).isRotating()) {
if (frameCount >= frmRate * (turnMax - 1) / speed) {
objs.get(objCnt).rewind(frmRate, speed);
} else {
if (random(1.0) < 0.5) {
objs.get(objCnt).setRotation(frmRate, speed);
}
}
}
// draw object
blendMode(SUBTRACT);
stroke((baseHue + objCnt * 20.0) % 360.0, 90.0, 60.0, 100.0);
pushMatrix();
objs.get(objCnt).rotates();
objs.get(objCnt).draws();
popMatrix();
}
blendMode(BLEND);
casing();
saveFrame("frames/" + String.format("%04d", frameCount) + ".png");
}
/**
* casing : draw fancy casing
*/
public void casing() {
fill(0.0, 0.0, 0.0, 0.0);
strokeWeight(30.0);
stroke(0.0, 0.0, 30.0, 100.0);
rect(0.0, 0.0, width, height);
strokeWeight(28.0);
stroke(0.0, 0.0, 100.0, 100.0);
rect(0.0, 0.0, width, height);
}
/**
* Disc
* holds disc information and control rotation and drawing
*
*/
class Disc {
int arcDiv = 8;
int radiusDiv = 5;
ArrayList<PVector> arcs;
int rotateUnit;
int rotateFrmStart;
int rotateFrmEnd;
float baseRotation;
Disc() {
baseRotation = 0.0;
// failsafe
rotateUnit = 0;
rotateFrmStart = 0;
rotateFrmEnd = 0;
arcs = new ArrayList<PVector>();
for (int arcCnt = 0; arcCnt < arcDiv; arcCnt++) {
arcs.add(new PVector
(
floor(random(radiusDiv * 0.3, radiusDiv)) * min(width, height) * 0.5 / radiusDiv,
arcCnt * TWO_PI / arcDiv
));
}
}
/**
* rewind :
* @param _frmRate : frame rate(fps)
* @param _speed : disc rotate speed
*/
public void rewind(int _frmRate, float _speed) {
float signBaseRot = baseRotation / abs(baseRotation);
float rewindTheta = (abs(baseRotation) > PI) ? signBaseRot * (abs(baseRotation) - TWO_PI) : baseRotation;
rotateUnit = -round(rewindTheta * arcDiv / TWO_PI);
rotateFrmStart = frameCount;
rotateFrmEnd = floor(rotateFrmStart + _frmRate / ((_speed <= 0.0) ? 1.0 : _speed));
}
/**
* setRotation :
* @param _frmRate : frame rate(fps)
* @param _speed : disc rotate speed
*/
public void setRotation(int _frmRate, float _speed) {
rotateUnit = round(random(-arcDiv, arcDiv) * 0.5);
rotateFrmStart = frameCount;
rotateFrmEnd = floor(rotateFrmStart + _frmRate / ((_speed <= 0.0) ? 1.0 : _speed));
}
/**
* rotates : rotate disc
*/
public void rotates() {
if (isRotating()) {
if (frameCount == rotateFrmEnd) {
baseRotation += rotateUnit * TWO_PI / arcDiv;
baseRotation %= TWO_PI;
} else {
float frmRatio = map(frameCount, rotateFrmStart, rotateFrmEnd, 0.0, 1.0);
float easeRatio = InOutCubic(frmRatio);
rotate(rotateUnit * easeRatio * TWO_PI / arcDiv);
}
}
rotate(baseRotation);
}
/**
* draws : draw disc with arc()
*/
public void draws() {
noFill();
strokeCap(SQUARE);
for (int i = 0; i < arcs.size(); i++) {
PVector a = arcs.get(i);
PVector b = arcs.get((i + 1) % arcs.size());
float w = constrain(abs(a.x - b.x), 0.0, a.x);
float r = a.x + w * 0.5;
if (w != 0.0) {
strokeWeight(w);
arc(
0.0, 0.0,
r, r,
a.y, (a.y < b.y) ? b.y : b.y + TWO_PI
);
}
}
}
/**
* isRotating
* @return : rotating = true, not rotating = false
*/
public Boolean isRotating() {
return (frameCount > rotateFrmEnd) ? false : true;
}
/**
* easeInOutCubic easing function.
* @param _t : 0.0 - 1.0 : linear value.
* @return float : 0.0 - 1.0 : eased value.
*/
private float InOutCubic(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;
}
}
/*
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/>
*/
```

## Comments

## 2 comments :

Thanks for this, it was really interesting!

I thank you for reading! 🙂

## Post a Comment