Poor man's DLA Moss: Example code with my poor man's DLA algorithm

Colorful branches that grow round like moss.

Grow moss on your screen.

It's a creative coding art-work or generative art example. It draws colorful branches that grew round like moss.

I implemented this 'Processing' example code with my "Poor man's DLA" algorithm.







 

Shot on the rhythm.

The key to getting this result on code is here.

angle += angleMult * sin(anglePhase + angleDiv * shotRatio);

This code shoots the node straight from the outer rim to the center.

Shoots straight from the outer rim to the center.

If it shot nodes at regular intervals, it will put a result like this.

With regular intervals.

Though, if it shot nodes at intervals calculated with the formula above, the result will come out like this. You can get interesting results with the rhythm by another formula.

Shoots nodes at intervals calculated with the formula above.

And I finished this code by drawing lines between nodes.

Colorful branches that grow round like moss.

 

The 'Processing' example code.

Please feel free to use this example code under the terms of the GPL. 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.


/**
 * Poor mans DLA Moss.
 * ref. https://www.deconbatch.com/2019/10/the-poor-mans-dla-diffusion-limited.html
 * 
 * @author @deconbatch
 * @version 0.1
 * Processing 3.5.3
 * created 2021.03.27
 */

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

  int   fileMax   = 3;
  float distStart = random(0.01);

  translate(width * 0.5, height * 0.5);
  for (int fileCnt = 0; fileCnt < fileMax; fileCnt++) {

    float distBase = 0.01 + (distStart + fileCnt * 0.003) % 0.01;
    int   shotMax  = floor(map(distBase, 0.01, 0.02, 3000.0, 1000.0));
    int   runMax   = floor(max(width, height) * 0.5);
    
    background(0.0, 0.0, 90.0, 100.0);
    drawNodes(dlaResult(shotMax, runMax, distBase), runMax * distBase);
    casing();

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

  }
  exit();

}

/**
 * dlaResult : get poor man's dla result.
 */
private ArrayList<Node> dlaResult(int _shotMax, int _runMax, float _distBase) {

  float angleMult  = random(0.05, 1.05);
  float anglePhase = random(TWO_PI);
  float angleWidth = random(HALF_PI, TWO_PI);
  float nHue       = random(360.0);
  float nDist      = _distBase * _runMax;

  ArrayList<Node> nodes = new ArrayList<Node>();
  nodes.add(new Node(0.0, 0.0, nHue)); // seed

  float angle = 0.0;
  for (int shotCnt = 0; shotCnt < _shotMax; shotCnt++) {

    float shotRatio = map(shotCnt, 0, _shotMax, 0.0, 1.0);
    angle += angleMult * sin(anglePhase + angleWidth * shotRatio);

    // start from outer rim
    Node n = new Node(
                      _runMax * cos(angle),
                      _runMax * sin(angle),
                      nHue
                      );
    for (int runCnt = 0; runCnt < _runMax; runCnt++) {
      // run to the center
      n.x -= cos(angle);
      n.y -= sin(angle);

      if (checkCollision(nodes, n, nDist)) {
        nodes.add(n);
        nHue += _distBase * 10.0;
        break;
      }
      
    }

  }

  return nodes;

}

/**
 * checkCollision : check collision between a node and the nodes.
 */
private boolean checkCollision(ArrayList<Node> _nodes, Node _n, float _dist) {

  // run through if there were one very near node
  for (Node n : _nodes) {
    if (dist(n.x, n.y, _n.x, _n.y) < _dist * 0.7) {
      return false;
    }
  }

  // collision
  for (Node n : _nodes) {
    if (dist(n.x, n.y, _n.x, _n.y) < _dist) {
      return true;
    }
  } 

  return false;
}

/**
 * drawNodes : draw the lines between nodes.
 */
private void drawNodes(ArrayList<Node> _nodes, float _dist) {
  float eSat = 60.0;
  float eBri = 40.0;
  noFill();
  for (Node n : _nodes) {
    for (Node p : _nodes) {
      float d = dist(n.x, n.y, p.x, p.y);
      if (d <= _dist) {
        strokeWeight(d * d * d * 0.1 / _dist);
        stroke(p.h % 360.0, eSat, eBri, 100.0);
        line(n.x, n.y, p.x, p.y);
      }
    }
  }
}

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

/**
 * Node : Hold a node information.
 */
private class Node {
  // informations are writable purposely
  public float x, y; // coordinate value of the node.
  public float h;    // hue value of the node.

  Node(float _x, float _y, float _hue) {
    x = _x;
    y = _y;
    h = _hue;
  }
}


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


 

Yet another example image.


Colorful branches that grow round like moss.

Decorated version.

Colorful branches that grow round like moss. Decorated version.

 

Next Post Previous Post
No Comment
Add Comment
comment url