//DLA_CIRCLES_WEB3.PDE import processing.net.*; import processing.pdf.*; Client myClient; float max_inc = 2; float thickness = 4.0; float max_radius = 6; float min_radius = 3; float stick_prob = .8; float max_agg_rad = 220; float cart_force_x = 0; float cart_force_y = 0; float polar_force_r = 0; float polar_force_a = 0; ArrayList saved_aggregations = new ArrayList(); PImage banner; PApplet myApp; int w = 600; int h = 600; PFont bFont; PFont iFont; int curr_mil = 0; Circle NUL = new Circle(0,0, -99); Aggregation curr_agg; ArrayList aggregations; int curr_index = -1; int top_index = -1; int bottom_index = -1; int display_index = 0; int saved_disp_index = 0; ArrayList historyStack = new ArrayList(); boolean paused = false; boolean record = false; PGraphics g; PImage b; PApplet app = this; float ca_scale = 1; int ca_color = 0; float ca_xoff = 0; float ca_yoff = 0; float target_scale = 1; int target_color = 170; float target_xoff = 0; float target_yoff = 0; boolean tweening = false; int act = 0; Window main_window; Window agg_window; //SlidingTab controls; Window controls; SlidingTab advControls; SlidingTab saved; Window instructions; PauseButton pause; ClearButton clear; ClearAllButton clearAll; HelpButton help; ZoomButton zoomIn; ZoomButton zoomOut; AddButton add_button; DeleteButton del; AddCurrButton add_curr_b; CartInput ci; RadInput ri; TextBox probBox; ProbSlider stickSlide; TextBox radBox; DiamSlider radSlide; TextBox minBox; MinRadSlider minSlide; TextBox maxBox; MaxRadSlider maxSlide; boolean connected = false; boolean prev_prob_act = false; boolean prev_d_act = false; boolean prev_max_act = false; boolean prev_min_act = false; void setup() { size(w,h); //smooth(); fill(0); ag = this.g; bFont = loadFont("04b11-8.vlw"); iFont = loadFont("ArialMT-12.vlw"); textFont(bFont,8); if (online) { /*try { Socket sock = new Socket("n-e-r-v-o-u-s.com", 5204); myClient = new Client(this, sock); connected = true; } catch (Exception e) { exit(); }*/ } instructions = new Window(20,20,width-40,height-40,this); instructions.fillC = color(255); instructions.strokeC = -1; Label instructionText = new Label(10,10,width-60,height-60, inst); instructionText.fillC = color(255); instructionText.strokeC = -1; instructionText.tsize = 12; instructionText.f = iFont; instructions.visible = false; instructions.add(instructionText); main_window = new Window(0,0,width, height,this); aggregations = new ArrayList(); agg_window = new Window(0, 300, 300,300,this); agg_window.strokeC = color(0); agg_window.fillC = 255; //main_window.add(agg_window); //println(agg_window.getX()); //println(agg_window.parentWindow.x); main_window.fillC = 255; curr_agg = new Aggregation(new Circle(0, 0, random(min_radius,max_radius))); curr_agg.smooth = true; curr_agg.xOffset = agg_window.w/2.0; curr_agg.yOffset = agg_window.h/2.0; //controls = new SlidingTab("Ctrs", 300,300,140,40,this); controls = new Window(0,0,300,35,this); advControls = new SlidingTab("Advanced Controls", 300, 335, 200,140, this); saved = new SlidingTab("Saved", 300, 480, width/3.0, height/6.0,this); //saved.isOpen = false; controls.fillC = color(100,170); SaveButton save = new SaveButton(5,20,40,10,"Next"); pause = new PauseButton(5,5,40,10,"Pause"); BackButton back = new BackButton(175,20,10,10,"<"); ForwardButton forward = new ForwardButton(190,20,10,10,">"); Label undoLabel = new Label(135,20,40,10,"Undo:"); undoLabel.fillC = -1; undoLabel.strokeC = -1; clear = new ClearButton(50, 20,40,10,"Clear"); clearAll = new ClearAllButton(235,20,55,10,"Clear All"); zoomOut = new ZoomButton(175, 5,10,10,"-",false); zoomIn = new ZoomButton(190, 5,10,10,"+",true); Label zoomLabel = new Label(135,5,40,10,"Zoom:"); zoomLabel.fillC = -1; zoomLabel.strokeC = -1; add_curr_b = new AddCurrButton(50,5,40,10,"Save"); help = new HelpButton(235,5,40,10,"Help"); controls.add(save); controls.add(pause); controls.add(forward); controls.add(back); controls.add(undoLabel); controls.add(clear); controls.add(clearAll); controls.add(help); controls.add(zoomIn); controls.add(zoomOut); controls.add(zoomLabel); probBox = new TextBox(45,10,35,10); Label stickingProbLabel = new Label(5, 10, 40, 10, "Prob:"); stickingProbLabel.fillC = color(70); stickingProbLabel.strokeC = -1; stickSlide = new ProbSlider(stick_prob,85,10,105,10); radSlide = new DiamSlider(max_agg_rad,85,25,105,10); minSlide = new MinRadSlider(min_radius,85,40,105,10); maxSlide = new MaxRadSlider(max_radius,85,55,105,10); stickSlide.fillC = color(160); radSlide.fillC = color(160); minSlide.fillC = color(160); maxSlide.fillC = color(160); radBox = new TextBox(45,25,35,10); radBox.text = str(max_agg_rad); Label radiusLabel = new Label(5,25,40,10, "Agg D:"); radiusLabel.fillC = color(70); radiusLabel.strokeC = -1; minBox = new TextBox(45,40,35,10); minBox.text = str(min_radius); Label minLabel = new Label(5,40,40,10, "Min R:"); minLabel.fillC = color(70); minLabel.strokeC = -1; maxBox = new TextBox(45,55,35,10); maxBox.text = str(max_radius); Label maxLabel = new Label(5,55,40,10, "Max R:"); maxLabel.fillC = color(70); maxLabel.strokeC = -1; ci = new CartInput(85,70); ri = new RadInput(140,70); Label forceLabel = new Label(25,75,55,20, "Force control:"); forceLabel.fillC = color(70); forceLabel.strokeC = -1; advControls.add(ci); advControls.add(probBox); advControls.add(radBox); advControls.add(stickingProbLabel); advControls.add(radiusLabel); advControls.add(maxLabel); advControls.add(minLabel); advControls.add(maxBox); advControls.add(minBox); advControls.add(ri); advControls.add(stickSlide); advControls.add(radSlide); advControls.add(minSlide); advControls.add(maxSlide); advControls.add(forceLabel); advControls.fillC = color(70); saved.fillC = color(150); controls.add(add_curr_b); agg_window.add(curr_agg); agg_window.add(controls); //main_window.add(curr_agg); //main_window.add(controls); //main_window.add(advControls); //main_window.add(saved); curr_mil = millis(); //gr = createGraphics(w,h,JAVA2D); myApp = this; add_button = new AddButton(0,0,40,14,"Save",0); // add_button.strokeC = color(200); add_button.visible = false; del = new DeleteButton(0,0,15,15,"X",0); del.visible = false; saved.add(del); controls.render(); advControls.render(); saved.render(); //controls.w =5; advControls.w =5; saved.w =5; //controls.isOpen =false; advControls.isOpen =false; saved.isOpen =false; } void draw() { //gr.beginDraw(); background(255); if(!paused) { addCircle(curr_agg); if(curr_agg.viewCircles.size() < curr_agg.circles.size()) { curr_agg.viewCircles.add(curr_agg.circles.get(curr_agg.viewCircles.size())); } if(sqrt(pow(curr_agg.bottom-curr_agg.top,2)+pow(curr_agg.right-curr_agg.left,2)) > max_agg_rad && curr_agg.viewCircles.size() > 1) { agg_window.renderables.remove(curr_agg); storeAgg(curr_agg); ++act; curr_agg = new Aggregation(new Circle(0, 0, random(min_radius,max_radius))); curr_agg.smooth = true; curr_agg.scale = ca_scale; curr_agg.xOffset = agg_window.w/2.0; curr_agg.yOffset = agg_window.h/2.0; agg_window.add(0,curr_agg); } } if(!probBox.active) { if(prev_prob_act) { float newP = float(probBox.text); if(newP > 0 && newP <= 1) { stick_prob = newP; } else { probBox.text = str(stick_prob); } } else { probBox.text = str(stick_prob); } } prev_prob_act = probBox.active; if(!radBox.active) { if(prev_d_act) { float newR = float(radBox.text); if(newR > 1) { max_agg_rad = newR; } else { radBox.text = str(max_agg_rad); } } else { radBox.text = str(max_agg_rad); } } prev_d_act = radBox.active; if(!minBox.active) { if(prev_min_act) { float newR = float(minBox.text); if(newR >= .5) { min_radius = newR; } else { minBox.text = str(min_radius); } } else { minBox.text = str(min_radius); } } prev_min_act = minBox.active; if(!maxBox.active) { if(prev_max_act){ float newR = float(maxBox.text); if(newR > 1) { max_radius = newR; } else { maxBox.text = str(max_radius); } } else { maxBox.text = str(max_radius); } } prev_max_act = maxBox.active; // println(curr_agg.viewCircles.size()); if(record) { beginRecord(PDF, "dla_circles-####.pdf"); } render(); if(record) { endRecord(); record = false; } if(aggregations.size() > 6) { Aggregation disp = (Aggregation) aggregations.get(display_index); if(mouseX < 10 && mouseY < 300 && (display_index >0 || disp.targetXOff+disp.centerX*disp.scale-width/12.0 <= -5)) { for(int i=0;i 0 && display_index > 2) display_index-=3; } if(mouseX > width-10 && mouseY < 300 && (display_index+6*3 < aggregations.size() || disp.targetXOff+disp.centerX*disp.scale-width/12.0 >= 5)) { for(int i=0;i 10 && mouseX < width-10) || mouseY > 300) { float offy = disp.targetXOff+disp.centerX*disp.scale-width/12.0; // println(offy); if(offy < -0.1) { for(int i=0;i 0.1) { for(int i=0;i (i/3)*(width/6.0) && mouseX < (i/3+1)*(width/6.0) && mouseY < (i%3+1)*(height/6.0) && mouseY > (i%3)*(height/6.0)) { curr_index = i+display_index; toSmooth.smooth = true; add_button.visible = true; add_button.x = (i/3)*(width/6.0); add_button.y = (i%3)*(height/6.0); add_button.indy = curr_index; } } } del.visible = false; if(saved_aggregations.size() >0) { Aggregation disp2 = (Aggregation) saved_aggregations.get(saved_disp_index); if(saved.w > 2 && saved_disp_index saved.getX() && mouseX< saved.getX()+width/6.0 && mouseY > saved.getY() && mouseY < saved.getY()+height/6.0) { del.indy = saved_disp_index; del.visible = true; del.x = disp2.xOffset+disp2.centerX*disp2.scale-width/12.0+width/6.0-15; del.y = 0; } if(saved.w > 2 && saved_disp_index saved.getX()+width/6.0 && mouseX< saved.getX()+2*width/6.0 && mouseY > saved.getY() && mouseY < saved.getY()+height/6.0) { del.indy = saved_disp_index+1; del.visible = true; del.x = disp2.xOffset+disp2.centerX*disp2.scale-width/12.0+2*width/6.0-15; del.y = 0; } if(mouseX < saved.getX()+10 && mouseY < saved.getY()+saved.h && mouseY > saved.getY() && (saved_disp_index >0 || disp2.targetXOff+disp2.centerX*disp2.scale-width/12.0 <= -5)) { for(int i=0;i 0 && saved_disp_index > 0) --saved_disp_index; } if(mouseX > saved.getX()+saved.w-10 && mouseY < saved.getY()+saved.h && mouseY > saved.getY() && (saved_disp_index+2 < saved_aggregations.size() || disp2.targetXOff+disp2.centerX*disp2.scale-width/12.0 >= 5)) { for(int i=0;i0) { Aggregation disp = (Aggregation) aggregations.get(display_index); if(disp.xOffset+disp.centerX*disp.scale-width/12.0 < 0) addnext = 1; if(disp.xOffset+disp.centerX*disp.scale-width/12.0 > 0) addprev = 1; } int start = max(0,display_index-addprev*3); int end = min(display_index+(6+addnext)*3,aggregations.size()); for(int i=0;i 6*3) { Aggregation last = (Aggregation) aggregations.get(aggregations.size()-1); if(last.targetXOff != last.xOffset || last.targetYOff != last.yOffset || last.targetScale != last.scale) { minus =1; } } for(int i=end;i 6*3) { Aggregation last = (Aggregation) aggregations.get(aggregations.size()-1); if(last.targetXOff != last.xOffset || last.targetYOff != last.yOffset || last.targetScale != last.scale) { last.render(); } } controls.render(); advControls.render(); saved.render(); add_button.render(); agg_window.render(); if(instructions.visible) { fill(0,150); noStroke(); rect(0,0,width,height); instructions.render(); } } void addCircle(Aggregation a) { curr_mil = millis(); boolean stuck = false; while(true) { if(!paused && millis()-curr_mil > 100) return; //c.x = c.x+random(-max_inc, max_inc); //c.y = c.y+random(-max_inc,max_inc); if(distance(a.current_circle, a.release_circle) 0) { Circle first = (Circle) a.viewCircles.get(0); float cent_dist = sqrt((a.current_circle.x-first.x)*(a.current_circle.x-first.x)+(a.current_circle.y-first.y)*(a.current_circle.y-first.y)); float x_comp_rad = polar_force_r*max_inc*(a.current_circle.x-first.x)/cent_dist; float y_comp_rad = polar_force_r*max_inc*(a.current_circle.y-first.y)/cent_dist; float x_comp_ang = polar_force_a*max_inc*(-a.current_circle.y+first.y)/cent_dist; float y_comp_ang = polar_force_a*max_inc*(a.current_circle.x-first.x)/cent_dist; a.current_circle.x += x_comp_rad+x_comp_ang; a.current_circle.y += y_comp_rad+y_comp_ang; } /*float in_x = (-c.x+width/2.0)/sqrt(pow(c.x-w/2.0,2)+pow(c.y-h/2.0,2)); float in_y = (-c.y+height/2.0)/sqrt(pow(c.x-w/2.0,2)+pow(c.y-h/2.0,2)); float tan_x = in_y; float tan_y = -in_x; c.x = c.x+tan_x*0.9+in_x*0.1; c.y = c.y+tan_y*0.9+in_y*0.1; c.x += random(-0.1,0.1); c.y += random(-0.1,0.1); */ Circle in = intersect(a.current_circle,a); if(in.radius != -99){ if(distance(in, a.current_circle) > (in.radius+a.current_circle.radius)*.75) { if(random(1.0) < stick_prob) { stuck = true; a.circles.add(a.current_circle); a.release_circle.x = (a.release_circle.x*(a.circles.size()-1)+a.current_circle.x)/a.circles.size(); a.release_circle.y = (a.release_circle.y*(a.circles.size()-1)+a.current_circle.y)/a.circles.size(); float max_dist = 0; curr_agg.top = 9999; curr_agg.bottom = -9999; curr_agg.left = 9999; curr_agg.right = -9999; for(int i=0;i a.release_circle.radius*5) { float theta = random(TWO_PI); a.current_circle.x = a.release_circle.x+a.release_circle.radius*cos(theta); a.current_circle.y = a.release_circle.y+a.release_circle.radius*sin(theta); } //if(c.x < 0) c.x = w; //if(c.y < 0) c.y = h; //if(c.x > w) c.x = 0; //if(c.y > h) c.y = h; } /*circles.add(c); release_circle.x = (release_circle.x*(circles.size()-1)+c.x)/circles.size(); release_circle.y = (release_circle.y*(circles.size()-1)+c.y)/circles.size(); float max_dist = 0; for(int i=0;i 0) { Aggregation disp = (Aggregation) aggregations.get(display_index); start_pos = disp.targetXOff+disp.centerX*disp.scale-width/12.0; } if(aggregations.size() >= display_index+6*3 && mouseY > 300 ) { display_index+=3; for(int i=0;i right) right = c.x; if(c.y < top) { top = c.y; } else if(c.y > bottom) bottom = c.y; } right += max_radius; bottom += max_radius; left -= max_radius; top -= max_radius; a.left = left; a.right = right; centerX = (left+right)/2.0; centerY = (bottom+top)/2.0; a.centerX = centerX; a.fillC = color(150); a.strokeC = color(150); a.targetScale = min((width/6.0)/(right-left), (height/6.0)/(bottom-top)); a.targetScale *= .9; float targetX = ((aggregations.size()-display_index)/3)*width/6.0+width/12.0+start_pos; float targetY = ((aggregations.size()-display_index)%3)*height/6.0+height/12.0; a.targetXOff = targetX-centerX*a.targetScale; a.targetYOff = targetY-centerY*a.targetScale; a.xOffset = a.xOffset+agg_window.x; a.yOffset = a.yOffset+agg_window.y; a.parentWindow=null; aggregations.add(a); } void writeToServer(Aggregation a) { //if (!online) return; //String id = getParameter("osCsid"); String id="1"; if (online) id = getParameter("osCsid"); String message = id+ ":" + "ADD"; //myClient.write("STARTTRANSFER:"); for(int i=0;i 5) { xOffset = (targetXOff+xOffset*3)/4.0; } else if(targetXOff != -99999) xOffset = targetXOff; if(targetYOff != -99999 && abs(targetYOff - yOffset) > 5) { yOffset = (targetYOff+yOffset*3)/4.0; } else if(targetYOff != -99999) yOffset = targetYOff; if(targetScale != -99999 && abs(targetScale-scale) > .1) { scale = (targetScale+scale*3)/4.0; } else if(targetScale != -99999) scale = targetScale; /*if(abs(targetFillC-fillC) > 5) { fillC = (targetFillC+fillC*3)/4; } else if(targetFillC != -1) fillC = targetFillC; if(abs(targetStrokeC-strokeC) > 5) { fillC = (targetStrokeC+strokeC*3)/4; } else if(targetStrokeC != -1) strokeC = targetStrokeC; */ if(!visible) return; PGraphics wg = myApp.g; if (parentWindow != null) wg = parentWindow.pg; if (smooth) wg.smooth(); else wg.noSmooth(); float offX = 0; float offY = 0; //if(parentWindow != null) { offX = this.xOffset; offY = this.yOffset; //} wg.fill(fillC); //wg.smooth(); wg.stroke(strokeC); if(isSaved) { wg.fill(blendColor(fillC,color(0), BLEND)); wg.stroke(blendColor(strokeC,color(0), BLEND)); } for(int i=0; i< viewCircles.size();++i) { Circle c = (Circle) viewCircles.get(i); wg.ellipse(scale*c.x+offX,scale*c.y+offY,scale*c.radius*2, scale*c.radius*2); //println(c.x + " " + c.y + " " + c.radius); } wg.noSmooth(); } } Circle intersect(Circle c, Aggregation agg) { float least = 99; Circle re = NUL; for(int i = 0; i < agg.circles.size(); i++) { Circle c2 = (Circle) agg.circles.get(i); if(intersect(c,c2)) { if(sqrt(pow(c.x-c2.x,2)+pow(c.y-c2.y,2)) 0) { w-= ceil(w*.25); pg.resize(ceil(w),ceil(h)); } if(w <2) { w = 0; pg.resize(1,ceil(h)); } } wg.fill(fillC); wg.stroke(strokeC); wg.rect(this.getX(), this.getY(),w,h); wg.fill(0); wg.stroke(0); wg.rect(this.getX()+w, this.getY(),14,h); wg.stroke(210); wg.fill(210); wg.textFont(bFont, 8); wg.textAlign(LEFT); wg.translate(this.getX()+w+3, this.getY()+2); wg.rotate(PI/2.0); wg.text(name, 0,0); wg.rotate(-PI/2.0); wg.translate(-this.getX()-w-3, -this.getY()-2); pg.beginDraw(); //pg.smooth(); //pg.background(fillC); for(int i=0; i tempX && xPos < tempX+14 && yPos > getY() && yPos < getY()+h) { isOpen = !isOpen; //if(isOpen) { // w = tempW; //} else { // w = 0; //} } break; } } } public class TextBox extends Renderable { float x,y, h,w; String text; boolean active; int position = 0; TextBox(float _x, float _y, float _w, float _h) { x = _x; y = _y; w = _w; h = _h; text = ""; active = false; strokeC = color(0); fillC = color(200); registerMouseEvent(this); registerKeyEvent(this); } void mouseEvent(MouseEvent e) { int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { active = true; position = text.length(); } else { active = false; } break; } } void keyEvent(KeyEvent e) { if(!active || parentWindow.w == 0) return; int code = e.getKeyCode(); switch(e.getID()) { case KeyEvent.KEY_TYPED: char iC = e.getKeyChar(); if(iC != KeyEvent.CHAR_UNDEFINED && int(iC) != 8) { if(textWidth(text+e.getKeyChar()) < w-2) { //println(iC); text = text.substring(0,position)+ iC+text.substring(position, text.length()); ++position; } } break; case KeyEvent.KEY_PRESSED: if(code == KeyEvent.VK_BACK_SPACE && text.length() > 0 && position > 0) { text = text.substring(0,position-1)+text.substring(position,text.length()); --position; } else if(code == KeyEvent.VK_ENTER) { active = false; } else if(code == KeyEvent.VK_LEFT) { if(position >0) --position; } else if(code == KeyEvent.VK_RIGHT) { if(position 0) && xPos > poffX+x && xPos < poffX+x+w && yPos > poffY+y && yPos < poffY+y+h) { fillC = blendColor(fillC, color(180), BLEND); } else { fillC = tempFill; } break; } } void render() { if(!visible) return; PGraphics wg = myApp.g; if(parentWindow != null) wg = parentWindow.pg; wg.noFill(); if(fillC != -1) wg.fill(fillC); wg.noStroke(); if(strokeC != -1) wg.stroke(strokeC); wg.rect(x,y,w,h); wg.fill(255); wg.stroke(255); wg.textFont(bFont,8); wg.textAlign(CENTER); wg.text(name, x,y+3,w,h); } } public class PauseButton extends Button { PauseButton(float _x, float _y, float _w, float _h, String _name) { super(_x,_y,_w,_h,_name); } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { if(paused) { paused=false; name = "Pause"; } else { paused=true; name = "Play"; } } break; } } } public class ForwardButton extends Button { ForwardButton(float _x, float _y, float _w, float _h, String _name) { super(_x,_y,_w,_h,_name); } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { if(!paused) { paused=true; pause.name = "Play"; } if(historyStack.size() > 0) { //pop off stack Circle c = (Circle) historyStack.get(historyStack.size()-1); historyStack.remove(historyStack.size()-1); //push curr_agg.viewCircles.add(c); } else if(curr_agg.viewCircles.size() < curr_agg.circles.size()) { curr_agg.viewCircles.add(curr_agg.circles.get(curr_agg.viewCircles.size())); } else { addCircle(curr_agg); curr_agg.viewCircles.add(curr_agg.circles.get(curr_agg.viewCircles.size())); } } break; } } } public class BackButton extends Button { BackButton(float _x, float _y, float _w, float _h, String _name) { super(_x,_y,_w,_h,_name); } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { if(!paused) { paused=true; pause.name = "Play"; } if(curr_agg.viewCircles.size() > 0) { //pop off of circles Circle c = (Circle) curr_agg.viewCircles.get(curr_agg.viewCircles.size()-1); curr_agg.viewCircles.remove(curr_agg.viewCircles.size()-1); //push historyStack.add(c); } } } } } public class SaveButton extends Button { SaveButton(float _x, float _y, float _w, float _h, String _name) { super(_x,_y,_w,_h,_name); } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && curr_agg.viewCircles.size() > 1 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { agg_window.renderables.remove(curr_agg); /*curr_agg.xOffset = (main_window.w/6.0)*(act%6)+90; curr_agg.yOffset = int(act/6)*(main_window.w/6.0)+90; curr_agg.scale = (main_window.w/6.0)/curr_agg.release_circle.radius; curr_agg.fillC = color(150); curr_agg.strokeC = color(150); if(!connected) { try{ Socket sock = new Socket("localhost", 5204); myClient = new Client(app, sock); connected = true; } catch (Exception ex) { } } */ curr_agg.smooth = false; storeAgg(curr_agg); //main_window.add(0,curr_agg); ++act; curr_agg = new Aggregation(new Circle(0, 0, random(min_radius,max_radius))); curr_agg.scale = ca_scale; curr_agg.smooth = true; curr_agg.xOffset = agg_window.w/2.0; curr_agg.yOffset = agg_window.h/2.0; agg_window.add(0,curr_agg); } } } } public class ClearButton extends Button { ClearButton(float _x, float _y, float _w, float _h, String _name) { super(_x,_y,_w,_h,_name); } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { curr_agg.circles.clear(); curr_agg.viewCircles.clear(); curr_agg.circles.add(new Circle(0,0, random(min_radius,max_radius))); } } } } public class ZoomButton extends Button { boolean goIn; ZoomButton(float _x, float _y, float _w, float _h, String _name, boolean _in) { super(_x,_y,_w,_h,_name); goIn = _in; } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { if(goIn) {curr_agg.scale *= 1.1; ca_scale *= 1.1;} else {curr_agg.scale *= 0.9; ca_scale *= .9;} } } } } public class AddButton extends Button { int indy; AddButton(float _x, float _y, float _w, float _h, String _name, int _index) { super(_x,_y,_w,_h,_name); indy = _index; } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); float poffX = 0; float poffY = 0; if(parentWindow != null) { poffX = parentWindow.getX(); poffY = parentWindow.getY(); } switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if ((parentWindow == null || parentWindow.w > 0) && xPos > poffX+x && xPos < poffX+x+w && yPos > poffY+y && yPos < poffY+y+h) { Aggregation this_a = (Aggregation) aggregations.get(indy); if(this_a.isSaved) return; Aggregation toSave = new Aggregation(this_a); toSave.smooth = false; int d_ind = indy-display_index; if(saved_aggregations.size() > 1) { for(int i=0;i 0) { Aggregation last = (Aggregation) saved_aggregations.get(saved_aggregations.size()-1); toSave.targetXOff = last.targetXOff+last.centerX*last.scale-width/12-(toSave.centerX*toSave.scale-width/12.0)+width/6.0; } else { toSave.targetXOff = -(toSave.centerX*toSave.scale-width/12.0); } toSave.xOffset = toSave.targetXOff+2*width/6.0; toSave.yOffset = toSave.yOffset-(d_ind%3)*height/6.0; toSave.targetYOff = toSave.yOffset; this_a.isSaved=true; toSave.fillC = color(70); toSave.strokeC = color(70); saved_aggregations.add(toSave); saved.add(toSave); //if(online) writeToServer((Aggregation) aggregations.get(indy)); else println("NOT SAVED. NOT CONNECTED TO SERVER"); writeToServer((Aggregation) aggregations.get(indy)); } } } } public class AddCurrButton extends Button { AddCurrButton(float _x, float _y, float _w, float _h, String _name) { super(_x,_y,_w,_h,_name); } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); float poffX = 0; float poffY = 0; if(parentWindow != null) { poffX = parentWindow.getX(); poffY = parentWindow.getY(); } switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if ((parentWindow == null || parentWindow.w > 0) && xPos > poffX+x && xPos < poffX+x+w && yPos > poffY+y && yPos < poffY+y+h) { agg_window.renderables.remove(curr_agg); storeAgg(curr_agg); //main_window.add(0,curr_agg); ++act; curr_agg = new Aggregation(new Circle(0, 0, random(min_radius,max_radius))); curr_agg.smooth = true; curr_agg.scale = ca_scale; curr_agg.xOffset = agg_window.w/2.0; curr_agg.yOffset = agg_window.h/2.0; agg_window.add(0,curr_agg); Aggregation this_a = (Aggregation) aggregations.get(aggregations.size()-1); if(this_a.isSaved) return; Aggregation toSave = new Aggregation(this_a); toSave.smooth = false; int d_ind = aggregations.size()-1-display_index; if(saved_aggregations.size() > 1) { for(int i=0;i 0) { Aggregation last = (Aggregation) saved_aggregations.get(saved_aggregations.size()-1); toSave.targetXOff = last.targetXOff+last.centerX*last.targetScale-width/12-(toSave.centerX*toSave.targetScale-width/12.0)+width/6.0; } else { toSave.targetXOff = -(toSave.centerX*toSave.targetScale-width/12.0); } toSave.xOffset = toSave.targetXOff+2*width/6.0; toSave.yOffset = toSave.targetYOff-(d_ind%3)*height/6.0; toSave.targetYOff = toSave.yOffset; this_a.isSaved=true; toSave.fillC = color(70); toSave.strokeC = color(70); saved_aggregations.add(toSave); saved.add(toSave); //if(online) writeToServer((Aggregation) aggregations.get(aggregations.size()-1)); else println("NOT SAVED. NOT CONNECTED TO SERVER"); writeToServer((Aggregation) aggregations.get(aggregations.size()-1)); } } } } public class DeleteButton extends Button { int indy; DeleteButton(float _x, float _y, float _w, float _h, String _name, int _index) { super(_x,_y,_w,_h,_name); indy = _index; } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); float poffX = 0; float poffY = 0; if(parentWindow != null) { poffX = parentWindow.getX(); poffY = parentWindow.getY(); } switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if ((parentWindow == null || parentWindow.w > 0) && del.visible && xPos > poffX+x && xPos < poffX+x+w && yPos > poffY+y && yPos < poffY+y+h) { //println(saved_aggregations.size()); Aggregation this_a = (Aggregation) saved_aggregations.get(indy); for(int i=0;isaved_disp_index+2) sa.visible = false; } } else { if(saved_disp_index!=0)--saved_disp_index; for(int i=indy-1;i>=0;--i) { Aggregation sa = (Aggregation) saved_aggregations.get(i); sa.targetXOff += width/6.0; sa.visible = true; if(isaved_disp_index+2) sa.visible = false; } } saved_aggregations.remove(indy); saved.renderables.remove(this_a); //if(online) deleteFromServer(this_a); deleteFromServer(this_a); } } } } public class ClearAllButton extends Button { ClearAllButton(float _x, float _y, float _w, float _h, String _name) { super(_x,_y,_w,_h,_name); } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); float poffX = 0; float poffY = 0; if(parentWindow != null) { poffX = parentWindow.getX(); poffY = parentWindow.getY(); } switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if ((parentWindow == null || parentWindow.w > 0) && xPos > poffX+x && xPos < poffX+x+w && yPos > poffY+y && yPos < poffY+y+h) { aggregations = new ArrayList(); display_index = 0; } } } } public class HelpButton extends Button { HelpButton(float _x, float _y, float _w, float _h, String _name) { super(_x,_y,_w,_h,_name); } void mouseEvent(MouseEvent e) { super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); float poffX = 0; float poffY = 0; if(parentWindow != null) { poffX = parentWindow.getX(); poffY = parentWindow.getY(); } switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if ((parentWindow == null || parentWindow.w > 0) && xPos > poffX+x && xPos < poffX+x+w && yPos > poffY+y && yPos < poffY+y+h) { instructions.visible = true; paused = true; pause.name = "Play"; } } } } public class CartInput extends Renderable { float h,w,x,y; CartInput(float _x, float _y) { x = _x; y = _y; h = 50; w = 50; registerMouseEvent(this); } void render() { PGraphics wg = parentWindow.pg; wg.noStroke(); wg.fill(200); wg.rect(x,y,w,h); wg.stroke(140); wg.line(x+2,y+h/2.0,x+w-2,y+h/2.0); wg.line(x+w/2.0,y+2,x+w/2.0,y+h-2); wg.stroke(30); wg.fill(30); wg.ellipse(x+w/2.0,y+h/2.0,3,3); if (cart_force_x != 0 || cart_force_y != 0) { wg.smooth(); wg.strokeWeight(2); wg.line(x+w/2.0, y+h/2.0, x+w/2.0+cart_force_x*w/2.0,y+h/2.0+cart_force_y*h/2.0); float force_l = sqrt(pow(cart_force_x,2)+pow(cart_force_y,2)); float arr_vx = -cart_force_x/force_l*sqrt(2.0)/2.0*5+cart_force_y/force_l*sqrt(2.0)/2.0*5; float arr_vy = -cart_force_x/force_l*sqrt(2.0)/2.0*5-cart_force_y/force_l*sqrt(2.0)/2.0*5; float arr_vx2 = -cart_force_x/force_l*sqrt(2.0)/2.0*5-cart_force_y/force_l*sqrt(2.0)/2.0*5; float arr_vy2 = cart_force_x/force_l*sqrt(2.0)/2.0*5-cart_force_y/force_l*sqrt(2.0)/2.0*5; wg.line(x+w/2.0+cart_force_x*w/2.0,y+h/2.0+cart_force_y*h/2.0,x+w/2.0+cart_force_x*w/2.0+arr_vx,y+h/2.0+cart_force_y*h/2.0+arr_vy); wg.line(x+w/2.0+cart_force_x*w/2.0,y+h/2.0+cart_force_y*h/2.0,x+w/2.0+cart_force_x*w/2.0+arr_vx2,y+h/2.0+cart_force_y*h/2.0+arr_vy2); wg.strokeWeight(1); } wg.fill(255); wg.textFont(bFont); wg.text("Cartesian", x-2,y+h+10); } void mouseEvent(MouseEvent e) { //super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { cart_force_x =(mouseX-parentWindow.getX()-x-w/2.0)/w*2.0; cart_force_y =(mouseY-parentWindow.getY()-y-h/2.0)/h*2.0; } } } } public class RadInput extends Renderable { float h,w,x,y; RadInput(float _x, float _y) { x = _x; y = _y; h = 50; w = 50; registerMouseEvent(this); } void render() { PGraphics wg = parentWindow.pg; wg.smooth(); wg.noStroke(); wg.fill(200); wg.rect(x,y,w,h); wg.stroke(140); //wg.line(x+2,y+h/2.0,x+w-2,y+h/2.0); //wg.line(x+w/2.0,y+2,x+w/2.0,y+h-2); wg.noFill(); wg.ellipse(x+w/2.0,y+h/2.0,w/2.0,h/2.0); wg.stroke(30); wg.fill(30); wg.ellipse(x+w/2.0,y+h/4.0,3,3); if (polar_force_r != 0 || polar_force_a != 0) { wg.strokeWeight(2); wg.line(x+w/2.0, y+h/4.0, x+w/2.0+polar_force_a*w/4.0,y+h/4.0-polar_force_r*h/4.0); float force_l = sqrt(pow(polar_force_r,2)+pow(polar_force_a,2)); float arr_vx = -polar_force_a/force_l*sqrt(2.0)/2.0*5-polar_force_r/force_l*sqrt(2.0)/2.0*5; float arr_vy = -polar_force_a/force_l*sqrt(2.0)/2.0*5+polar_force_r/force_l*sqrt(2.0)/2.0*5; float arr_vx2 = -polar_force_a/force_l*sqrt(2.0)/2.0*5+polar_force_r/force_l*sqrt(2.0)/2.0*5; float arr_vy2 = polar_force_a/force_l*sqrt(2.0)/2.0*5+polar_force_r/force_l*sqrt(2.0)/2.0*5; wg.line(x+w/2.0+polar_force_a*w/4.0,y+h/4.0-polar_force_r*h/4.0,x+w/2.0+polar_force_a*w/4.0+arr_vx,y+h/4.0-polar_force_r*h/4.0+arr_vy); wg.line(x+w/2.0+polar_force_a*w/4.0,y+h/4.0-polar_force_r*h/4.0,x+w/2.0+polar_force_a*w/4.0+arr_vx2,y+h/4.0-polar_force_r*h/4.0+arr_vy2); wg.strokeWeight(1); } wg.fill(255); wg.text("Polar", x+7,y+h+10); } void mouseEvent(MouseEvent e) { //super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { polar_force_a =(mouseX-parentWindow.getX()-x-w/2.0)/w*4.0; polar_force_r = -(mouseY-parentWindow.getY()-y-h/4.0)/h*4.0; } } } } public class Slider extends Renderable { float h,w,x,y,n; float max = 1; Slider(float _n, float _x, float _y, float _w, float _h) { n = _n; x = _x; y = _y; w = _w; h = _h; registerMouseEvent(this); } void render() { PGraphics wg = parentWindow.pg; if (fillC == -1) { wg.noFill(); } else { wg.fill(fillC); } if (strokeC == -1) { wg.noStroke(); } else { wg.stroke(strokeC); } wg.rect(x,y,w,h); wg.stroke(40); wg.line(x,y+h/2.0,x+w,y+h/2.0); float slider_x = x+w*n/max; wg.line(slider_x,y,slider_x,y+h); } void mouseEvent(MouseEvent e) { //super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { n =((mouseX-parentWindow.getX()-x)/w*max); } } } } public class ProbSlider extends Slider { ProbSlider(float _n, float _x, float _y, float _w, float _h) { super(_n,_x,_y,_w,_h); } void render() { super.render(); n = stick_prob; } void mouseEvent(MouseEvent e) { //super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { n =((mouseX-parentWindow.getX()-x)/w*max); stick_prob = n; } } } } public class DiamSlider extends Slider { DiamSlider(float _n, float _x, float _y, float _w, float _h) { super(_n,_x,_y,_w,_h); max = 500; } void render() { super.render(); n = max_agg_rad; } void mouseEvent(MouseEvent e) { //super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { n =((mouseX-parentWindow.getX()-x)/w*max); max_agg_rad = n; } } } } public class MaxRadSlider extends Slider { MaxRadSlider(float _n, float _x, float _y, float _w, float _h) { super(_n,_x,_y,_w,_h); max = 15; } void render() { super.render(); n = max_radius; } void mouseEvent(MouseEvent e) { //super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { n =max(((mouseX-parentWindow.getX()-x)/w*max),min_radius); max_radius = n; } } } } public class MinRadSlider extends Slider { MinRadSlider(float _n, float _x, float _y, float _w, float _h) { super(_n,_x,_y,_w,_h); max = 15; } void render() { super.render(); n = min_radius; } void mouseEvent(MouseEvent e) { //super.mouseEvent(e); int xPos = e.getX(); int yPos = e.getY(); switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: if (parentWindow.w > 0 && xPos > parentWindow.getX()+x && xPos < parentWindow.getX()+x+w && yPos > parentWindow.getY()+y && yPos < parentWindow.getY()+y+h) { n =min(((mouseX-parentWindow.getX()-x)/w*max),max_radius); min_radius = n; } } } } class Renderable { Window parentWindow; color fillC; color strokeC; float xOffset = 0; float yOffset = 0; float scale = 1; float targetXOff = -99999; float targetYOff = -99999; float targetScale = -99999; color targetFillC = -1; color targetStrokeC = -1; boolean visible = true; boolean smooth = false; Renderable() { parentWindow = null; fillC = color(0); strokeC = color(0); } float getX() { if(parentWindow == null) return 0; return parentWindow.getX()+xOffset; } float getY() { if(parentWindow == null) return 0; return parentWindow.getY()+yOffset; } void render() { } } public class POSTRequest extends Thread { String content; String urlString; String output = ""; POSTRequest(String _c, String _u) { super(); content = _c; urlString = _u; } void start() { super.start(); } void run() { try{ URL url; HttpURLConnection urlConn; DataOutputStream printout; // DataInputStream input; // URL of CGI-Bin script. url = new URL (urlString); // URL connection channel. urlConn = (HttpURLConnection) url.openConnection(); // Let the run-time system (RTS) know that we want input. urlConn.setDoOutput (true); urlConn.setDoInput(true); urlConn.setRequestMethod("POST"); // No caching, we want the real thing. // urlConn.setUseCaches (false); // Specify the content type. // urlConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // Send POST output. printout = new DataOutputStream (urlConn.getOutputStream ()); printout.writeBytes (content); printout.flush (); printout.close (); //println(message); BufferedReader in = new BufferedReader( new InputStreamReader( urlConn.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { output += inputLine; println(inputLine); } in.close(); } catch (Exception e) { exit(); } } }