Created
April 23, 2011 16:05
-
-
Save mvaz/938737 to your computer and use it in GitHub Desktop.
FisicaGraph
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package net.mvaz.examples.visualization.processingparis; | |
| import java.util.ArrayList; | |
| import java.util.Calendar; | |
| import java.util.HashMap; | |
| import java.util.HashSet; | |
| import java.util.List; | |
| import java.util.Map; | |
| import java.util.Set; | |
| import org.apache.commons.lang.Validate; | |
| import processing.core.PApplet; | |
| import fisica.FBody; | |
| import fisica.FCircle; | |
| import fisica.FDistanceJoint; | |
| import fisica.FJoint; | |
| import fisica.FWorld; | |
| import fisica.Fisica; | |
| public class FisicaGraph extends PApplet { | |
| private static final long serialVersionUID = 3798824130918332655L; | |
| // Reference to physics world | |
| FWorld physics; | |
| // how many nodes on each side of the mesh | |
| int nodeCount = 11; | |
| float bigNodeDiameter = 30; | |
| float smallNodeDiameter = 10; | |
| int numberBigNodes = 30; | |
| int numberSmallNodes = 350; | |
| List<FCircle> bigNodes; | |
| List<FBody> smallNodes; | |
| Map<FBody, Set<FBody>> connections; | |
| // dragged node | |
| FBody selectedNode = null; | |
| float nodeDiameter = 16; | |
| int t = 0; | |
| public void setup() { | |
| size(1200, 800); | |
| smooth(); | |
| noStroke(); | |
| // Initialize the physics | |
| Fisica.init(this); | |
| physics = new FWorld(); | |
| physics.setGravity(0, 0); | |
| physics.setEdges(this, 0); | |
| generateGraph(); | |
| // frameRate(10); | |
| } | |
| public void draw() { | |
| t++; | |
| physics.step(); | |
| // background( color(140, 170, 193) ); | |
| background(255); | |
| updateBigNodes(); | |
| physics.draw(); | |
| } | |
| private void updateBigNodes() { | |
| noiseDetail(8,(float) 0.65); | |
| for (int i=0; i<bigNodes.size(); i++) { | |
| FCircle node = bigNodes.get(i); | |
| float n = map( noise( i * 101, (float) (t/10.0)), 0, 1, 1, 254); | |
| float n2 = map( noise( i * 90, (float) (t/1000.0)), 0, 1, 1, 254); | |
| node.setStrokeColor(color(n, i, 100)); | |
| node.setStrokeWeight(2 + map(n2, 0, 255, 10, 40)); | |
| List<FJoint> springs = node.getJoints(); | |
| for (FJoint spring: springs) { | |
| if (!(spring instanceof fisica.FDistanceJoint)) continue; | |
| FDistanceJoint j = (FDistanceJoint) spring; | |
| float currentDistance = dist(j.getBody1().getX(), j.getBody1().getY(), j.getBody2().getX(), j.getBody2().getY()); | |
| float d = 440; | |
| if (!( smallNodes.contains(j.getBody1()) || smallNodes.contains(j.getBody2()) )) { | |
| float mynoise = map( noise(i*13, (float)(t/7.0)), 0, 1, (float)(-.2), (float)0.2); | |
| j.setLength( d * ( 1 + mynoise ) ); | |
| } | |
| } | |
| } | |
| } | |
| private void generateGraph() { | |
| bigNodes = new ArrayList<FCircle>(); | |
| smallNodes = new ArrayList<FBody>(); | |
| connections = new HashMap<FBody, Set<FBody>>(); | |
| for (int i=0; i < numberBigNodes; i++) { | |
| FCircle bigNode = createBigNode( random( 50, width-50), random(50, height-50)); | |
| addBigNode( bigNode ); | |
| } | |
| for (int i=0; i < numberBigNodes; i++) { | |
| for (int j=0; j < i ; j++) | |
| physics.add( createRepulsion( bigNodes.get(i), bigNodes.get(j), (float) 1.8)); | |
| } | |
| for (int i = 0; i < numberSmallNodes ; i++) { | |
| FCircle smallNode = createSmallNode( random( 50, width-50), random(50, height-50) ); | |
| addSmallNode(smallNode); | |
| connectSmallNodeToRandomBigNode(smallNode); | |
| } | |
| for (Map.Entry<FBody,Set<FBody>> s: connections.entrySet()) { | |
| List<FBody> smallNodeList = new ArrayList<FBody>( s.getValue() ); | |
| for (int i=0; i < smallNodeList.size() ; i++) | |
| for (int j=0; j < i; j++) { | |
| physics.add(createRepulsion(smallNodeList.get(i), smallNodeList.get(j), (float) .9)); | |
| } | |
| } | |
| } | |
| private void addBigNode(FCircle bigNode) { | |
| physics.add(bigNode); | |
| bigNodes.add(bigNode); | |
| connections.put( bigNode, new HashSet<FBody>()); | |
| } | |
| private FCircle createBigNode(float x, float y) { | |
| FCircle bigNode = new FCircle(bigNodeDiameter); | |
| bigNode.setPosition( x, y); | |
| initFCircle(bigNode); | |
| return bigNode; | |
| } | |
| private FCircle createSmallNode(float x, float y) { | |
| FCircle smallNode = new FCircle(smallNodeDiameter); | |
| smallNode.setPosition(x, y); | |
| initFCircle(smallNode); | |
| return smallNode; | |
| } | |
| private void connectSmallNodeToRandomBigNode(FBody smallNode) { | |
| FBody bigNode = getRandomBigNode(); | |
| physics.add( createSpring(bigNode, smallNode)); | |
| connections.get(bigNode).add(smallNode); | |
| } | |
| private void addSmallNode(FBody smallNode) { | |
| physics.add(smallNode); | |
| smallNodes.add(smallNode); | |
| } | |
| private FBody getRandomBigNode() { | |
| Validate.notNull(bigNodes); | |
| Validate.notEmpty(bigNodes); | |
| int randomIndex = round( random(0, (float) (bigNodes.size() - 0.51)) ); | |
| return bigNodes.get(randomIndex); | |
| } | |
| FDistanceJoint createSpring(FBody bigNode, FBody smallNode) { | |
| FDistanceJoint spring = new FDistanceJoint(bigNode, smallNode); | |
| spring.setFrequency(8); | |
| spring.setDamping((float) 1); | |
| initFSpring(spring); | |
| return spring; | |
| } | |
| FDistanceJoint createRepulsion(FBody bigNode, FBody smallNode, float k) { | |
| FDistanceJoint spring = new FDistanceJoint(bigNode, smallNode); | |
| spring.setFrequency((float) 1 + random(0, 1/10)); | |
| spring.setDamping((float) 0.5 + random(0, 1/10)); | |
| spring.setStroke(0, 130, 164); | |
| spring.setStrokeWeight((float) 0.01); | |
| spring.setLength(k * random(200, 300)); | |
| spring.setDrawable(false); | |
| return spring; | |
| } | |
| private void initFSpring(FDistanceJoint spring) { | |
| spring.setStroke(0, 130, 164); | |
| spring.setStrokeWeight(2); | |
| spring.setStrokeWeight(1); | |
| // spring.setDrawable(false); | |
| spring.setLength(random(40, 80)); | |
| } | |
| public void keyPressed() { | |
| if (key == 's' || key == 'S') | |
| saveFrame(timestamp() + "_##.png"); | |
| if (key == 'r' || key == 'R') { | |
| background(255); | |
| physics.clear(); | |
| generateGraph(); | |
| } | |
| } | |
| String timestamp() { | |
| return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", Calendar.getInstance()); | |
| } | |
| private void initFCircle(FBody node) { | |
| node.setDensity((float) 0.2); | |
| node.setFill(0); | |
| node.setStrokeWeight(2); | |
| // node.setStroke(255, 0); | |
| // node.setStroke(0, random(1,255), 0); | |
| node.setStroke(127, 0); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment