Finding the 'Cat formula' during my pursuit of creative coding truth

A cat shape with my creative coding cat formula.


 

How I discovered the 'Cat formula' in this creative coding.

It's a creative coding animation work made with the 'Processing'.

I found a 'Cat formula' when I was palying with the idea of @ozachou_g.

How to Build Discrete Universe
https://how-to-build-du-e.tumblr.com/

A cat formula.

 X1 = (pow(sin(X0), 3) + cos(Y0)) * sin(T0);
 Y1 = (cos(X0) + pow(sin(Y0), 3)) * cos(T0);
 T1 = T0 + timeDiv

And I made an animation with this morphing (lerping) method.

 A, B  : morph from A shape to B shape
 morph : from 1.0 to 0.0
 shape = A * morph + B * (1 - morph)







 

The 'Processing' code example.

Please feel free to use this code under the terms of the GPL.
To see other works based on my code is my pleasure. And my honor.

// Morph the Cat.
// @author @deconbatch
// @version 0.1
// Processing 3.2.1
// 2018.11.11

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   recurseCntMax = 2500;
  float divRotate     = random(0.01, 0.02) * rndSign();
  float baseHue       = random(360);

  // cat shape
  int   phaseCntMax  = 500;  // must for cat!  > 500
  float phaseDiv     = 1.0 / phaseCntMax;
  float phaseDivInit = PI * 0.75 - phaseDiv * phaseCntMax;

  // some shape
  float paramSomX = random(0.1, 1.0);
  float paramSomY = random(0.1, 1.0) * rndSign();
  float paramSomT = random(0.5, 1.5);

  translate(width / 2, height / 2);
  rotate(PI * (0.25 - 0.49 * frameCntMax * divRotate));  // for upright cat
 
  for (int frameCnt = 1; frameCnt <= frameCntMax; ++frameCnt) {

    float easing  = easeInOutCubic(map(frameCnt, 0, frameCntMax, 1.0, 0.0));  // animate factor
    float timeDiv = phaseDivInit;

    background((baseHue + 150) % 360, 5, 90, 100);
    rotate(PI * divRotate * easing);
    
    for (int phaseCnt = 0; phaseCnt < phaseCntMax; ++phaseCnt) {

      float phaseRate = map(phaseCnt, 0, phaseCntMax, 0.0, 1.0);
      timeDiv += PI * phaseDiv;

      float prevCatX = 0.0;
      float prevCatY = 0.0;
      float prevCatT = 0.0;
      float prevSomT = 0.0;

      for (int recurseCnt = 0; recurseCnt < recurseCntMax; ++recurseCnt) {

        // cat formula
        float catX = (pow(sin(prevCatX), 3) + cos(prevCatY)) * sin(prevCatT);
        float catY = (cos(prevCatX) + pow(sin(prevCatY), 3)) * cos(prevCatT);

        // some shape formula
        float somX = (sin(prevCatX) * paramSomX - cos(prevCatY) * paramSomY) + cos(prevSomT);
        float somY = (cos(prevCatX) * paramSomX - sin(prevCatY) * paramSomY) + sin(prevSomT);

        float x = catX * (1.0 - easing) + somX * easing;
        float y = catY * (1.0 - easing) + somY * easing;
        
        float catT = prevCatT + timeDiv;
        float somT = prevSomT - (x + y) * paramSomT;

        float eX = x * width * (0.35 + easing * 0.0);
        float eY = y * height * (0.35 + easing * 0.0);
        float eS = phaseRate;

        fill(
             (baseHue + phaseRate * 60.0) % 360,
             40,
             (1.0 - phaseRate) * 30.0,
             100
             );
        ellipse(
                eX,
                eY,
                eS,
                eS
                );

        prevCatX = catX;
        prevCatY = catY;
        prevCatT = catT;
        prevSomT = somT;

      }
    }

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

  }

  // for showing cat shape longer
  for (int i = 0; i < 5; ++i) {
    saveFrame("frames/99" + String.format("%02d", i) + ".png");
  }

  saveFrame("frames/0000.png");  // for Twitter thumbnail
  
  exit();

}

/**
 * easeInOutCubic easing function.
 * @param  t     0.0 - 1.0 : linear value.
 * @return float 0.0 - 1.0 : eased value.
 */
private 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;
}

/**
 * rndSign random sign maker.
 * @return int  +1 or -1 : random
 */
private int rndSign() {
  int rndVal = ceil(random(-10, 10));
  if (rndVal == 0) {
    return -1;
  } else {
    return rndVal / abs(rndVal);
  }
}

/*
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 "https://www.gnu.org/licences/"
*/



 

On-going status of morphing.


Start scene of my cat formula morphing.

An example image of the scene of this animation.

 

Next Post Previous Post
No Comment
Add Comment
comment url