Product of My Own Design : The strange attractor creates interesting shapes for me.

Processing code examples made this image.

I don't abandon the converging parameters!

It's a creative coding animation made with Processing.

Yet another application with De Jong attractors.
Strange attractors often converge like this.



So I wanted to make these boring converging parameters to an interesting one. And it worked!

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.

Processing code example.

Please feel free to use this example code, if you like it.
To see other works based on my code is my pleasure. And my honor.


// Product of My Own Design.
// @deconbatch
// Processing 3.2.1
// 2018.06.24
// 10 fps x 5s animation

class deJongShape {

  float hueApply, satApply, briApply;
  float pA, pB, pC, pD;
  float frstX, scndX, thrdX;
  float frstY, scndY, thrdY;
  float multX, multY;
  
  deJongShape(float hueApply, float satApply, float briApply, float multX, float multY) {
    this.hueApply = hueApply;
    this.satApply = satApply;
    this.briApply = briApply;
    this.multX    = multX;
    this.multY    = multY;

    float seed  = 0.01;
    float scope = 100.0;
    pA = seed * floor(random(-scope, scope));
    pB = seed * floor(random(-scope, scope));
    pC = seed * floor(random(-scope, scope));
    pD = seed * floor(random(-scope, scope));

    resetShape();
   
  }

  void resetShape() {

    thrdX = sin(pA) - cos(pB);
    thrdY = sin(pC) - cos(pD);
    scndX = sin(pA * thrdY) - cos(pB * thrdX);
    scndY = sin(pC * thrdX) - cos(pD * thrdY);
    frstX = sin(pA * scndY) - cos(pB * scndX);
    frstY = sin(pC * scndX) - cos(pD * scndY);

  }

  void drawShape(float hueAdd) {

    frstX = sin(pA * scndY) - cos(pB * scndX);
    frstY = sin(pC * scndX) - cos(pD * scndY);

    stroke((hueApply + hueAdd) % 360.0, satApply, briApply, 100.0);
    fill(0.0, 0.0, 0.0, 0.0);
    beginShape(LINES);
    vertex(frstX * multX - 80.0, frstY * multY - 80.0);
    vertex(scndX * multX - 80.0, scndY * multY - 80.0);
    vertex(thrdX * multX - 80.0, thrdY * multY - 80.0);
    vertex(thrdY * multX - 80.0, thrdX * multY - 80.0);
    vertex(scndY * multX - 80.0, scndX * multY - 80.0);
    vertex(frstY * multX - 80.0, frstX * multY - 80.0);
    endShape();

    stroke(0.0, 0.0, 0.0, 0.0);
    fill((hueApply - hueAdd) % 360.0, satApply, briApply, 5.0);
    beginShape();
    vertex(frstX * multX - 80.0, frstY * multY - 80.0);
    vertex(scndX * multX - 80.0, scndY * multY - 80.0);
    vertex(scndY * multX - 80.0, scndX * multY - 80.0);
    vertex(frstY * multX - 80.0, frstX * multY - 80.0);
    endShape();

    thrdX = scndX;
    thrdY = scndY;
    scndX = frstX;
    scndY = frstY;

  }

}

void setup() {

  size(720, 720);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  smooth();
  noLoop();
  strokeWeight(0.5);

}

void draw() {

  // put them just little upper
  translate(width / 2.0, height / 2.0 - 10.0);

  int   fps         = 10;
  int   frameCntMax = fps * 5;
  int   shapeCntMax = 30;
  int   drawCntMax  = 60;
  int[] drawSkip    = new int[shapeCntMax];
  float hueBase     = random(360);

  // create shape objects
  deJongShape[] djShape = new deJongShape[shapeCntMax];
  for(int shapeCnt = 0; shapeCnt < shapeCntMax; ++shapeCnt) {
    drawSkip[shapeCnt] = floor(random(5.0, 10.0));
    djShape[shapeCnt]  = new deJongShape(
                                         (hueBase + (shapeCnt % 3) * 30.0) % 360.0,
                                         map(shapeCnt % 6, 0, 5, 60.0, 80.0),
                                         map(shapeCnt % 5, 0, 4, 10.0, 50.0),
                                         width  / 6.5,
                                         height / 6.5
                                         );
  }

  // draw decomposed shape and save it for each frame
  for (int frameCnt = 0; frameCnt < frameCntMax; ++frameCnt) {
    
    background(0.0, 0.0, 90.0, 100.0);
  
    pushMatrix();
    for(int shapeCnt = 0; shapeCnt < shapeCntMax; ++shapeCnt) {

      // draw 6 shape on circle
      rotate(PI / 3.0);

      djShape[shapeCnt].resetShape();
      pushMatrix();
      for (int drawCnt = 0; drawCnt < drawCntMax; ++drawCnt) {

        // decompose
        rotate(PI * 0.005 * easeInOutCubic(map(frameCnt, 0, (frameCntMax - 1), 1.0, 0.0)));

        // draw shape
        if (drawCnt % drawSkip[shapeCnt] == 0) {
          djShape[shapeCnt].drawShape(map(drawCnt, 0, drawCntMax, 0.0, 30.0));
        }
      }
      popMatrix();

    }
    popMatrix();
    saveFrame("frames/pmod1" + String.format("%03d", frameCnt) + ".png");

  }

  // draw composed shape and save it for last part of animation
  for (int frameCnt = 0; frameCnt < fps * 1.5; ++frameCnt) {
    saveFrame("frames/pmod9" + String.format("%03d", frameCnt) + ".png");
  }

  // save composed shape for twitter thumnail
  saveFrame("frames/pmod0000.png");
  exit();

}

// easing function
float easeInOutCubic(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) 2018- 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 example images.

Processing code examples made this image.
Processing code examples made this image.


No comments :

Post a Comment