## How I discovered the 'Cat formula'.

A creative coding animation work made with Processing.

I found '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/

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 method.
A, B  : morph from A shape to B shape
morph : from 1.0 to 0.0
shape = A * morph + B * (1 - morph)

## Processing code example.

Please feel free to use this code, if you like it.
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
*/

```