float radious = 250;
ArrayList<Particle> particles;
PVector rNoise1, rNoise2;
float nScale = 3.4;
float maxVel = PI / 2048;
float velStep = PI / 20480;
void setup(){
size(640, 640, P3D);
particles = new ArrayList<Particle>();
for(int i = 0; i < 30; i++){
particles.add(new Particle());
}
rNoise1 = new PVector(random(100000), random(100000));
rNoise2 = new PVector(random(100000), random(100000));
stroke(0, 128);
noFill();
}
void draw(){
background(255);
translate(width / 2, height / 2);
rotateX(0.001 * frameCount);
rotateY(0.002 * frameCount);
rotateZ(0.003 * frameCount);
for(Particle particle: particles){
particle.update();
particle.draw();
}
}
class Particle{
float r1, r2;
float vr1, vr2;
ArrayList<PVector> track;
Particle(){
r1 = random(TWO_PI);
r2 = random(TWO_PI);
vr1 = random(-maxVel, maxVel);
vr2 = random(-maxVel, maxVel);
track = new ArrayList<PVector>();
float x = radious * sin(r1) * cos(r2);
float y = radious * sin(r1) * sin(r2);
float z = radious * cos(r1);
track.add(new PVector(x, y, z));
}
void update(){
vr1 += map(noise(rNoise1.x + cos(r1) * nScale, rNoise1.y + sin(r1) * nScale), 0, 1, -velStep, velStep);
constrain(vr1, -maxVel, maxVel);
r1 += vr1;
if(r1 < 0){
r1 += TWO_PI;
} else if(r1 >= TWO_PI){
r1 -= TWO_PI;
}
vr2 += map(noise(rNoise2.x + cos(r2) * nScale, rNoise2.y + sin(r2) * nScale), 0, 1, -velStep, velStep);
constrain(vr2, -maxVel, maxVel);
r2 += vr2;
if(r2 < 0){
r2 += TWO_PI;
} else if(r2 >= TWO_PI){
r2 -= TWO_PI;
}
float x = radious * sin(r1) * cos(r2);
float y = radious * sin(r1) * sin(r2);
float z = radious * cos(r1);
track.add(new PVector(x, y, z));
if(track.size() > 1000){
track.remove(0);
}
}
void draw(){
beginShape();
for(PVector p: track){
vertex(p.x, p.y, p.z);
}
endShape();
}
}