/* Example application using Force Directed Graph Layout. Click on blue nodes to connect them to the currently selected node. Click on red nodes to expand the graph with a random subtree starting on the currently selected node. Hit any key to add random nodes. Sean McCullough http://www.cricketschirping.com 26. Feb 2007 */ import traer.physics.*; import traer.animation.*; Graph g; ParticleSystem physics; Smoother3D centroid; String GROW = "+"; String CONNECT = "-"; PFont font; void setup() { size( 400, 400 ); smooth(); fill( 0 ); frameRate( 24 ); ellipseMode( CENTER ); font = loadFont("CourierNew36.vlw"); physics = new ParticleSystem( 0, 0.07 ); centroid = new Smoother3D( 0.8 ); centroid.setValue( 0, 0, 1.0 ); g = new Graph(physics); Node anchor = g.newNode(" "); anchor.getParticle().makeFixed(); g.setSelectedNode(anchor); generateRandomTree(anchor,4,4); } void generateRandomTree(Node root, int depth, int maxC) { System.out.println("grt: " + depth); if (depth <= 0) return; int c = (int)(Math.random()*maxC)+1; Node n = null; while (c-- > 0) { n = g.newNode(root, ""+g.getNodes().size()); n.setLabel((Math.random()>0.5 ? GROW : CONNECT)); n.getParticle().moveTo(root.getParticle().position().x()+(0.01-(float)Math.random()*0.05), root.getParticle().position().y()+(0.01-(float)Math.random()*0.05), 0.0); System.out.println("node"); generateRandomTree(n, depth-1, maxC); } if (n != null) g.setSelectedNode(n); } void keyPressed() { growRandom(); } void growRandom() { if (g.getSelectedNode() != null) { generateRandomTree(g.getSelectedNode(),1,4); } else { Node anchor = g.newNode(" "); anchor.getParticle().makeFixed(); g.setSelectedNode(anchor); generateRandomTree(anchor,3,4); } } void draw() { if (g.getNodes().size() == 0){ growRandom(); } physics.advanceTime( 0.5 ); updateCentroid(); centroid.tick(); background( 255 ); translate( width/2 , height/2 ); scale( min(centroid.z(),1.0) ); translate( -centroid.x(), -centroid.y() ); g.draw(); } int mx() { return (int)((mouseX-width/2)/min(centroid.z(),1.0) + centroid.x()); } int my() { return (int)((mouseY-height/2)/min(centroid.z(),1.0) + centroid.y()); } void mousePressed() { ArrayList nodes = g.getNodes(); for(int i=0; i deltaX ) centroid.setTarget( xMin + 0.5*deltaX, yMin +0.5*deltaY, height/(deltaY+50) ); else centroid.setTarget( xMin + 0.5*deltaX, yMin +0.5*deltaY, width/(deltaX+50) ); }