Salvaging a sunken code from my brain ocean.

It's a creative coding artwork that creates a still image of a large number of vertical thin lines. And it's a response to the call of reproduction of my past work.


Sometimes, I've written a blog post about my code. But mostly I scribble freely and abandon the code often. I tried to reproduce my past work this time that because I got fun when I reproduced the classic of Vera Molnár.

The result was like this. It's not perfect reproduction but not bad I think.



The 'custonNoise' function and the formula below create the vertical thin lines. We may get yet another interesting result when we change these right way.

  float amplitude = ampBase * (1.0 + lineRatio + noise(lineRatio, thetaRatio));
  float vibration = sin(customNoise(lineRatio * PI + theta * thetaMult) * PI + phase);


 

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.








/**
 * Raining in My Heart.
 * draws vertical thin lines.
 *
 * @author @deconbatch
 * @version 0.1
 * @license GPL Version 3 http://www.gnu.org/licenses/
 * Processing 3.5.3
 * 2021.04.12
 */

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

void draw() {
  
  int   imgMax    = 5;             // output image file number
  int   lineMax   = 9;             // horizontal line number
  float ampBase   = height * 0.05; // height of vertical thin lines
  float thetaDiv  = PI * 0.001;    // density of vertical thin lines
  float thetaMult = 20.0;          // changes pattern of vertical thin lines
  float thetaMax  = PI * width / 90.0;
  float marginY   = (height / lineMax) * 0.5;
  int   noiseBase = floor(random(100.0));

  PImage bg = getBackground(width, height);
  for (int imgCnt = 0; imgCnt < imgMax; imgCnt++) {

    noiseSeed(noiseBase + imgCnt);
    float phase   = random(TWO_PI);
    float hueBase = random(360.0);
    
    // draw background
    blendMode(BLEND);
    background(0.0, 0.0, 90.0, 100.0);
    image(bg, 0, 0);

    // draw foreground
    blendMode(SUBTRACT);
    noStroke();
    for (int lineCnt = 0; lineCnt < lineMax; lineCnt++) {
      float lineRatio = map(lineCnt, 0, lineMax, 0.0, 1.0);
      float direction = (lineCnt % 2 == 0) ? 1.0 : -1.0;

      beginShape();
      fill((hueBase + lineRatio * 360) % 360.0, 50.0, 30.0, 100.0);
      for (float theta = 0.0; theta < thetaMax; theta += thetaDiv) {
        float thetaRatio = map(theta, 0.0, thetaMax, 0.0, 1.0);

        float lineBase  = marginY + lineRatio * height;
        float amplitude = ampBase * (1.0 + lineRatio + noise(lineRatio, thetaRatio));
        float vibration = sin(customNoise(lineRatio * PI + theta * thetaMult) * PI + phase);

        float x = (0.5 * (1.0 + direction) - direction * thetaRatio) * width;
        float y = lineBase + amplitude * vibration;
        vertex(x, y);
      }
      endShape();

    }

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

  }
  exit();
}

/**
 * getBackground : returns background image
 */
private PImage getBackground(int _w, int _h) {

  float div = min(_w, _h) * 0.01;
  
  PGraphics p = createGraphics(_w, _h);
  p.beginDraw();
  p.colorMode(HSB, 360, 100, 100, 100);
  p.background(0.0, 0.0, 100.0, 100.0);
  // matrix
  p.noFill();
  p.stroke(0.0, 0.0, 90.0, 100.0);
  p.strokeWeight(1.0);
  for (float x = 0; x < p.width; x += div) {
    p.line(x, 0, x, p.height);
  }
  for (float y = 0; y < p.height; y += div) {
    p.line(0, y, p.width, y);
  }
  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 * 1.1);
  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);
  noStroke();
  noFill();
  noStroke();
}

/**
 * customNoise : returns custom noise value
 */
private float customNoise(float value) {
  return sin(value * cos(value));
}


/*
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/>
*/




How to tune the result.

  size(980, 980);

You can change the image size with 'size(width, height)'. I've written the value with the ratio of image size not literal in this code, so it will create a similar result with any image size.

  int   imgMax    = 5;

It's a number of the creating images.
This code does not show the result on the display. The results are the PNG image files in the 'frames' directory.

These four parameters affect the looks. I listed these in order of importance.
  int   lineMax   = 9;

It's the number of the horizontal thick belts.

  float ampBase   = height * 0.05;

It's the thickness of each belt.

  float thetaDiv  = PI * 0.001;

It's the density of the vertical thin lines. The smaller value the higher density.

  float thetaMult = 20.0;


It changes the pattern of the vertical thin lines. To tell the truth, I can't explain it well.



Example images.


  int   lineMax   = 12;
  float ampBase   = height * 0.025;
  float thetaDiv  = PI * 0.01;
  float thetaMult = 20.0;


  int   lineMax   = 6;
  float ampBase   = height * 0.08;
  float thetaDiv  = PI * 0.0001;
  float thetaMult = 50.0;



This 'customNoise' function will create more smooth vertical thin lines.

  return sin(value * TWO_PI);


Lost child department.

This code creates various results with randomness. And it can create thousands of images. You might lose your way in the middle of choosing the best one from a lot of results created by this code.
If you felt you find the best one, you had better wait for 24 hours. When you look at it again and you still feel it nice and interesting, it is the best one.