A bent shape like a peacock.

Bending a meaningless symmetrical dot pattern.

This is my creative coding artwork that draws bent symmetrical dot patterns. It's a by-product of my 'More News From Nowhere'. The code was written in Processing.

At first, I tried to make something with rim rectangles.

A generative art with rim rectangles.

It's not bad but I was interested in a small colored rectangles pattern.

A generative art with small colored rectangles pattern.

And I found by chance that I could bend the shape with the 'rotate()' function.

A generative art with small colored rectangles pattern.

I implemented three shape patterns with the 'DrawingWay' class.

A bent shape like a peacock.
Peacock.

A bent shape like a concave.
Concave.

A bent shape like a flag.
Flag.





An example code of Processing.

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

This code does not display any images on the screen but generates image files in frames directory.


/**
 * Above the Clouds.
 * Bending a meaningless symmetrical dot pattern.
 *
 * @author @deconbatch
 * @version 0.1
 * @license GPL Version 3 http://www.gnu.org/licenses/
 * Processing 3.5.3
 * 2021.04.24
 */

void setup() {
  size(980, 980);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  smooth();
  noLoop();
}

void draw() {

  // class of the parameters to draw foreground image
  ArrayList<DrawingWay> dws = new ArrayList();
  dws.add(new Peacock(width, height));
  dws.add(new Concave(width, height));
  dws.add(new Flag(width, height));
  
  int imgCnt = 0;
  for (DrawingWay dw : dws) {

    image(getBackground(width, height), 0.0, 0.0);
    image(getForeground(width, height, dw), 0.0, 0.0);
    casing();

    imgCnt++;
    saveFrame("frames/" + String.format("%04d", imgCnt) + ".png");

  }
  exit();
}

/**
 * getBackground : returns noise field + matrix image
 */
private PImage getBackground(int _w, int _h) {

  PGraphics p = createGraphics(_w, _h);
  p.beginDraw();
  p.colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  p.background(0.0, 0.0, 90.0, 100.0);

  // noise marble
  float noiseStep = 0.025;
  int   stepSize  = 2;
  p.noStroke();
	for (int x = 0; x < width; x += stepSize) {
		float nX = x * noiseStep;
		for (int y = 0; y < height; y += stepSize) {
      float yRatio = map(y, 0, height, 0.0, 1.0);
			float nY = y * noiseStep;
			float nVal = noise(nX, nY, noise(nX, nY) * 10.0);
			float nBri = 50.0 + 20.0 * sin(PI * yRatio) + 20.0 * nVal;
			p.fill(0.0, 0.0, nBri, 100.0);
      p.rect(x, y, stepSize, stepSize);
		}
	}

  // matrix
  int divNum    = 20;
  int divSizX   = floor(width / divNum);
  int divSizY   = floor(height / divNum);
  int selection = floor(random(divNum));
  p.noFill();
  p.strokeWeight(2.0);
  for (int x = 0; x < divNum; x++) {
    for (int y = 0; y < divNum; y++) {
      if ((x * y + x + y) % divNum == selection) {
        p.stroke(0.0, 0.0, random(70.0, 80.0), 100.0);
        p.line(x * divSizX, 0, x * divSizX, height);
        p.line(0, y * divSizY, width, y * divSizY);
      }
    }
  }

  p.endDraw();
  return p;
}

/**
 * getForeground : returns foreground image with the parametes of _dw
 */
private PImage getForeground(int _w, int _h, DrawingWay _dw) {

  int   divNum   = _dw.getNumber();
  int   divSiz   = _dw.getSize();
  int   shapeSiz = divSiz * divNum;
  float rimWidth = min(_w, _h) * 0.04 / divNum;
  float pattern  = random(1.0, 2.0);
  float hueBase  = random(360.0);
  
  PGraphics p = createGraphics(_w, _h);
  p.beginDraw();
  p.colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  p.rectMode(CENTER);

  p.blendMode(REPLACE);
  p.background(0.0, 0.0, 0.0, 0.0);
  p.pushMatrix();
  p.translate(width * 0.5, height * 0.5);
  _dw.rotateCanvas(p);
  p.noStroke();
  for (int x = -shapeSiz; x <= shapeSiz; x += divSiz) {
    for (int y = -shapeSiz; y <= shapeSiz; y += divSiz) {

      float xRatio = x * 1.0 / shapeSiz;
      float yRatio = y * 1.0 / shapeSiz;
        
      float s = abs((((abs(x * x) + abs(y * x)) / divSiz) % pattern) / pattern);
      float t = abs((((x * y + y) / divSiz) % pattern) / pattern);

      float theta  = PI * s;
      float radius = shapeSiz * t;
			
      float rX   = radius * cos(theta);
      float rY   = radius * sin(theta);
      float rHue = hueBase + s * 60.0 + t * 60.0 + xRatio * yRatio * 90.0;

      float sizMin  = divSiz / 20.0 + abs(PI * radius / shapeSiz);
      float wdPlate = constrain(s * divSiz, sizMin, divSiz);
      float htPlate = constrain(t * divSiz, sizMin, divSiz);
      float wdRim   = abs(wdPlate - divSiz * 0.5);
      float htRim   = abs(htPlate - divSiz * 0.5);
      float sizDot  = sizMin * 1.75;

      p.pushMatrix();
      _dw.rotateParts(p, x, y);
      // plate
      p.noStroke();
      p.fill(rHue % 360.0, 40.0, 60.0, 100.0);
      p.rect(x, y, wdPlate, htPlate);
      // rim
      p.stroke((rHue + 60.0) % 360.0, 80.0, 30.0, 100.0);
      p.strokeWeight(rimWidth);
      p.fill(0.0, 0.0, 0.0, 0.0);
      p.rect(x, y, wdRim, htRim);
      // dot
      if (random(1.0) < 0.2) {
        p.stroke((rHue + 30.0) % 360.0, 80.0, 30.0, 100.0);
        p.strokeWeight(random(1.0, 2.0) * rimWidth);
        p.fill(rHue % 360.0, 90.0, 30.0, 100.0);
        p.ellipse(x, y, sizDot, sizDot);
      }
      p.popMatrix();
    }
  }
  p.popMatrix();

  p.endDraw();
  return p;
}

/**
 * casing : draw fancy casing
 */
private void casing() {
  float w = min(width, height) * 0.05;
  fill(0.0, 0.0, 0.0, 0.0);
  strokeWeight(w + 4.0);
  stroke(0.0, 0.0, 0.0, 100.0);
  rect(0.0, 0.0, width, height);
  strokeWeight(w);
  stroke(0.0, 0.0, 100.0, 100.0);
  rect(0.0, 0.0, width, height);
}

/**
 * DrawingWay : drawing parameters.
 */
interface DrawingWay {
  void rotateCanvas(PGraphics _p);
  void rotateParts(PGraphics _p, float _x, float _y);
  int  getNumber();
  int  getSize();
}

private class Peacock implements DrawingWay {
  float w, h;
  Peacock(float _w, float _h) {
    w = _w;
    h = _h;
  }
  void rotateCanvas(PGraphics _p) {
    _p.rotate(-PI * 0.25);
  }
  void rotateParts(PGraphics _p, float _x, float _y) {
    _p.rotate((_x + _y) * PI * 0.0005);
  }
  int  getNumber() {
    return 7;
  }
  int  getSize() {
    return 42;
  }
}

private class Concave implements DrawingWay {
  float w, h;
  float rndParts;
  Concave(float _w, float _h) {
    w = _w;
    h = _h;
  }
  void rotateCanvas(PGraphics _p) {
    // nop
  }
  void rotateParts(PGraphics _p, float _x, float _y) {
    _p.rotate(sin(PI * (_x * _y / w / h)) * PI * 0.08);
  }
  int  getNumber() {
    return 16;
  }
  int  getSize() {
    return 22;
  }
}

private class Flag implements DrawingWay {
  float w, h;
  Flag(float _w, float _h) {
    w = _w;
    h = _h;
  }
  void rotateCanvas(PGraphics _p) {
    _p.rotate(random(-0.01, 0.01) * PI);
  }
  void rotateParts(PGraphics _p, float _x, float _y) {
    _p.rotate((cos(_x * PI / w) + sin(_y * PI / h)) * PI * 0.06);
  }
  int  getNumber() {
    return 8;
  }
  int  getSize() {
    return 39;
  }
}


/*
Copyright (C) 2021- 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/>
*/