# Calculation formulas involving trigonometric functions can generate stunning dances.

## Vivid dance with some interesting calculation formula.

It's a creative coding animation made with 'Processing'. I found an interesting formula that creates some funny dance of particles.

This calculation makes points an interesting location moving.

// magic calculation for the vivid dance
float theta = PI * cos(divX + divY) * sin(divY) + sin(divX + divY) * cos(divX);
divX = cos(theta);
divY = sin(theta);
x += divX;
y += divY;

And I drew the points with 'TRIANGLE_STRIP', then it looked like a vivid dance of wireframe object.

beginShape(TRIANGLE_STRIP);
for (PVector p : _p) {
vertex(p.x * _mult, p.y * _mult);
}

## An example source code of 'Processing'.

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 under the terms of the GPL. To see other works based on my code is my pleasure. And my honor.

``````
/**
* Neutron Dance.
* vivid dance with some interesting calculation formula.
*
* @author @deconbatch
* @version 0.1
* Processing 3.5.3
* 2020.10.04
*/

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

void draw() {

int   frmMax    = 24 * 8; // 24fps x 8sec animation
int   objectMax = 3;
float baseTheta = random(0.28, 0.40); // for nice dancing
float rotation  = random(PI);

translate(width * 0.5, height * 0.5);

for (int frmCnt = 0; frmCnt < frmMax; frmCnt++) {
float frmRatio  = map(frmCnt, 0, frmMax, 0.0, 1.0);
float easeRatio = InOutCubic(frmRatio);

background(0.0, 0.0, 90.0, 100.0);

// draw orbits
strokeWeight(1.0);
noFill();
for (int i = 1; i <= 6; i++) {
stroke(0.0, 0.0, 50.0 + i * 5.0, 100.0);
ellipse(0.0, 0.0, radius * 2.0 * i, radius * 2.0 * i);
}

// calculate object shape and location
ArrayList<ArrayList<PVector>> objects = new ArrayList<ArrayList<PVector>>();
for (int objectCnt = 0; objectCnt < objectMax; objectCnt++) {
float objectRatio = map(objectCnt, 0, objectMax, 0.0, 1.0);
float theta = TWO_PI * (objectRatio + baseTheta);
float divX  = cos(theta + easeRatio * TWO_PI / objectMax);
float divY  = sin(theta + easeRatio * TWO_PI / objectMax);
ArrayList<PVector> points = getPoints(5, divX, divY);
}

// draw background particles
for (ArrayList<PVector> points : objects) {
pushMatrix();
rotate(rotation + HALF_PI + frmRatio * TWO_PI);
for (int i = 1; i <= 2; i++) {
rotate(PI);
drawJoints(points, radius * i * 2.0, 30.0);
}
popMatrix();
}

// draw dancing objects
for (ArrayList<PVector> points : objects) {
pushMatrix();
rotate(rotation);
popMatrix();
}

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

exit();
}

/**
* getPoints
* @param  _pMax    : points number to calculate
* @param  _dX, _dY : distance between points
* @return  : array of points location.
*/

private ArrayList<PVector> getPoints(int _pMax, float _dX, float _dY) {

float divX = _dX;
float divY = _dY;
float x    = 0.0;
float y    = 0.0;
ArrayList<PVector> points = new ArrayList<PVector>();

for (int pCnt = 0; pCnt < _pMax; pCnt++) {
// magic calculation for the vivid dance
float theta = PI * cos(divX + divY) * sin(divY) + sin(divX + divY) * cos(divX);
divX = cos(theta);
divY = sin(theta);
x += divX;
y += divY;
}
return points;
}

/**
* drawBones
* @param  _p    : array of points to draw
* @param  _mult : object size
*/
private void drawBones(ArrayList<PVector> _p, float _mult) {
strokeWeight(2.0);
stroke(0.0, 0.0, 50.0, 100.0);
noFill();
beginShape(TRIANGLE_STRIP);
for (PVector p : _p) {
vertex(p.x * _mult, p.y * _mult);
}
endShape();
}

/**
* drawJoints
* @param  _p    : array of points to draw
* @param  _mult : object size
* @param  _sat  : saturation value with drawing
*/
private void drawJoints(ArrayList<PVector> _p, float _mult, float _sat) {
float margin = 5.0;
for (PVector p : _p) {
float siz = map(sin(0.5 * (p.x * p.y)), -1.0, 1.0, 10.0, 25.0);
strokeWeight(margin);
stroke(0.0, 0.0, 90.0, 100.0);
fill(360.0 * abs(sin(0.4 * (p.x + p.y))) % 360, _sat, 80.0, 100.0);
ellipse(p.x * _mult, p.y * _mult, siz, siz);
if (sin(0.2 * (p.x * p.y)) > 0.5) {
strokeWeight(2);
stroke(0.0, 0.0, 50.0, 100.0);
noFill();
ellipse(p.x * _mult, p.y * _mult, siz + margin, siz + margin);
}
}
}

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

/**
* casing : draw fancy casing
*/
public void casing() {
fill(0.0, 0.0, 0.0, 0.0);
strokeWeight(30.0);
stroke(0.0, 0.0, 50.0, 100.0);
rect(0.0, 0.0, width, height);
strokeWeight(28.0);
stroke(0.0, 0.0, 100.0, 100.0);
rect(0.0, 0.0, width, height);
}

/*

This program is free software: you can redistribute it and/or modify
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/>
*/
```
```

No Comment