title

deconbatch's Land of 1000 Creative Codings. example codes of Processing / p5.js, how-to articles, generative art images, and much more!

Snap and Roll.

Creative coding examples.
Creative coding examples.


Description of this creative coding animation.

Creative coding animation work made with Processing.

When I tried to draw a flower with the formula abs(sin(3 * theta)).

Flower with sin().

I started to want to draw lines with each dot.
And I wonder, I had to make Node class even if I draw lines in a sequence?

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

Processing code example.

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



/**
 * Snap and Roll.
 * Node garden without nodes.
 * 
 * @author @deconbatch
 * @version 0.1
 * Processing 3.2.1
 * 2019.03.12
 */

/* ---------------------------------------------------------------------- */

void setup() {

  size(720, 720);
  colorMode(HSB, 360, 100, 100, 100);
  rectMode(CENTER);
  smooth();
  noLoop();

}

void draw() {

  int   frameCntMax = 24 * 6;
  int   nodeCntMax  = floor(random(9.0, 13)) * 2;
  int   cornerCnt   = floor(random(2.0, 9.0));
  float limitMin    = 50.0;
  float limitMax    = 200.0;
  float baseHue     = random(360.0);

  StepEasing se = new StepEasing(3);
  EasingCalc ec = new InOutCubic();
  Node [] nodes = new Node[nodeCntMax];
  for (int i = 0; i < nodeCntMax; ++i) {
    nodes[i] = new Node(baseHue + (i % 3) * 30.0);
  }

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

    background(0, 0, 90, 100);
    float easeRatio = se.calculate(ec, map(frameCnt, 0, frameCntMax, 0.0, 1.0));

    // set nodes
    for (int nodeCnt = 0; nodeCnt < nodeCntMax; ++nodeCnt) {
      float radian = TWO_PI * map(nodeCnt, 0, nodeCntMax, 0.0, 1.0);
      float radius = abs(sin(radian * cornerCnt + PI * easeRatio)) * width * 0.4;
      float eX = radius * cos(radian);
      float eY = radius * sin(radian);
      nodes[nodeCnt].setNode(eX, eY);
    }

    // draw lines in a sequence
    for (int i = 0; i < nodeCntMax - 1; i++) {
      for (int j = i + 1; j < nodeCntMax; j++) {
        nodes[i].drawLine(nodes[j], limitMin, limitMax);
      }
    }

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

  }
  exit();
}


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

/**
 * Keeping node information. Drawint polka dot and line between nodes.
 * @param  baseHue 0.0 - 360.0 : draw points color.
 */
private class Node {

  private float nX, nY;
  private float nHue;

  Node(float baseHue) {
    nX    = 0.0;
    nY    = 0.0;
    nHue  = baseHue % 360.0;
  }

  public void setNode(float pX, float pY) {
    nX = pX;
    nY = pY;
  }

  public float getNodeX() {
    return nX;
  }

  public float getNodeY() {
    return nY;
  }

  public void drawLine(Node toNode, float limitMin, float limitMax) {
  
    float distance = dist(nX, nY, toNode.getNodeX(), toNode.getNodeY());

    if (distance < limitMax && distance > limitMin) {
      strokeWeight(sin(PI * map(distance, limitMin, limitMax, 0.0, 1.0)) * 2.0);
      stroke(nHue, 40.0, 60.0, 100.0);
      line(nX, nY, toNode.getNodeX(), toNode.getNodeY());
    }
  
  }
}

/**
 * StepEasing : calculate easing value with step landing. It just has one easing function yet.
 * @param  _landingCount : 1 - any int value : landing number.
 */
private class StepEasing {

  private float landingPoint;
  private float easePrev;
  private float easeRatio;
  
  StepEasing(int _landingCount) {
    landingPoint = 1.0 / (_landingCount + 1);
    reset();
  }

  StepEasing() {
    landingPoint = 1.0;
    reset();
  }

  private void reset() {
    easePrev  = 0.0;
    easeRatio = 0.0;
  }
  
  /**
   * calculate : calculate easing value with step landing.
   * @param  _t    0.0 - 1.0 : linear value.
   * @return float 0.0 - 1.0 : eased value with step landing.
   */
  public float calculate(EasingCalc _calc, float _t) {
    float easeCurr = _calc.calculate(map(_t % landingPoint, 0.0, landingPoint, 0.0, 1.0));
    easeRatio += constrain((easeCurr - easePrev) * landingPoint, 0.0, 1.0);
    easePrev = easeCurr;

    return easeRatio;
  }

}

/**
 * easeInOutCubic easing function.
 * @param  _t    : 0.0 - 1.0 : linear value.
 * @return float : 0.0 - 1.0 : eased value.
 */
interface EasingCalc {
  float calculate(float _t);
}

private class InOutCubic implements EasingCalc {
  public float calculate(float _t) {
    _t *= 2.0;
    if (_t < 1.0) {
      return pow(_t, 3) / 2.0;
    }
    _t -= 2.0;
    return (pow(_t, 3) + 2.0) / 2.0;
  }
}

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




Post a Comment

0 Comments