Sitting On Top Of The World.

Generative art example image with DLA similar method.


No noise() and no random()!

It's a creative coding example with my poor man's DLA.

I wrote an article 'The poor man's DLA (Diffusion Limited Aggregation).' that explain how to make a image similar DLA without Brownian motion nor random moving.

I played with this method and found some interesting results.
I picked one of them and made an animation.
And I tried to unuse random() and noise() in this code.

This code does not display any images on the screen but generates image files in frames directory.
You can make an animation with these images.

Processing code example (Java).

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


/**
 * Sitting On Top Of The World.
 * draw Yggdrasill with my poor man's DLA
 * 
 * @author @deconbatch
 * @version 0.1
 * Processing 3.2.1
 * created 2019.10.14
 * 
 */

/**
 * Point : Hold a point information.
 */
private class Point {
  public float x, y, h; // informations are writable purposely

  /**
   * @param  _x   : x-coordinate value of the point.
   * @param  _y   : y-coordinate value of the point.
   * @param  _hue : hue value of the point.
   */
  Point(float _x, float _y, float _hue) {
    x = _x;
    y = _y;
    h = _hue % 360.0;
  }
}

void setup(){
  size(720, 720);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  rectMode(CENTER);
  smooth();
  noLoop();
}
 
void draw(){

  int   plotMax = 5500;
  int   frmMax  = 24 * 10;
  int   walkMax = width * 2;
  float pSize   = 5.0;
  float pHue    = System.currentTimeMillis() % 360.0;
  float initDiv = 0.08;

  ArrayList<Point> cluster = new ArrayList<Point>();
  for (float i = -0.5 ; i < 0.5; i += initDiv) {
    cluster.add(new Point(
                          i * width,
                          height * 0.5,
                          pHue));
  }

  translate(width * 0.5, height * 0.5);

  float entryR = -0.1;  // entryRadius
  for (int plotCnt = 0; plotCnt < plotMax; plotCnt++) {

    float plotRatio = map(plotCnt, 0, plotMax, 0.4, 1.0);

    entryR += entryR; // * plotRatio;
    entryR = entryR % PI;
    Point p = new Point(
                        width * cos(entryR),
                        height * sin(entryR),
                        pHue);
    for (int walkCnt = 0; walkCnt < walkMax; walkCnt++) {

      // walk to the center, make center point lower
      p.x -= cos(entryR - cos(entryR) * 0.05);
      p.y -= sin(entryR - cos(entryR) * 0.05);
      
      if (checkCollision(cluster, p, pSize)) {
        cluster.add(p);
        pHue += 0.04;
        break;
      }
      
    }

    // speed up
    if (plotCnt % floor(plotCnt * 0.01 + plotMax / frmMax) == 0) {
      background(0.0, 0.0, 90.0, 100.0);
      drawCluster(cluster, pSize);
      casing();
      saveFrame("frames/0." + String.format("%05d", plotCnt) + ".png");
    }    

  }

  // draw the final frame
  background(0.0, 0.0, 90.0, 100.0);
  drawCluster(cluster, pSize);
  casing();

  for (int i = 0; i < 48; i++) {
    saveFrame("frames/1." + String.format("%05d", i) + ".png");
  }

  // for Twitter thumnail
  saveFrame("frames/0.00000.png");
  exit();

}

/**
 * drawCluster : draw the points cluster 
 * @param  _cluster : ArrayList of the Point class.
 * @param  _size    : draw point size.
 */
private void drawCluster(ArrayList<Point> _cluster, float _size) {
  float eSat = 80.0;
  float eBri = 50.0;
  float eSiz = _size * 0.75;
  noStroke();
  noFill();
  for (Point p : _cluster) {
    eSat -= 0.004;
    eBri += 0.002;
    //    fill(p.h % 360.0, eSat, eBri, 100.0);
    //    ellipse(p.x, p.y, eSiz, eSiz);
    stroke(p.h % 360.0, eSat, eBri, 100.0);
    for (Point c : _cluster) {
      float distance = dist(p.x, p.y, c.x, c.y);
      if (distance > _size * 0.5 && distance < _size * 1.5) {
        strokeWeight(4.0 * _size / (distance * 2.0));
        line(p.x, p.y, c.x, c.y);
        //    fill(p.h, eSat, eBri, 100.0);
      }
    }
  }
}

/**
 * checkCollision : check collision between a point and the cluster.
 * @return boolean  : true = detect collision.
 * @param  _cluster : ArrayList of the Point class.
 * @param  _p       : a point
 * @param  _size    : size of the point.
 */
private boolean checkCollision(ArrayList<Point> _cluster, Point _p, float _size) {
  for (Point p : _cluster) {
    if (dist(p.x, p.y, _p.x, _p.y) < _size * 1.0) {
      return false;
    }
  }

  for (Point p : _cluster) {
    if (dist(p.x, p.y, _p.x, _p.y) < _size * 1.2) {
      return true;
    }
  }  
  return false;
}

/**
 * casing : draw fancy casing
 */
private void casing() {
  blendMode(BLEND);
  fill(0.0, 0.0, 0.0, 0.0);
  strokeWeight(34.0);
  stroke(0.0, 0.0, 0.0, 100.0);
  rect(0.0, 0.0, width, height);
  strokeWeight(30.0);
  stroke(0.0, 0.0, 100.0, 100.0);
  rect(0.0, 0.0, width, height);
  noStroke();
  noFill();
}


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




Generative art example image with DLA similar method.
Generative art example image with DLA similar method.


No comments :

Post a Comment