Calculating the walker path with the Worley noise method


It's a creative coding animation made with the 'Processing'.

 

👉 この記事は日本語でも読めます。

Trying to use the Worley noise in eccentric way.

The ordinal way to use the distance value in the Worley noise is like this. Calculate the hue value, saturation, or brightness and plot the point.

See more about the Worley noise.

I want to use the distance value in the Worley noise method in yet another way. And I tried to use the distance value as the direction of the walker.

I did not write a code from 'the To draw the path like this' point of view but from the 'How about the walker like this?'. And it drew something interesting path, so I made an animation.









 

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. You can make an animation with these files.


/**
 * Walk On By.
 * I tried to use the distance value as the direction of the walker.
 *
 * Processing 3.5.3
 * @author @deconbatch
 * @version 0.1
 * created 0.1 2021.09.12
 */

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

void draw() {
  int   frmMax   = 30 * 6;
  int   cycleMax = 3;
  float baseHue  = random(360.0);

  translate(width * 0.25, height * 0.25);
  for (int cycleCnt = 0; cycleCnt < cycleMax; cycleCnt++) {

    int   nodeMax = 30;
    float nodeGap = 0.05 * min(width, height);
    float zigzag  = random(12.0, 18.0); // walker path roughness
    int   plotMax = floor(20.0 * zigzag);
    baseHue += 90.0;

    // make randomly located nodes
    ArrayList<PVector> nodes = plotNodes(randomAdds(nodeMax, width * 0.5, height * 0.5), nodeGap);

    for (int frmCnt = 0; frmCnt < frmMax; frmCnt++) {
      float easeRatio = InFourthPow(map(frmCnt, 0, frmMax, 0.0, 1.0));
      background(baseHue % 360.0, 30.0, 80.0, 100.0);
      drawWalker(nodes, plotMax, zigzag, easeRatio);

      saveFrame("frames/" + String.format("%02d", cycleCnt) + String.format("%03d", frmCnt + 1) + ".png");
    }
  }
  
  exit();
}


/**
 * randomAdds : make 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.
 */
public ArrayList<PVector> plotNodes(ArrayList<PVector> _adds, float _gap) {

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

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

    float fX = _adds.get(i).x;
    float fY = _adds.get(i).y;

    // collision?
    boolean collision = false;
    for (PVector f : nodes) {
      if (dist(fX, fY, f.x, f.y) < _gap) {
        collision = true;
        break;
      }
    }
    // add new node
    if (!collision) {
      int pixIndex = floor(fY * width + fX);
      nodes.add(new PVector(fX, fY));
    }
  }

  return nodes;

}


/**
 * drawWalker : draw walker with Worley's noise method.
 */
public void drawWalker(ArrayList<PVector> _nodes, int _plotMax, float _zigzag, float _drawRatio) {

  float range   = max(width, height);
  float step    = floor(range * map(_drawRatio, 0.0, 1.0, 0.020, 0.015));
  int   plotMax = floor(map(_drawRatio * _drawRatio, 0.0, 1.0, 0.1, 1.0) * _plotMax);

  PVector initNode = _nodes.get(0);
  float x = initNode.x;
  float y = initNode.y;
  
  ArrayList<PVector> walker = new ArrayList<PVector>();
  walker.add(new PVector(x, y));

  // walk along the nearest node
  int   minIndx = 0;
  for (int plotCnt = 0; plotCnt < plotMax; plotCnt++) {
    float minDist = range;
    for (int i = 0; i < _nodes.size(); i++) {
      float d = dist(x, y, _nodes.get(i).x, _nodes.get(i).y);
      if (minDist > d) {
        minDist = d;
        minIndx = i;
      }
    }
    float r = _zigzag * PI * sin(PI * minDist / range);
    x += step * cos(r);
    y += step * sin(r);
    walker.add(new PVector(x, y));
  }

  // draw walker path
  noFill();
  stroke(0.0, 0.0, 0.0, 100.0);
  strokeWeight(1.0);
  beginShape();
  for (PVector w : walker) {
    ellipse(w.x, w.y, 4.0, 4.0);
    vertex(w.x, w.y);
  }
  endShape();

  // draw nodes
  noFill();
  stroke(0.0, 0.0, 0.0, 100.0);
  strokeWeight(1.0);
  for (PVector n : _nodes) {
    ellipse(n.x, n.y, 14.0, 14.0);
  }
  ellipse(_nodes.get(minIndx).x, _nodes.get(minIndx).y, 4.0, 4.0);

}


/**
 * InFourthPow : easing function.
 */
private float InFourthPow(float _t) {
  return 1.0 - pow(1.0 - _t, 4);
}


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

Next Post Previous Post
No Comment
Add Comment
comment url