import processing.core.*; import java.applet.*; import java.awt.*; import java.awt.image.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.text.*; import java.util.*; import java.util.zip.*; import javax.sound.midi.*; import javax.sound.midi.spi.*; import javax.sound.sampled.*; import javax.sound.sampled.spi.*; import java.util.regex.*; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.sax.*; import javax.xml.transform.stream.*; import org.xml.sax.*; import org.xml.sax.ext.*; import org.xml.sax.helpers.*; public class accretion_disk2 extends PApplet {float arot; PFont font; int maxpennies=150; int npennies; float[][] pennies; int maxacc=150; int naccreted = 0; float[][] accreta; boolean mouseHeld; float stepsize; int ballsize = 5; int nsides = 16; int nlevels = 25; int lastTime = 0; float[] level; int it=0; int npennies_t=0; int naccreted_t=0; int ncoll = 0; boolean IncludeCone= true; boolean IncludeWalls = false; boolean IncludeFlats = false; boolean UseColor = false; boolean UseLight = false; boolean UseWireFrame = true; boolean RotateFunnel= false; public void setup() { size(400, 400, P3D); arot = 0; npennies = 0; pennies = new float[3][maxpennies]; naccreted = 0; accreta = new float[2][maxacc]; mouseHeld = false; stepsize = TWO_PI/200; level = new float[nlevels]; for (int i = 0; i< nlevels;i++) { level[i] = (nlevels-i)*(nlevels-i)*180.0f/(nlevels*nlevels); } colorMode(HSB, 1,1,1); font = loadFont("AmericanTypewriter-24.vlw"); textFont(font,12); } public void draw() { int currentTime = millis(); if (currentTime > lastTime+50) { println(currentTime - lastTime); it++; background(0); if (UseLight) lights(); //draw "mouse position bar" noFill(); stroke(0.4f,0.4f,0.4f); rect(width/2-level[0],9*height/10,2*level[0],2); noStroke(); fill(1,0,1); rect(mouseX-ballsize/4,9*height/10-2*ballsize,ballsize/2,3*ballsize); triangle(mouseX,9*height/10-3*ballsize,mouseX-ballsize,9*height/10-2*ballsize,mouseX+ballsize,9*height/10-2*ballsize); ellipse(mouseX,9*height/10,2*ballsize,2*ballsize); //draw "reset button" noFill(); stroke(0.4f,0.4f,0.4f); rect(width/40,height/40,width/20,height/20); line(width/40,height/40,3*width/40,3*height/40); line(3*width/40,height/40,width/40,3*height/40); //draw "add heap of points" boxes noFill(); stroke(0.4f,0.4f,0.4f); triangle(width/2-125-width/40,height/20,width/2-125+width/40,height/20,width/2-125,3*height/40); triangle(width/2-100-width/40,height/20,width/2-100+width/40,height/20,width/2-100,3*height/40); triangle(width/2-75-width/40,height/20,width/2-75+width/40,height/20,width/2-75,3*height/40); triangle(width/2-50-width/40,height/20,width/2-50+width/40,height/20,width/2-50,3*height/40); triangle(width/2-25-width/40,height/20,width/2-25+width/40,height/20,width/2-25,3*height/40); triangle(width/2-0-width/40,height/20,width/2-0+width/40,height/20,width/2-0,3*height/40); text("click here to drop 10 objects",width/2-130,3*height/80); text("click anywhere to drop one object",width/2-130,19*height/20); text("launched: "+npennies_t,7*width/10,height/20); text("accreted: "+naccreted_t,7*width/10,height/10); text("collisions: "+ncoll,7*width/10,3*height/20); translate(width / 2, height / 2); rotateY(PI/2); rotateZ(map(mouseY, 0, height, 0, -PI/2)); noStroke(); fill(255, 255, 255); translate(0, -40, 0); arot += stepsize * (currentTime-lastTime)/50; if (RotateFunnel) { for (int i=0;i TWO_PI) { pennies[1][i] -= TWO_PI; } } for (int i=0;i width/2) { pennies[1][npennies] = PI/2; } else { pennies[1][npennies] = 3*PI/2; } pennies[2][npennies] = random(1); println(mouseX + " " + mouseY + " = " + pennies[0][npennies]+ " " + pennies[1][npennies] ); pushMatrix(); drawPenny(npennies,10); popMatrix(); // sort pennies by radius sortPennies(); npennies++; npennies_t++; //if the mouse click was in the reset button area if (mouseX > width/40 && mouseY > height/40 && mouseX < 3*width/40 && mouseY < 3*height/40) { npennies = 0; naccreted = 0; npennies_t = 0; naccreted_t = 0; ncoll = 0 ; } //if the mouse click was in the add-planets button area if (mouseY < height/10) { if (mouseX > width/2-125-width/40 && mouseX < width/2+width/40) { npennies--; for (int i=npennies;i 0) { while (pennies[0][npennies-1] <= 0) // discard pennies that fall thru center { // println("accretion needed "+ npennies + " " + pennies[0][npennies-1]); npennies--; accreta[0][naccreted] = myCurve(0.0f); accreta[1][naccreted] = pennies[2][npennies]; naccreted++; naccreted_t++; if (naccreted > maxacc) naccreted=100; //hard cap println("accreted! to "+ naccreted + " " + accreta[0][naccreted]); if (npennies <= 0) break; } } // track accreted objects if (naccreted > 0) { while (accreta[0][0] > 500 && naccreted > 0) //let some accreta fall off bottom of view { naccreted--; println("fell off bottom"); for (int i=0;i npennies-1) continue; if (abs(pennies[1][i] - pennies[1][j])*pennies[0][i] < 10) { if (abs(pennies[0][i] - pennies[0][j]) < 10) //close in radius { pushMatrix(); translate(pennies[0][i]*cos(pennies[1][i]), myCurve(pennies[0][i]), pennies[0][i]*sin(pennies[1][i])); fill(10,1,1); noStroke(); sphere(5); // "collision" flash popMatrix(); ncoll++; //move in consequence float kicksize = (random(5)+2)/sqrt(1+pow(5.0f/(sqrt(pennies[0][i])),2)); // println(pennies[0][i] + " " + kicksize); pennies[0][i] += kicksize; pennies[0][j] -= kicksize; pushMatrix(); drawPenny(i,8); popMatrix(); pushMatrix(); drawPenny(j,8); popMatrix(); } } } } sortPennies(); } static public void main(String args[]) { PApplet.main(new String[] { "accretion_disk2" }); }}