Skip to content

Instantly share code, notes, and snippets.

@mvaz
Created April 23, 2011 16:05
Show Gist options
  • Select an option

  • Save mvaz/938737 to your computer and use it in GitHub Desktop.

Select an option

Save mvaz/938737 to your computer and use it in GitHub Desktop.
FisicaGraph
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