Weird tentacles code art with the De Jong attractor

A weird tentacles and bare bones.

 

Description of this creative coding artwork.

It's a creative coding artwork made with the 'Processing' programming language. It draws weird tentacles and bare-bones artwork.

The key to drawing this image is this recurrence formula. It's similar to the De Jong attractor.

  currX += pDiv * (sin(djA * prevY) - cos(djB * prevX));
  currY += pDiv * (sin(djC * prevX) - cos(djD * prevY));

I calculate these coordinates in 'calcTentacles()' function, and I draw tentacles shape in this function. I think, it is not good to contain plural things (calculation and drawing in this case) in one function. But it is so convenient, and I can't help use it.

This code art does not display any images on the screen but generates image files in frames directory.







 

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.


/**
 * Flesh and Bone.
 * draws weird tentacles and bare bones.
 * 
 * Processing 3.5.3
 * @author @deconbatch
 * @version 0.1
 * created 0.1 2020.03.15
 */

void setup() {

  size(980, 980, P2D);
  colorMode(HSB, 360, 100, 100, 100);
  rectMode(CENTER);
  smooth(8);
  noLoop();

}

void draw() {

  int   frmMax     = 3; // draws three images
  float baseHue    = random(360);
  float baseRadius = min(width, height) / 6.0;
  
  translate(width * 0.5, height * 0.5);
  for (int frmCnt = 0; frmCnt < frmMax; frmCnt++) {

    float rndRotate = random(PI);
    noiseSeed(floor(baseHue + rndRotate));

    // draw background
    blendMode(BLEND);
    baseHue += 60.0;
    drawCanvas(baseHue);

    pushMatrix();
    rotate(rndRotate);
    // calculate tentacles and draw
    ArrayList<PVector> pvs = calcTentacles(baseHue, baseRadius);
    // draw bones
    baseHue += 60.0;
    drawBones(baseHue, baseRadius, pvs);
    popMatrix();  

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

  }
  exit();
}

/**
 * calcTentacles : calculate tentacle shapes and draw with ellipse.
 *                 it may not good to do a calculation and drawing in one function. but it convenient.
 * @param  _baseHue    : shape's base color.
 * @param  _baseRadius : shape's whole size.
 * @return calculated main tentacle's coodinates as ArrayList<PVector>.
 */
ArrayList calcTentacles(float _baseHue, float _baseRadius) {

  ArrayList<PVector> pvs = new ArrayList<PVector>();
  float pDiv = random(0.018, 0.05); // it determines the shape. increment value in recurrence formula
  int   tMax = 200;  // how many tentacles
  int   lMax = 50;   // tentacle's length

  for (int tCnt = 0; tCnt < tMax; tCnt++) {

    // calculation parameters
    float djA = random(-TWO_PI, TWO_PI);
    float djB = random(-TWO_PI, TWO_PI);
    float djC = random(-TWO_PI, TWO_PI);
    float djD = random(-TWO_PI, TWO_PI);

    // grow tentacles in all directions
    float dR = map(tCnt, 0, tMax, 0.0, TWO_PI);

    float prevX   = 0.0;
    float prevY   = 0.0;
    float currX   = 0.0;
    float currY   = 0.0;
    float bX      = 0.0;
    float bY      = 0.0;
    float tLength = 0.0;

    ArrayList<PVector> tempArray = new ArrayList<PVector>();
    
    noStroke();
    for (int lCnt = 0; lCnt < lMax; lCnt++) {

      // it's not the De Jong attractor
      currX += pDiv * (sin(djA * prevY) - cos(djB * prevX));
      currY += pDiv * (sin(djC * prevX) - cos(djD * prevY));

      // rotational transfer
      float tX = currX * cos(dR) - currY * sin(dR);
      float tY = currY * cos(dR) + currX * sin(dR);
      tempArray.add(new PVector(tX, tY));

      prevX = currX;
      prevY = currY;

      // draw tentacle with ellipse
      float pSiz = dist(bX, bY, tX, tY) * _baseRadius * 2.0;
      float pHue = _baseHue + dist(tX, tY, 0.0, 0.0) * noise(tX * 0.1, tY * 0.1) * 90.0;
      fill(
           pHue % 360.0,
           map(noise(10.0, tX, tY), 0.0, 1.0, 0.0, 90.0),
           map(noise(20.0, tX, tY), 0.0, 1.0, 20.0, 90.0),
           100.0
           );
      ellipse(
              _baseRadius * tX,
              _baseRadius * tY,
              pSiz,
              pSiz
              );

      tLength += dist(bX, bY, tX, tY);
      bX = tX;
      bY = tY;
    
    }

    // long tentacles will pass this test
    if (tLength > pDiv * 50.0) {
      pvs.addAll(tempArray);
    }
    
  }
  return pvs;
}

/**
 * drawBones : draws bones with line.
 * @param  _baseHue    : drawing base color.
 * @param  _baseRadius : shape's whole size.
 * @param  _pvs        : calculated coodinates.
 */
void drawBones(float _baseHue, float _baseRadius, ArrayList<PVector> _pvs) {

  noFill();
  for (PVector ppv : _pvs) {
    float pDist = dist(ppv.x, ppv.y, 0.0, 0.0);
    for (PVector fpv : _pvs) {
      float distance = dist(ppv.x, ppv.y, fpv.x, fpv.y);
      if (distance > 0.1 && distance < 0.2) {
        float lHue = _baseHue + pDist * noise(ppv.x * 0.1, ppv.y * 0.1) * 90.0;
        float lWgt = constrain(map(pDist, 0.0, 3.0, 5.0, 3.0), 3.0, 5.0);

        blendMode(MULTIPLY);
        strokeWeight(lWgt);
        stroke(
               lHue % 360.0,
               map(noise(10.0, fpv.x, fpv.y), 0.0, 1.0, 0.0, 90.0),
               map(noise(20.0, ppv.x, ppv.y), 0.0, 1.0, 80.0, 90.0),
               100.0
               );
        line(
             _baseRadius * ppv.x,
             _baseRadius * ppv.y,
             _baseRadius * fpv.x,
             _baseRadius * fpv.y

             );

        blendMode(ADD);
        strokeWeight(lWgt * 0.25);
        line(
             _baseRadius * ppv.x,
             _baseRadius * ppv.y,
             _baseRadius * fpv.x,
             _baseRadius * fpv.y

             );
      }
    }
  }
}

/**
 * casing : draw fancy casing
 */
private void casing() {
  
  fill(0.0, 0.0, 0.0, 0.0);
  strokeWeight(40.0);
  stroke(0.0, 0.0, 0.0, 100.0);
  rect(0.0, 0.0, width, height);
  strokeWeight(30.0);
  stroke(0.0, 0.0, 90.0, 100.0);
  rect(0.0, 0.0, width, height);
    
}

/**
 * drawCanvas : draw rough textured background
 * @param  _baseHue    : drawing base color.
 */
void drawCanvas(float _baseHue) {

  background((_baseHue + 30.0) % 360.0, 0.0, 90.0, 100.0);
  for (int x = 1; x < width * 0.5; x += 2) {
    for (int y = 1; y < height * 0.5; y += 2) {
	
      float pSize = random(0.5, 2.0);
      float pDiv  = random(-2.0, 2.0);
      float pSat = 0.0;
      if ((x + y) % 3 == 0) {
        pSat = 40.0;
      }
      strokeWeight(pSize);
      stroke(_baseHue, pSat, 50.0, 20.0);
      point(x + pDiv, y + pDiv);
      point(-x + pDiv, y + pDiv);
      point(x + pDiv, -y + pDiv);
      point(-x + pDiv, -y + pDiv);
	
    }
	}
}

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




 

Yet another example artwork.


A weird tentacles and bare bones.
A weird tentacles and bare bones.

 

Next Post Previous Post
No Comment
Add Comment
comment url