見出し画像

Generative Art #12

絵のストック放出.以前の再帰分割絵に図形を追加しつつ赤色のアクセントを入れた.白・黒・赤の配色は見てて飽きない.

画像1

画像2

画像3

画像4

画像5

AbstractShape[] shapeList;

void setup() {
 size(800, 800);
 
 background(0);
 rectMode(CENTER);
 
 shapeList = new AbstractShape[] {
   new RectShape(),
   new HeartShape(),
   new DiceShape(),
   new CircleShape(),
   new StripeShape(),
   new PolkaDotShape(),
   new DarkPolkaDotShape()
 };
 
 noLoop();
}

void draw() {
 drawPattern();
}

void drawPattern() {
 float sf = random(1.5, 2.0);
 float[] denominators = new float[] {0.5, 6.0, 4.0, 3.0};
 float rot = PI / denominators[(int)random(denominators.length)];
 rot = rot * (random(1) > 0.5 ? -1.0 : 1.0);
 
 translate(width / 2.0, height / 2.0);
 scale(sf, sf);
 rotate(rot);
 
 background(0);
 recur(new PVector(0.0, 0.0), width, 0);
}

void recur(PVector p, float s, int d) {
 if (d > 1 && random(1) < float(d) / 6) {
   AbstractShape shape = shapeList[(int)random(shapeList.length)];
   shape.drawShape(p, s, d);
 } else {
   recur(new PVector(p.x + s / 4.0, p.y + s / 4.0), s / 2.0, d + 1);
   recur(new PVector(p.x - s / 4.0, p.y + s / 4.0), s / 2.0, d + 1);
   recur(new PVector(p.x + s / 4.0, p.y - s / 4.0), s / 2.0, d + 1);
   recur(new PVector(p.x - s / 4.0, p.y - s / 4.0), s / 2.0, d + 1);
 }
}

static final String timestamp(final String name, final String ext) {
return name + "-" + year() + nf(month(), 2) + nf(day(), 2) +
  "-" + nf(hour(), 2) + nf(minute(), 2) + nf(second(), 2) + ext;
}

void mouseReleased() {
 redraw();
}

void keyReleased() {
 saveFrame(String.format("frames/%s", timestamp("Project", ".png")));
}

abstract class AbstractShape {
 abstract void drawShape(PVector p, float s, int d);
}

class RectShape extends AbstractShape{
 void drawShape(PVector p, float s, int d) {
   fill(0);
   stroke(255);
   
   int n = (int)random(1, 5);
   pushMatrix();
   translate(p.x, p.y);
   for (int k = 0; k < n; k++) {
     rect(0, 0, s, s);
     
     scale(1.0 / sqrt(2), 1.0 / sqrt(2)); // 回転によって外にはみ出ないようにする
     rotate(PI / 4);
     strokeWeight(pow(sqrt(2), k)); // scaleによって線が細くなり過ぎないようにする
   }
   popMatrix();
   
   strokeWeight(1.0);
 }
}

class HeartShape extends AbstractShape {
 void drawShape(PVector p, float s, int d) {
   fill(0);
   noStroke();
   
   color heartColor = color(255);
   if (random(1) < 0.05) {
     heartColor = color(240, 0, 0);
   }
   
   rect(p.x, p.y, s, s);
   
   PShape heart = createHeart();
   heart.beginShape();
   heart.noStroke();
   heart.fill(heartColor);
   heart.endShape();
   
   pushMatrix();
   translate(p.x, p.y);
   scale(s / heart.width / 2.0 * 0.98, s / heart.height / 2.0 * 0.98);
   shape(heart, 0, 0);
   popMatrix();
 }
}

PShape createHeart() {
   int N = 100;
   
   PShape s = createShape();
   s.beginShape();
   for (int k = 0; k < N; k++) {
       float t = TWO_PI * k / (float)N;
       float x = 16 * pow(sin(t), 3);
       float y = -(13 * cos(t) - 5*cos(2*t) - 2*cos(3*t) - cos(4*t));
       s.vertex(x, y);
   }
   s.endShape(CLOSE);
   
   return s;
}

class DiceShape extends AbstractShape {
 void drawShape(PVector p, float s, int d) {
   
   int N = 100;
   float r = s / 8.0;
   int number = (int)random(1, 7);
   color[] dicePalette = null;
   
   if (random(1) < 0.05) {
     dicePalette = new color[] {color(255), color(0), color(240, 0, 0)};
   } else {
     dicePalette = new color[] {color(255), color(0), color(0)};
   }
   
   pushMatrix();
   translate(p.x, p.y);
   
   fill(0);
   noStroke();
   rect(0, 0, s, s);
   
   noStroke();
   fill(dicePalette[0]);
   
   beginShape();
   for (int k = 0; k < N; k++) {
     float t = TWO_PI * k / (float)N;
     float x = r * cos(t);
     float y = r * sin(t);
     
     if (t < PI / 2.0) {
       x = x + (s / 2.0 - r);
       y = y + (s / 2.0 - r);
     } else if (t < PI) {
       x = x - (s / 2.0 - r);
       y = y + (s / 2.0 - r);
     } else if (t < PI * 3 / 2) {
       x = x - (s / 2.0 - r);
       y = y - (s / 2.0 - r);
     } else {
       x = x + (s / 2.0 - r);
       y = y - (s / 2.0 - r);
     }
     
     vertex(x, y);
   }
   endShape(CLOSE);
   
   if (number == 1) {
     fill(dicePalette[2]);
     circle(0, 0, s / 4.0);
   } else if (number == 2) {
     fill(dicePalette[1]);
     circle(s / 3.0, s / 3.0, s / 5.0);
     circle(-s / 3.0, -s / 3.0, s / 5.0);
   } else if (number == 3) {
     fill(dicePalette[1]);
     circle(s / 3.0, s / 3.0, s / 5.0);
     circle(0.0, 0.0, s / 5.0);
     circle(-s / 3.0, -s / 3.0, s / 5.0);
   } else if (number == 4) {
     fill(dicePalette[1]);
     circle(s / 3.0, s / 3.0, s / 5.0);
     circle(-s / 3.0, s / 3.0, s / 5.0);
     circle(s / 3.0, -s / 3.0, s / 5.0);
     circle(-s / 3.0, -s / 3.0, s / 5.0);
   } else if (number == 5) {
     fill(dicePalette[1]);
     circle(0.0, 0.0, s / 5.0);
     circle(s / 3.0, s / 3.0, s / 5.0);
     circle(-s / 3.0, s / 3.0, s / 5.0);
     circle(s / 3.0, -s / 3.0, s / 5.0);
     circle(-s / 3.0, -s / 3.0, s / 5.0);
   } else if (number == 6) {
     fill(dicePalette[1]);
     circle(s / 3.0, 0.0, s / 5.0);
     circle(-s / 3.0, 0.0, s / 5.0);
     circle(s / 3.0, s / 3.0, s / 5.0);
     circle(-s / 3.0, s / 3.0, s / 5.0);
     circle(s / 3.0, -s / 3.0, s / 5.0);
     circle(-s / 3.0, -s / 3.0, s / 5.0);
   }
   
   popMatrix();
 }
}

class CircleShape extends AbstractShape{
 void drawShape(PVector p, float s, int d) {
   fill(0);
   stroke(255);
   
   int n = (int)random(1, 6);
   for (int k = 0; k < n; k++) {
     circle(p.x, p.y, s - s / (float)n * k);
   }
 }
}

class StripeShape extends AbstractShape{
 void drawShape(PVector p, float s, int d) {
   
   boolean rotation = random(1) > 0.5;
   
   fill(255);
   noStroke();
   rect(p.x, p.y, s, s);
   blendMode(SUBTRACT);
   int n = (int)random(1, 6) * 2;
   for (int k = 0; k < n; k++) {
     if (k % 2 != 0) {
       if (!rotation) {
         rect(p.x - s / 2.0 + s / (float)n * k, p.y, s / (float)n, s);
       } else {
         rect(p.x, p.y - s / 2.0 + s / (float)n * k, s, s / (float)n);
       }
     }
   }
   blendMode(BLEND);
 }
}

class PolkaDotShape extends AbstractShape {
 void drawShape(PVector p, float s, int d) {
   fill(255);
   noStroke();
   
   rect(p.x, p.y, s, s);
   
   blendMode(SUBTRACT);
   int n = (int)random(1, 6) * 2 + 1;
   float r = s / (float)n;
   for (int i = 0; i < n; i++) {
     for (int j = 0; j < n; j++) {
       if ((i * n + j) % 2 == 0) {
         float x = p.x - s / 2.0 + r / 2.0 + r * j;
         float y = p.y - s / 2.0 + r / 2.0 + r * i;
         circle(x, y, r / 2.0);
       }
     }
   }
   blendMode(BLEND);
 }
}

class DarkPolkaDotShape extends AbstractShape {
 void drawShape(PVector p, float s, int d) {
   fill(0);
   noStroke();
   
   rect(p.x, p.y, s, s);
   
   blendMode(ADD);
   fill(255);
   int n = (int)random(1, 6) * 2 + 1;
   float r = s / (float)n;
   for (int i = 0; i < n; i++) {
     for (int j = 0; j < n; j++) {
       if ((i * n + j) % 2 == 0) {
         float x = p.x - s / 2.0 + r / 2.0 + r * j;
         float y = p.y - s / 2.0 + r / 2.0 + r * i;
         circle(x, y, r / 2.0);
       }
     }
   }
   blendMode(BLEND);
 }
}

いただいたサポートは主にクリエイターとしての活動費になります