/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.McsNtZg0zBW/rev.121
*
* authors:
* Wolfe
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
// I'm aware the code is a mess.
// I had modified, added and tried often until have been lost in code :)
final int MAX_VERTEX = 1000;
int drawnVertex;
final float GRAVITY = 9.80665;
final int BURST = 6;
int colorChanger;
boolean lockXrot, lockYrot;
int lastX, lastY;
boolean pressed;
float farZ, nearZ;
float camX, camY, camZ;
Vertice[] vertex;
////////////// + S E T U P + //////////////
void setup() {
size (400, 400);
drawnVertex = 1000;
pressed = false;
vertex = new Vertice[MAX_VERTEX];
colorChanger = 30;
for (int i=0; i<vertex.length;i++) {
vertex[i] = new Vertice(0, 1000, 0, random(-10), 0, radians(random(360)), 0);
}
lockXrot = true;
lockYrot = false;
}
////////////// - S E T U P - //////////////
////////////// + D R A W + //////////////
void draw() {
// background(0);
fill(0,20);
rect(0,0,width,height);
for (int i=0; i<vertex.length;i++) {
vertex[i].update();
}
for (int i=0; i<drawnVertex;i++) {
vertex[i].draw();
}
//farZ = -1000;
//nearZ = 1000;
if ( frameCount % BURST == 0) colorChanger++;
if (colorChanger>360) colorChanger=0;
fill(255);
text("Press SPACE key to "+((lockXrot)?"unlock":"lock"), 0, 20);
text("X-axis rotation.", 0, 35);
text("Press number keys ( 1 to 1000 ) for count of particles * 100", 20, height-10);
}
////////////// - D R A W - //////////////
/////// + R O T A T I O N S + ///////
////////////// +calcRotations+ //////////////
float[] calcRotations(float x, float y, float z, float a, float b, float c) {
float rx = x*cos(a)*cos(b) - y*sin(a)*cos(b) - z*sin(b);
float ry = y*cos(a)*cos(c) + x*sin(a)*cos(c) - z*cos(b)*sin(c) - x*cos(a)*sin(b)*sin(c) + y*sin(a)*sin(b)*sin(c);
float rz = y*cos(a)*sin(c) + x*sin(a)*sin(c) + z*cos(b)*cos(c) + x*cos(a)*sin(b)*cos(c) - y*sin(a)*sin(b)*cos(c);
return new float[] {
rx, ry, rz
};
}
////////////// -calcRotations- //////////////
public float[] rotObjX(float x, float y, float z, float ang) {
float yy = y*cos(ang) - z*sin(ang);
float zz = y*sin(ang) + z*cos(ang);
return new float[] {
yy, zz
};
}
public float[] rotObjY(float x, float y, float z, float ang) {
float zz = z*cos(ang) - x*sin(ang);
float xx = z*sin(ang) + x*cos(ang);
return new float[] {
xx, zz
};
}
public float[] rotObjZ(float x, float y, float z, float ang) {
float xx = x*cos(ang) - y*sin(ang);
float yy = x*sin(ang) + y*cos(ang);
return new float[] {
xx, yy
};
}
////////////
public void rotCamX(float ang) {
camX -= ang;
}
public void rotCamY(float ang) {
camY -= ang;
}
public void rotCamZ(float ang) {
camZ += ang;
}
/////// - R O T A T I O N S - ///////
///////
class Vertice {
float x, y, z;
float rx, ry, rz;
float a, b, c; //total angles
int col;
float swivel, tilt;
float velocity;
float time;
Vertice(float x, float y, float z, float velocity, float tilt, float swivel, int col) {
this.x = x;
this.y = y;
this.z = z;
this.velocity = velocity;
this.tilt = tilt;
this.swivel = swivel;
this.col = col;
a = b = c = 0;
time = 0;
}
public void update() {
//projectile projection
float rot[];
rot = rotObjY(x, y, z, -swivel);
x = rot[0];
z = rot[1];
float vx = sin(tilt) * velocity;
float vy = -1 * cos(tilt) * velocity * time + GRAVITY * time * time;
x += vx;
y += vy;
rot = rotObjY(x, y, z, swivel);
x = rot[0];
z = rot[1];
time += 0.005;
if (y>150) {
x = 0;//(random(-100,100));
y = 150;
z = 0;
velocity = random(2, 10);
tilt = radians(random(-5, 5));
swivel = radians(random(360));
time = 0;
col = colorChanger;
}
rz = y*cos(a)*sin(c) + x*sin(a)*sin(c) + z*cos(b)*cos(c) + x*cos(a)*sin(b)*cos(c) - y*sin(a)*sin(b)*cos(c);
if (farZ < rz) farZ = rz;
if (nearZ > rz) nearZ = rz;
}
public void draw() {
float rot[];
rot = calcRotations(x, y, z, camX, camY, camZ);
float proj = (1000 / (1000 - rot[2]));
float x2d = rot[0] * proj + width/2;
float y2d = rot[1] * proj + height/2;
pushStyle();
float vertSize= abs(map(rot[2], nearZ, farZ, 1, 8));
float vertShade=abs(map(rot[2], nearZ, farZ, 1, 255));
colorMode(HSB, 360, 100, 100);
fill(col, 100, vertShade);
noStroke();
ellipse(x2d, y2d, vertSize, vertSize);
popStyle();
}
}
///////////////
float xTo2D (Vertice vert) {
return vert.x * (1000 / (1000 - vert.z)) + width/2;
}
float yTo2D (Vertice vert) {
return vert.y * (1000 / (1000 - vert.z)) + height/2;
}
void mousePressed() {
pressed = true;
lastX = mouseX;
lastY = mouseY;
}
void mouseDragged() {
if (!lockXrot)
rotCamX(radians((lastY-mouseY) % 20));
if (!lockYrot)
rotCamY(radians((mouseX-lastX) % 20));
lastX = mouseX;
lastY = mouseY;
}
void mouseReleased() {
pressed = false;
}
void keyReleased() {
if (keyCode>=49 && keyCode<=57) drawnVertex = (keyCode-48) * 100;
if (keyCode==48) drawnVertex = 1000;
// numpad keys
if (keyCode>=97 && keyCode<=106) drawnVertex = (keyCode-96) * 100;
if (keyCode==96) drawnVertex = 1000;
if (key == 32) {
if (lockXrot) lockXrot = !lockXrot;
else {
camX = 0;
camY = 0;
camZ = 0;
lockXrot = !lockXrot;
}
}
}
01