sphere composed of particles
@author
float scale = 100;
float phi = (1 + sqrt(5)) / 2.0;
ArrayList<Particle> particles;
void setup(){
size(500, 500, P3D);
PVector[] vertices = {new PVector(0, 1, phi),
new PVector(0, -1, phi),
new PVector(0, -1, -phi),
new PVector(0, 1, -phi),
new PVector(phi, 0, 1),
new PVector(-phi, 0, 1),
new PVector(-phi, 0, -1),
new PVector(phi, 0, -1),
new PVector(1, phi, 0),
new PVector(-1, phi, 0),
new PVector(-1, -phi, 0),
new PVector(1, -phi, 0)};
ArrayList<Triangle> triangles = new ArrayList<Triangle>();
triangles.add(new Triangle(vertices[0], vertices[8], vertices[9]));
triangles.add(new Triangle(vertices[0], vertices[9], vertices[5]));
triangles.add(new Triangle(vertices[0], vertices[5], vertices[1]));
triangles.add(new Triangle(vertices[0], vertices[1], vertices[4]));
triangles.add(new Triangle(vertices[0], vertices[4], vertices[8]));
triangles.add(new Triangle(vertices[1], vertices[5], vertices[10]));
triangles.add(new Triangle(vertices[1], vertices[10], vertices[11]));
triangles.add(new Triangle(vertices[1], vertices[11], vertices[4]));
triangles.add(new Triangle(vertices[2], vertices[3], vertices[7]));
triangles.add(new Triangle(vertices[2], vertices[7], vertices[11]));
triangles.add(new Triangle(vertices[2], vertices[11], vertices[10]));
triangles.add(new Triangle(vertices[2], vertices[10], vertices[6]));
triangles.add(new Triangle(vertices[2], vertices[6], vertices[3]));
triangles.add(new Triangle(vertices[3], vertices[6], vertices[9]));
triangles.add(new Triangle(vertices[3], vertices[9], vertices[8]));
triangles.add(new Triangle(vertices[3], vertices[8], vertices[7]));
triangles.add(new Triangle(vertices[4], vertices[11], vertices[7]));
triangles.add(new Triangle(vertices[4], vertices[7], vertices[8]));
triangles.add(new Triangle(vertices[5], vertices[9], vertices[6]));
triangles.add(new Triangle(vertices[5], vertices[6], vertices[10]));
for(int i = 0; i < 4; i++){
ArrayList<Triangle> nextTriangles = new ArrayList<Triangle>();
for(Triangle t: triangles){
nextTriangles.addAll(t.divide());
}
triangles = nextTriangles;
}
particles = new ArrayList<Particle>();
for(Triangle tri: triangles){
for(PVector v: tri.vertices){
boolean isExist = false;
for(Particle p: particles){
if(v.x * scale == p.home.x && v.y * scale== p.home.y && v.z * scale == p.home.z){
isExist = true;
break;
}
}
if(!isExist){
particles.add(new Particle(new PVector(v.x * scale, v.y * scale, v.z * scale)));
}
}
}
}
void draw(){
background(0);
translate(width / 2, height / 2);
rotateY(frameCount * 0.01);
stroke(0, 255, 255);
for(Particle p: particles){
p.display();
p.update();
}
}
void mousePressed(){
for(Particle p: particles){
p.impact();
}
}
class Particle{
PVector home, loc, vel;
Particle(PVector _home){
home = _home;
loc = new PVector(home.x, home.y, home.z);
vel = new PVector(0, 0, 0);
}
void display(){
point(loc.x, loc.y, loc.z);
}
void impact(){
float velSize = random(10,20);
float velAng1 = random(PI);
float velAng2 = random(TWO_PI);
float x = velSize * sin(velAng1) * cos(velAng2);
float y = velSize * cos(velAng1);
float z = velSize * sin(velAng1) * sin(velAng2);
vel = new PVector(x, y, z);
}
void update(){
PVector acc = PVector.sub(home, loc);
acc.limit(0.1);
vel.add(acc);
vel.mult(0.98);
loc.add(vel);
}
}
class Triangle{
PVector[] vertices;
Triangle(PVector v0, PVector v1, PVector v2){
vertices = new PVector[3];
vertices[0] = v0;
vertices[1] = v1;
vertices[2] = v2;
}
ArrayList<Triangle> divide(){
PVector[] midpoints = new PVector[3];
for(int i = 0; i < 3; i++){
int j = i != 2 ? i + 1: 0;
PVector m = PVector.lerp(vertices[i], vertices[j], 0.5);
m.normalize();
m.mult(sqrt(sq(1) + sq(phi)));
midpoints[i] = m;
}
ArrayList<Triangle> triangles = new ArrayList<Triangle>();
triangles.add(new Triangle(vertices[0], midpoints[0], midpoints[2]));
triangles.add(new Triangle(vertices[1], midpoints[1], midpoints[0]));
triangles.add(new Triangle(vertices[2], midpoints[2], midpoints[1]));
triangles.add(new Triangle(midpoints[0], midpoints[1], midpoints[2]));
return triangles;
}
}