Hide in Your Shell : Creative coding artwork between organic and mechanic.

The inorganic shell contains organic matter.

A creative coding art work made with Processing.

I reused Desert Rose to make something between organic and mechanic image.
And I've lost my way during tuning the parameters. XP

This code does not display any images on the screen but just generates image files.

Processing code example.

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


/**
 * Hide in Your Shell.
 * 
 * Something between organic and mechanic.
 * 
 * @author @deconbatch
 * @version 0.1
 * Processing 3.2.1
 * 2019.04.14
 */

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

void draw() {

  int   shellCntMax = 3;
  float hueBase = random(360.0);

  // shape parameters
  float pCorner = random(1.0);
  float pRotate = random(1.0);

  translate(width * 0.5, height * 0.5);
  background((hueBase + 270.0) % 360.0, 40.0, 15.0, 100.0);
  blendMode(ADD);

  for (int shellCnt = 0; shellCnt < shellCntMax; ++shellCnt) {

    // shape parameters
    float pJoint  = random(1.0);
    float pSoft   = random(1.0);

    float shellRatio = map(shellCnt, 0, shellCntMax - 1, 0.0, 1.0);
    curveTightness(map(shellRatio, 0.0, 1.0, -5.0, 1.0));  
    int iterMax = 500 + floor(shellRatio * 1500);

    for (int iter = 0; iter < iterMax; ++iter) {
    
      float iterRatio = map(iter, 0, iterMax, 0.0, 1.0);

      int   shellCorners = floor(map(pCorner, 0.0, 1.0, 3.0, 9.0));
      int   shellJoints  = floor(map(shellRatio, 0.0, 1.0, 5.0, 2.0 + pJoint * 2.0));
      float shellSize    = width * map(shellRatio, 0.0, 1.0, 0.2, 0.55) * map(pJoint, 0.0, 1.0, 1.0, 0.9);
      float shellSoft    = map(shellRatio, 0.0, 1.0, 0.2, 0.1 + pSoft * 0.1);
      float shellHole    = shellRatio * 0.6;
      float shellHue     = hueBase + shellRatio * 45.0;
    
      pushMatrix();
      rotate(HALF_PI * pRotate + TWO_PI * shellRatio / shellCorners);
      drawShell(
                shellCorners,
                shellJoints,
                shellSize,
                shellSoft,
                shellHole,
                shellHue,
                iterRatio
                );
      popMatrix();
    
    }
  }

  casing();
  saveFrame("frames/####.png");

  if (frameCount >= 3) {
    exit();
  }

}

/**
 * casing : draw fancy casing
 */
private void casing() {
  rectMode(CENTER);
  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();
}

/**
 * drawShell : draw shell image.
 * @param  _corners   : corner count of shell.
 * @param  _joints    : joint count of shell.
 * @param  _shellSize  : size of shell.
 * @param  _softness  : 0.1 - 0.2 : shape softness.
 * @param  _hole    : 0.0 - 1.0 :size of center hole.
 * @param  _hueBase   : hue value of shell.
 * @param  _drawRatio : 0.0 - 1.0 : drawing ratio of the total.
 * too many parameters!
 */
private void drawShell(int _corners, int _joints, float _shellSize, float _softness, float _hole, float _hueBase, float _drawRatio) {

  // make node list
  NodeList[] jointNodes = new NodeList[_joints];
  for (int jointCnt = 0; jointCnt < _joints; ++jointCnt) {

    float jointRatio = map(jointCnt, 0, _joints, 0.0, 1.0);
    jointNodes[jointCnt] = new NodeList();

    for (int cornerCnt = 0; cornerCnt < _corners; ++cornerCnt) {

      float cornerRatio = map(cornerCnt, 0, _corners, 0.0, 1.0);
      float shapeFactor = sin(TWO_PI * (cornerRatio + _drawRatio));

      float direction = noise(_hueBase * _joints + _corners) < 0.5 ? 1.0 : -1.0; // random rotate direction
      float nRadius   = _shellSize * (_hole + (1.0 - _hole) * jointRatio);
      float nRadian   = direction * TWO_PI * (cornerRatio + map(shapeFactor, -1.0, 1.0, -_softness, _softness));

      float nX = nRadius * cos(nRadian);
      float nY = nRadius * sin(nRadian);
    
      Node joint = new Node(new PVector(nX, nY));
      jointNodes[jointCnt].add(joint);

    }
  }

  // draw lines with node lists
  for (int jointCnt = 0; jointCnt < _joints - 1; ++jointCnt) {
    jointNodes[jointCnt].drawLines(
                                   jointNodes[jointCnt + 1],
                                   _hueBase,
                                   map(jointCnt, 0, _joints - 1, 0.0, 1.0),
                                   1.0 / _corners
                                   );
  }
}

/**
 * Keep node information.
 * @param  _position : node position
 */
class Node {
  PVector position;
  Node(PVector _position) {
    position = new PVector();
    position.set(_position);
  }
}

/**
 * Keep nodes in one joint.
 * number of nodes = number of corners.
 * draw lines from some joint to other joint.
 * @param  _otherNodes : draw lines to this nodes.
 * @param  _hueBase    : hue value of lines.
 * @param  _jointRatio : 0.0 - 1.0 : joint ratio of the total. from center to outer.
 * @param  _density    : 0.0 - 1.0 : to control stroke weight. bigger = thick.
 */
class NodeList extends ArrayList {
  void drawLines(NodeList _otherNodes, float _hueBase, float _jointRatio, float _density) {

    noFill();
    strokeWeight(0.1 + _jointRatio * map(_density, 0.0, 1.0, 0.0, 1.0));
    stroke(
           (_hueBase + 360.0 + map(_jointRatio, 0.0, 1.0, -45.0, 45.0)) % 360.0,
           50.0 - 20.0 * _jointRatio,
           3.0 - 2.0 * _jointRatio,
           100.0
           );

    beginShape();
    // draw twice for nice curve
    for (int j = 0; j < 2; ++j) {
      for (int i = 0; i < this.size(); ++i) {
        Node node = this.get(i);
        Node other = _otherNodes.get(i);
        curveVertex(
                    node.position.x,
                    node.position.y
                    );
        curveVertex(
                    other.position.x + random(-1.0, 1.0),
                    other.position.y + random(-1.0, 1.0)
                    ); // using random to make stroke inconspicuously
      }
    }
    endShape(CLOSE);
    
  }
}

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



Yet another image examples.

An example image of something between organic and mechanic.
Made with Processing code examples in this article.
Made with Processing code examples in this article.


No comments :

Post a Comment