99.

The colorful cells are drawn with Worley's noise.

Description of this creative coding.

It's a creative coding work made with Processing. It draws the colorful cells are drawn with Worley's noise.
Coding in the Cabana 4: Worley Noise
If you locate cells just randomly, it looks no good.
The colorful cells are drawn with Worley's noise.
So I move cells toward the center of the canvas with moveNodes() function.
public void moveNodes(ArrayList<Node> _nodes, float _limit, float _step)
I tried to make it a cube with drawing shadow in casing() function. It looks delicious, isn't it?😋
public void casing(float _baseHue)

Processing example code.

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.


/**
 * 99.
 * The colorful cells are drawn with Worley's noise.
 * reference. https://www.youtube.com/watch?v=4066MndcyCk&feature=youtu.be
 *
 * Processing 3.5.3
 * @author @deconbatch
 * @version 0.1
 * created 0.1 2020.05.31
 */

void setup() {

  size(980, 980);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  smooth();
  noLoop();

}

void draw() {

  int   frmMax   = 3;
  int   nodeMax  = floor(random(20.0, 40.0));
  float baseHue  = random(360.0);
  float moveStep = random(0.0001, 0.1);

  for (int frmCnt = 0; frmCnt < frmMax; ++frmCnt) {

    baseHue += 60.0;
    float nodeGap    = random(50.0, 150.0);
    float centerCell = random(3.0, 20.0);
    float moveLimit  = nodeGap;

    // make randomly located nodes and move these toward the center of the canvas.
    ArrayList<Node> rnds = plotNodes(randomAdds(nodeMax, width, height), baseHue, nodeGap);
    for (int i = 0; i < 100; i++) {
      moveNodes(rnds, moveLimit, moveStep);
    }

    // draw
    background(baseHue % 360.0, 20.0, 90.0, 100.0);
    drawWorley(rnds, 5.0, 2);
    drawWorley(rnds, centerCell, 1);
    casing(baseHue);

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

  }
  exit();
}


/**
 * moveNodes : move Nodes with (fake) gravity to the center of the canvas.
 *             NOT A PHYSICAL MODEL.
 * @param ArrayList<Node> _nodes : Nodes to move.
 * @param _limit : min distance that detect collision. 
 * @param _step  : moving step
 */
public void moveNodes(ArrayList<Node> _nodes, float _limit, float _step) {

  float range = max(width, height) * _step;

  for (Node r : _nodes) {
    boolean collide = false;
    float centerD = dist(r.x, r.y, width * 0.5, height * 0.5);
    float centerR = atan2(width * 0.5 - r.y, height * 0.5 - r.x);
    for (Node p : _nodes) {
      if (r != p) {
        float nR = atan2(p.x - r.y, p.y - r.x);
        // if there are other nodes in the center direction then stop to move
        if (abs(nR - centerR) < HALF_PI) {
          float nD = dist(r.x, r.y, p.x, p.y);
          if (nD < _limit) {
            collide = true;
            break;
          }
        }
      }
    }
    if (!collide) {
      r.x += cos(centerR) * range * centerD / width;
      r.y += sin(centerR) * range * centerD / height;
    }
  }

}


/**
 * randomAdds : make random PVectors
 * @param  _rndsMax        : Pvectors number.
 * @param  _width, _height : x, y scope of random location.
 * @return ArrayList<PVector> : random PVectors.
 */
public ArrayList<PVector> randomAdds(float _rndsMax, float _width, float _height) {

  ArrayList<PVector> rnds = new ArrayList<PVector>();
  for (int rndsCnt = 0; rndsCnt < _rndsMax; rndsCnt++) {
    rnds.add(new PVector(random(_width), random(_height)));
  }
  return rnds;

}


/**
 * plotNodes : locate Nodes with some distance each other.
 * @param ArrayList<PVector> _adds : location point candidates.
 * @param _baseHue : drawing color.
 * @param _gap     : min distance each nodes.
 * @return ArrayList<Node> : holds nodes.
 */
public ArrayList<Node> plotNodes(ArrayList<PVector> _adds, float _baseHue, float _gap) {

  ArrayList<Node> nodes = new ArrayList<Node>();

  for (int i = 0; i < _adds.size(); i++) {

    float fX = _adds.get(i).x;
    float fY = _adds.get(i).y;
    if (dist(fX, fY, width * 0.5, height * 0.5) > width * 0.5) {
      continue;
    }
    
    // add new node
    boolean inner = false;
    for (Node f : nodes) {
      if (dist(fX, fY, f.x, f.y) < _gap) {
        inner = true;
        break;
      }
    }
    if (!inner) {
      int pixIndex = floor(fY * width + fX);
      nodes.add(new Node(
                         fX,
                         fY,
                         (map(noise(10.0, fX * 0.001, fY * 0.001), 0.0, 1.0, -45.0, 45.0) + _baseHue + 360.0) % 360.0,
                         map(noise(20.0, fX * 0.001, fY * 0.001), 0.0, 1.0, 50.0, 100.0),
                         map(noise(30.0, fX * 0.001, fY * 0.001), 0.0, 1.0, 60.0, 90.0) 
                         ));
    }
  }

  return nodes;

}


/**
 * drawWorley : draw Worley's noise.
 * @param ArrayList<Node> _nodes  : Nodes to draw.
 * @param _cellSize : cell size, bigger value makes little size cell.
 * @param _detail   : plot interval, bigger value makes light color.
 */
public void drawWorley(ArrayList<Node> _nodes, float _cellSize, int _detail) {

  float range = max(width, height);
  
  noStroke();
  for (int iX = 0; iX < width; iX += _detail) {
    for (int iY = 0; iY < height; iY += _detail) {

      int   minIndx = 0;
      float minDist = range;
      for (int i = 0; i < _nodes.size(); i++) {
        float distance = dist(iX, iY, _nodes.get(i).x, _nodes.get(i).y);
        if (minDist > distance) {
          minIndx = i;
          minDist = distance;
        }
      }

      Node n = _nodes.get(minIndx);
      float nAlp = constrain((range - minDist * _cellSize) / range, 0.0, 1.0) * 100.0;
      fill(n.hueVal, n.satVal, n.briVal, nAlp);
      rect(iX, iY, _detail, _detail);

    }
  }
}


/**
 * casing : draw fancy casing
 * @param _baseHue : drawing color.
 */
public void casing(float _baseHue) {

  int   caseW = 50;
  float sHue  = _baseHue % 360.0;

  pushMatrix();
  translate(-5.0 , -5.0);
  strokeWeight(caseW * 2.0);
  stroke(0.0, 0.0, 100.0, 100.0);
  rect(0.0, 0.0, width, height);
  fill(0.0, 0.0, 0.0, 0.0);
  strokeWeight(1.0);
  stroke(sHue, 20.0, 60.0, 100.0);
  rect(caseW, caseW, width - caseW * 2.0, height - caseW * 2.0);
  for (int i = 0; i < 20; i++) {
    stroke(sHue, 60.0, 60.0, 50.0 - i * 2.5);
    line(caseW + 1.0 + i, caseW + 1.0 + i, width - caseW, caseW + 1.0 + i);
    line(caseW + 1.0 + i, caseW + 1.0 + i, caseW + 1.0 + i, height - caseW);
    stroke(sHue, caseW, 60.0, 100.0 - i * 5.0);
    line(caseW + 1.0 + i, height - caseW + 1.0 + i, width - caseW + i, height - caseW + 1.0 + i);
    line(width - caseW + 1.0 + i, caseW + 1.0 + i, width - caseW + 1.0 + i, height - caseW + 1.0 + i);
  }
  popMatrix();

}


/**
 * Node : hold location and color.
 */
public class Node {

  public  float x, y;   // coordinate of node
  private float hueVal; // hue value of node
  private float satVal; // saturation value of node
  private float briVal; // brightness value of node

  Node(float _x, float _y, float _c, float _s, float _b) {
    x = _x;
    y = _y;
    hueVal = _c;
    satVal = _s;
    briVal = _b;
  }

}


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





The colorful cells are drawn with Worley's noise.




No comments :

Post a Comment