# Cosmic Cycler

It was made with Processing programming code and Kdenlive video editor.
I learned PShape and PVector in this example code.
Thank you sir Daniel Shiffman for nice tutorials.
PShape
https://processing.org/tutorials/pshape/
PVector
https://processing.org/tutorials/pvector/

And thanks to nice music:
Riser by Evan Schaeffer
2017/02/21
http://freemusicarchive.org/music/Evan_Schaeffer/Glow_1216/Evan_Schaeffer_-_04_-_Riser
For more permissions:
contact artist

## Processing code example.

```// Cosmic Cycler
// Processing 3.2.1
// 2017.04.18

import java.util.Random;

World wd;
Cycler cl;
BigObject bo;
Shooting st;

float SKY_WIDTH = 600;
float SKY_HEIGHT = 340;

/* ---------------------------------------------------------------------- */
class World {

Star st;
PVector[] locateStars;
float[] colorStars;
int numStars;

World() {

numStars = 50;

st = new Star();
st.setBodyFill(0, 90, 80, 100);

float divWidth = SKY_WIDTH * 2.5 / numStars;
locateStars = new PVector[numStars];
colorStars = new float[numStars];
for (int i = 0; i < numStars; ++i) {
locateStars[i] = new PVector(
-SKY_WIDTH * 1.25 + divWidth * (i + random(0, 0.25)),
map(random(1.), 0., 1., -SKY_HEIGHT, -100.),
map(random(1.), 0., 1., -900., -500.)
);
colorStars[i] = random(360);
}

}

void redraw() {
lightFalloff(1.0, 0.00005, 0.000002);
pointLight(0, 0, 100, 0, 0, 100);
camera(0, 0, 80,
0, 0, 0,
0, 1, 0);
background(0, 0, 0);
}

void twilight() {
float cntColor = 0.;
float cntSaturation = 0.;
float cntBright = 0.;
strokeWeight(3);
for (float i = -SKY_HEIGHT; i < SKY_HEIGHT; ++i) {
cntColor += 0.13;
cntSaturation += 0.07;
cntBright += 0.07;
stroke(
230 + cntColor,
100 - cntSaturation,
50 + cntBright,
100
);
pushMatrix();
translate(0, i, -500);
line(-SKY_WIDTH, 0, SKY_WIDTH, 0);
popMatrix();
}
}

void starlysky() {
float divColor = (frameCount % 3600) / 10;
for (int i = 0; i < numStars; ++i) {
st.changeColor((colorStars[i] + divColor) % 360);
pushMatrix();
translate(locateStars[i].x, locateStars[i].y, locateStars[i].z);
st.twinkle();
popMatrix();
}
}

}

/* ---------------------------------------------------------------------- */
class Cycler {

Star[] st;
float[] rotateNoise;
PVector[] locateStars, velocityStars;
int numStars = 2;

Cycler() {
st = new Star[numStars];
rotateNoise = new float[numStars];
locateStars = new PVector[numStars];
velocityStars = new PVector[numStars];
for (int i = 0; i < numStars; ++i) {
st[i] = new Star();
rotateNoise[i] = random(10);
locateStars[i] = new PVector(-SKY_WIDTH - 1000, 0, 0);
velocityStars[i] = new PVector(0, 0, 0);
}
}

void resetCourse() {
float lx = SKY_WIDTH / 2;
float ly = map(random(1.), 0., 1., 0., SKY_HEIGHT / 8);
float lz = map(random(1.), 0., 1., -200., -80.);
float vx = map(random(1.), 0., 1., -0.5, -1.0);
float vy = map(random(1.), 0., 1., -0.4, 0.3);
float vz = 0;
float bodyColor = random(360);
for (int i = 0; i < numStars; ++i) {
st[i].setBodyFill(
(bodyColor + i * 180) % 360,
60,
80,
100
);
locateStars[i].set(
lx + i * (10 + random(10)),
ly + i * (5 + random(5)),
lz + i * 10
);
velocityStars[i].set(
vx,
vy,
vz
);
}
}

void cycling() {
noStroke();
float[] rotateValue = new float[numStars];
PVector locateAfter = new PVector(0, 0, 0);
for (int i = 0; i < numStars; ++i) {
if (locateStars[i].x < -SKY_WIDTH / 2 - 30 || abs(locateStars[i].y) > SKY_HEIGHT / 2 + 30) {
resetCourse();
}

rotateValue[i] = noise(rotateNoise[i]);

// Star
pushMatrix();
translate(locateStars[i].x, locateStars[i].y, locateStars[i].z);
st[i].resetColor();
st[i].twinkle();
popMatrix();

// After Image
locateAfter = locateStars[i].copy();
for (int j = 0; j < 3; ++j) {
locateAfter.sub(PVector.mult(velocityStars[i], 3));
pushMatrix();
translate(locateAfter.x, locateAfter.y, locateAfter.z);
st[i].changeBright(36. - j * 8);
st[i].twinkle();
popMatrix();
}

rotateNoise[i] += 0.0005;
locateStars[i].add(PVector.mult(velocityStars[i], 1 + rotateValue[i] / 4));
}
}

}

/* ---------------------------------------------------------------------- */
class BigObject {

Star st;
Moon mn;
float stBright, stdivBright, stBrightMax, stBrightMin;
float mnBrightMax, mnBrightMin;

BigObject() {
stBrightMax = 90;
stBrightMin = 50;
stBright = stBrightMin;
stdivBright = -1;
st = new Star();
st.setBodyFill(
230,
90,
50,
100
);
st.changeSize(12);

mnBrightMax = 80;
mnBrightMin = 0;
mn = new Moon();
mn.setBodyFill(
0,
60,
80,
100
);
}

void rise() {
stBright += stdivBright;
if (stBright < stBrightMin) {
stdivBright = 0.01;
} else if (stBright > stBrightMax) {
stdivBright = -0.03;
}
st.changeBright(stBright);
mn.changeBright(map(stBright, stBrightMin, stBrightMax, mnBrightMax, mnBrightMin));

pushMatrix();
translate(0, 0, -100);
mn.twinkle();
translate(-140, -60, -50);
st.rotate(-0.0002);
st.twinkle();
popMatrix();
}

}

/* ---------------------------------------------------------------------- */
class Shooting {

Star meteor;
Star[] dusts;
PVector gravity;
PVector locateMeteor, velocityMeteor;
PVector[] locateDusts, velocityDusts;
float[] rotateDusts, brightDusts;
int numDusts = 100;
int numDrawDusts;

Shooting() {
// Shooting Star
meteor = new Star();
meteor.changeSize(4.0);
meteor.setBodyFill(
0,
0,
100,
100
);
locateMeteor = new PVector(-SKY_WIDTH - 1000, 0, 0);
velocityMeteor = new PVector(0, 0, 0);
gravity = new PVector(0, 0, 0);

// Star Dusts
dusts = new Star[numDusts];
rotateDusts = new float[numDusts];
brightDusts = new float[numDusts];
locateDusts = new PVector[numDusts];
velocityDusts = new PVector[numDusts];
for (int i = 0; i < numDusts; ++i) {
dusts[i] = new Star();
dusts[i].setBodyFill(
random(360),
100,
60,
100
);
rotateDusts[i] = map(random(1.), 0., 1., -2., 2.);
brightDusts[i] = 0;
locateDusts[i] = new PVector(0, 0, 0);
velocityDusts[i] = new PVector(0, 0, 0);
}
numDrawDusts = 0;
}

void resetCourse() {
// Shooting Star
float lx = map(random(1.), 0., 1., -SKY_WIDTH / 8, SKY_WIDTH / 2);
float lz = map(random(1.), 0., 1., -500., -300.);
float ly = lz * 0.6;
float vx = map(random(1.), 0., 1., -0.5, -3.0);
float vy = map(random(1.), 0., 1., 0.8, 2.0);
float vz = -lz / 120;
float gy = map(vy, 1.0, 2.0, 0.01, 0.04);

if (random(10) < 6) {
lz = lz * 0.1;
vz = -vz * 0.8;
vy = vy * 2;
gy = -gy * 0.05;
}

meteor.setBodyFill(
random(360),
60,
80,
100
);
locateMeteor.set(lx, ly, lz);
velocityMeteor.set(vx, vy, vz);
gravity.set(0, gy, 0);

// Star Dusts
for (int i = 0; i < numDusts; ++i) {
dusts[i].resetSize();
dusts[i].changeSize(0.6);
}
numDrawDusts = 0;

}

void shoot() {
// Shooting Star
if (frameCount % 210 == 0) {
if (locateMeteor.x < -SKY_WIDTH / 2 - 100 || locateMeteor.y > SKY_HEIGHT / 2 + 100) {
resetCourse();
}
}
pushMatrix();
translate(locateMeteor.x, locateMeteor.y, locateMeteor.z);
meteor.twinkle();
popMatrix();

// Star Dusts
if (numDrawDusts >= numDusts) {
numDrawDusts = numDusts;
} else {
locateDusts[numDrawDusts] = locateMeteor.copy();
locateDusts[numDrawDusts].sub(PVector.mult(velocityMeteor, 10));
velocityDusts[numDrawDusts].set(
map(random(1.), 0., 1., -3., 3.),
map(random(1.), 0., 1., -2., 0.),
0
);
brightDusts[numDrawDusts] = 60;
++numDrawDusts;
}
for (int i = 0; i < numDrawDusts; ++i) {
brightDusts[i] = brightDusts[i] * 0.97;
dusts[i].changeBright(brightDusts[i]);
velocityDusts[i].mult(0.95);

pushMatrix();
translate(locateDusts[i].x, locateDusts[i].y, locateDusts[i].z);
dusts[i].changeSize(0.99);
dusts[i].twinkle();
popMatrix();
}

}

}

/* ---------------------------------------------------------------------- */
abstract class CelestialBody {

PShape aBody;
float bodyColor, bodySaturation, bodyBright, bodyAlpha;

CelestialBody() {
aBody = pscreateBody();
bodyColor = 0;
bodySaturation = 0;
bodyBright = 0;
bodyAlpha = 0;
}

abstract PShape pscreateBody();

void setBodyFill(float pcolor, float psaturation, float pbright, float palpha) {
bodyColor = pcolor;
bodySaturation = psaturation;
bodyBright = pbright;
bodyAlpha = palpha;
resetColor();
}

void resetColor() {
aBody.setFill(color(bodyColor, bodySaturation, bodyBright, bodyAlpha));
}

void changeColor(float scolor) {
aBody.setFill(color(scolor, bodySaturation, bodyBright, bodyAlpha));
}

void changeBright(float sbright) {
aBody.setFill(color(bodyColor, bodySaturation, sbright, bodyAlpha));
}

void resetSize() {
aBody.resetMatrix();
}

void changeSize(float sscale) {
aBody.scale(sscale);
}

}

void twinkle() {
shape(aBody);
}

}

/* ---------------------------------------------------------------------- */
class Star extends CelestialBody {

Star() {
super();
}

PShape pscreateBody() {
int vertexNum = 10;

noStroke();
PShape psStar = createShape();
psStar.beginShape();
for (int i = 0; i <= vertexNum; ++i) {
if (i%2 == 0) {
} else {
}
psStar.vertex(
);
}
psStar.endShape(CLOSE);
return psStar;
}

}

/* ---------------------------------------------------------------------- */
class Moon extends CelestialBody {

Moon() {
super();
}

PShape pscreateBody() {
noStroke();
PShape psMoon = createShape(ELLIPSE, 0, 0, 100, 100);
return psMoon;
}

}

/* ---------------------------------------------------------------------- */
void setup() {
size(1280, 720, P3D);
colorMode(HSB, 360, 100, 100, 100);
blendMode(LIGHTEST);
hint(DISABLE_DEPTH_TEST);
smooth();
background(0, 0, 0);
frameRate(30);

wd = new World();
cl = new Cycler();
bo = new BigObject();
st = new Shooting();
}

void draw() {

wd.redraw();
wd.twilight();
wd.starlysky();

bo.rise();
cl.cycling();
st.shoot();

/*
saveFrame("frames/####.png");
if (frameCount >= 5402) {
exit();
}
*/
}

/*

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

```

No Comment