One of the essential matters is between organic and mechanical.

The inorganic shell contains organic matter.

Creative coding artwork of generative shells.

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

I reused Desert Rose to make something between organic and mechanic image. This code draws so many lines with 'curveVertex()'. And the calculation to determine the vertexes is the main destination of this code. 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.







 

The 'Processing' code example.

Please feel free to use this 'Processing' example code under the terms of the GPL. To see other works based on my programed 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(980, 980);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  rectMode(CENTER);
  smooth();
  noLoop();
}

void draw() {

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

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

    // shape parameters
    float pCorner = random(1.0);
    float pRotate = random(1.0);
      
    hueBase += 90.0;
    blendMode(BLEND);
    background((hueBase + 180.0) % 360.0, 5.0, 90.0, 100.0);

    blendMode(DIFFERENCE);
    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 + shellCnt * 60.0; //shellRatio * 45.0;
    
        pushMatrix();
        rotate(HALF_PI * pRotate + TWO_PI * shellRatio / shellCorners);
        drawShell(
                  shellCorners,
                  shellJoints,
                  shellSize,
                  shellSoft,
                  shellHole,
                  shellHue,
                  iterRatio
                  );
        popMatrix();
    
      }
    }

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

  }
  exit();
}

/**
 * casing : draw fancy casing
 */
private void casing() {
  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<Node> {
  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) 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