Let's Twist Again.

An animation of flowing ribbons.

An animation of flowing ribbons.

Description.

Creative coding animation made with Processing.

I'm inspired by the idea of @ozachou_g.
I used the recurrence formula in this idea and made an animation of flowing ribbons.
How to Build Discrete Universe


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 example code.

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


// Let's Twist Again.
// @author @deconbatch
// @version 0.1
// Processing 3.2.1
// 2018.10.07

void setup() {

  size(720, 720);
  colorMode(HSB, 360, 100, 100, 100);
  blendMode(SUBTRACT);
  smooth();
  noLoop();
  noStroke();

}

void draw() {

  int   frameCntMax = 15 * 6; // 15fps x 6s
  int   shapeCntMax = 3;
  float easingMin   = 0.0;
  float easingMax   = 1.0;
  float baseHue     = random(360);

  ParameterMaker[] pm = new ParameterMaker[shapeCntMax];
  for (int shapeCnt = 0; shapeCnt < shapeCntMax; ++shapeCnt) {
    pm[shapeCnt] = new ParameterMaker();
  }
  
  translate(width / 2, height / 2);
  rotate(random(PI));

  for (int frameCnt = 1; frameCnt <= frameCntMax; ++frameCnt) {

    background((baseHue + 150) % 360, 2, 95, 100);

    for (int shapeCnt = 0; shapeCnt < shapeCntMax; ++shapeCnt) {

      float pAmin = pm[shapeCnt].getpAmin();
      float pAmax = pm[shapeCnt].getpAmax();
      float pB    = pm[shapeCnt].getpB();
      float pC    = pm[shapeCnt].getpC();
      float dTmin = pm[shapeCnt].getdTmin();
      float dTmax = pm[shapeCnt].getdTmax();
  
      float easing     = map(easeInOutQuadratic(sin(map(frameCnt, 1, frameCntMax, 0.0, PI))), 0.0, 1.0, easingMin, easingMax);
      float pA         = map(easing, easingMin, easingMax, pAmin, pAmax);
      float dT         = map(easing, easingMin, easingMax, dTmin, dTmax);
      int   densityMax = floor(map(easing, easingMin, easingMax, 4000, 2000));
      int   lineCntMax = floor(map(easing, easingMin, easingMax, 50, 100));

      for (int lineCnt = 0; lineCnt < lineCntMax; ++lineCnt) {

        float prevX = 0.0;
        float prevY = 0.0;
        float pTime = map(easing, easingMin, easingMax, 0.0, TWO_PI * 80.0); // moving line

        pA += pA * 0.01 / lineCntMax; // line width

        for (int density = 0; density < densityMax; ++density) {

          // calculate the shape
          float x =  sin(pA * prevX + pB * pTime) * cos(pA * pTime);
          float y =  cos(pA * prevY + pC * pTime) * sin(pA * pTime);

          float densityRatio = map(density % 1000, 0, 999, 0.0, 1.0);
          float size = densityRatio * 4.0;
          fill(
               (baseHue + densityRatio * 30.0 + shapeCnt * 15.0) % 360,
               map(densityRatio, 0.0, 1.0, 60.0, 10.0),
               map(densityRatio, 0.0, 1.0, 10.0, 0.0),
               100
               );
          ellipse(
                  x * width * 0.5,
                  y * height * 0.5,
                  size,
                  size
                  );

          prevX = x;
          prevY = y;
          pTime += dT;

        }

      }
    }

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

  }

  exit();

}

float easeInOutQuadratic(float t) {
  t *= 2.0;
  if (t < 1.0) {
    return pow(t, 2) / 2.0;
  }
  t -= 1.0;
  return -(t * (t - 2) - 1.0) / 2.0;
}

private class ParameterMaker {

  float pAmin;
  float pAmax;
  float pB;
  float pC;
  float dTmin;
  float dTmax;
  
  ParameterMaker() {
    pAmin = random(0.001, 0.01);
    pAmax = pAmin + 0.0001;
    pB    = random(0.001, 0.01);
    pC    = pB * random(0.2, 0.8);
    dTmin = random(0.4, 0.7) * HALF_PI;
    dTmax = dTmin + HALF_PI * 0.1;
  }

  private float getpAmin() {
    return pAmin;
  }

  private float getpAmax() {
    return pAmax;
  }

  private float getpB() {
    return pB;
  }

  private float getpC() {
    return pC;
  }

  private float getdTmin() {
    return dTmin;
  }

  private float getdTmax() {
    return dTmax;
  }

}

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






No comments :

Post a Comment