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
No comments :
Post a Comment