An example image of morphing calculation and viscous moving.

Simple morphing calculation and viscous moving.

It's a morphing animation made with creative coding with Processing. The lines in this animation move viscously.

The morphing method used in this code is my ordinary simple morphing calculation. it used in my other works like...

'Viscous moving' is also simple. I implemented it in this code here.


float rT = _ratioM * constrain(_ratioN + _ratioS, 0.0, 1.0);

These shapes are from the code of molding decoration of my other work 'Gates of Babylon'.


Yet another implementation example.

Using 'rect()' not 'curveVertex()' and applied 'blendMode(DIFFERENCE)'.

An example image using 'rect()' not 'curveVertex()'.

And also.

Yet another implementation with ellipse.





Processing code example.

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.
Please feel free to use this example code. To see other works based on my code is my pleasure. And my honor.



/**
 * Dancing in Circles.
 * A morphing animation move viscously.
 *
 * @author @deconbatch
 * @version 0.1
 * @license GPL Version 3 http://www.gnu.org/licenses/
 * Processing 3.5.3
 * 2021.01.11
 */

void setup() {
  size(720, 720);
  colorMode(HSB, 360.0, 100.0, 100.0, 100.0);
  rectMode(CENTER);
  smooth();
  noLoop();
}

void draw() {
  int frmRate  = 12;
  int frmMorph = frmRate * 3;       // morphing duration frames
  int cycles   = 6;                 // animation cycle no
  int frmMax   = frmMorph * cycles; // whole frames

  // shapes
  int   lines  = floor(random(2.0, 6.0));
  int   waves  = floor(random(3.0, 5.0));
  float radius = min(width, height) * 0.25;
  float step   = floor(random(1.0, 3.0)) * 0.05;
  ArrayList<ArrayList<PVector>> shapes = new ArrayList<ArrayList<PVector>>();
  for (int i = 0; i < cycles; i++) {
    shapes.add(getShape(lines, waves, i, radius, step));
  }
  int nodeMax = shapes.get(0).size();

  // morphing tools
  ArrayList<PVector> nodesFrom = new ArrayList<PVector>();
  ArrayList<PVector> nodesTo   = new ArrayList<PVector>();
  int cycleCnt = 0;

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

    // select morphing objects
    if (frmCnt % frmMorph == 0) {
      cycleCnt = frmCnt / frmMorph;
      nodesFrom = shapes.get(cycleCnt);
      nodesTo   = shapes.get((cycleCnt + 1) % cycles);
    }

    // easing calculation
    float frmRatio = map(frmCnt % frmMorph, 0, frmMorph - 1, 0.0, 1.0);
    float morphRatio = easeInOutCubic(frmRatio);
    float easeRatio  = InFourthPow(frmRatio);

    // draw
    noFill();
    stroke(0.0, 0.0, 30.0, 100.0);
    strokeWeight(2.0);
    beginShape();
    for (int i = 0; i < nodeMax + 3; i++) {
      // j is for close the curve.
      // ref. https://www.deconbatch.com/2021/01/processing-curvevertex-memo.html
      int j = i % nodeMax;
      float nodeRatio = map(j, 0, nodeMax, 0.0, 1.0);
      plotVertex(nodesFrom.get(j), nodesTo.get(j), nodeRatio, easeRatio, morphRatio * morphRatio);
    }
    endShape();
    casing();

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

/**
 * getShape : get shape points.
 * @param _lines, _waves, _shape : shape parameters
 * @param _radius : shape size 
 * @param _step   : vertex points spacing
 * @return   : PVector array of shape points
 */
private ArrayList<PVector> getShape(int _lines, int _waves, int _shape, float _radius, float _step) {
  ArrayList<PVector> line = new ArrayList<PVector>();
  
  // curve lines
  float phase = random(PI);
  for (int l = 0; l < _lines; l++) {
    for (float theta = 0.0; theta < TWO_PI; theta += PI * _step) {
      float t = (theta + phase) % TWO_PI;
      float r = _radius * (1.0 + 0.4 * sin(sin(t * (_waves + _shape) + l * TWO_PI / _lines) * TWO_PI));
      float x = r * cos(t);
      float y = r * sin(t);
      line.add(new PVector(x, y));
    }
  }
  return(line);
}

/**
 * plotVertex : plot the vertex with morphing calculation.
 * @param  _from, _to : nodes to draw, morphing from and to
 * @param  _ratioN    : vartex number ratio
 * @param  _ratioM    : morphing ratio
 * @param  _ratioS    : shift ratio for viscous moving
 */
void plotVertex(PVector _from, PVector _to, float _ratioN, float _ratioM, float _ratioS) {
  float rT = _ratioM * constrain(_ratioN + _ratioS, 0.0, 1.0);
  float rF = 1.0 - rT;
  float nX = (_from.x * rF + _to.x * rT);
  float nY = (_from.y * rF + _to.y * rT);
  curveVertex(nX, nY);
}

/**
 * easeInOutCubic easing function.
 * @param  t     0.0 - 1.0 : linear value.
 * @return float 0.0 - 1.0 : eased value.
 */
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;
}
  
/**
 * InFourthPow : easing function.
 * @param  _t    0.0 - 1.0 : linear value.
 * @return       0.0 - 1.0 : eased value.
 */
private float InFourthPow(float _t) {
  return 1.0 - pow(1.0 - _t, 4);
}

/**
 * casing : draw fancy casing
 */
private void casing() {
  fill(0.0, 0.0, 0.0, 0.0);
  strokeWeight(54.0);
  stroke(0.0, 0.0, 0.0, 100.0);
  rect(0.0, 0.0, width, height);
  strokeWeight(50.0);
  stroke(0.0, 0.0, 100.0, 100.0);
  rect(0.0, 0.0, width, height);
  noStroke();
  noFill();
  noStroke();
}

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

An example image of morphing calculation and viscous moving.

An example image of morphing calculation and viscous moving.