openProcessing visual ID : highlight / output : raw text geshi syntax highlighter pdf




Ring Ring by Kyle McDonald

visual id : 1167 author id : 838



Source files :

RingRing.pde
ForceDirectedGraph.pde
Musician.pde
Musicians.pde
SortedQueue.pde

Source files retrieved from openProcessing.org on Thursday 02 September 2010, 23:06:55 (CEST)
Code licensed under Creative Commons GNU GPL : http://creativecommons.org/licenses/GPL/2.0/





RingRing.pde



import promidi.*;
 
int midiPort = 0;
float musicianSize = 20;
int reactionAvg = 250; // global mean
int reactionVar = 100; // individual variance
int reactionMod = 50; // per clap variation
int fadeOut = 200;
int minVelocity = 30;
int maxVelocity = 100;
int[] notes = {
  45, 47,
  48, 50, 52, 53, 55, 57, 59,
  60, 62, 64, 65, 67, 69, 71,
  72, 74, 76, 77, 79, 81, 83,
  84, 86, 88};
 
Musicians m;
PFont trebuchet;
MidiIO midiIO;
MidiOut midiOut;
 
void setup() {
  size(640, 360);
  colorMode(HSB, 1);
 
  trebuchet = loadFont("TrebuchetMS-9.vlw");
  textFont(trebuchet, 9);
  m = new Musicians(26, new ForceDirectedGraph());
 
  midiIO = MidiIO.getInstance(this);
  midiOut = midiIO.openOutput(midiPort);
}
 
void draw() {
  background(1);
  m.update();
  if(dragged != null) {
    Vector3D xy = m.fdg.remap(mouseX, mouseY);
    dragged.particle.moveTo(xy.x(), xy.y(), 0);
  }
  m.render();
}
 
Musician dragged, watcher;
void keyPressed() {
  if(key == ' ')
    m.clap();
  else if(keyCode == TAB) {
    m.panic();
    setup();
  }
  else if(keyCode == BACKSPACE)
    watcher = null;
  else if(key >= 'a' && key <= 'z')
    connect(m.get(str(char(key))));
}
 
void connect(Musician selected) {
  if(watcher == null) {
    watcher = selected;
    watcher.highlight();
  } else {
    if(selected != null)
      if(watcher == selected)
        watcher.watch(null);
      else 
        watcher.watch(selected);
    watcher.highlight();
    watcher = null;
  }
}
 
void mousePressed() {
  Vector3D xy = m.fdg.remap(mouseX, mouseY);
  Musician cur = m.at(xy.x(), xy.y());
  if(cur != null) {
    if(mouseButton == RIGHT)
      cur.forceClap();
    else if(watcher != null || (keyPressed && keyCode == CONTROL))
      connect(cur);
    else
      dragged = cur;
  }
}
 
void mouseReleased() {
  dragged = null;
}



ForceDirectedGraph.pde



// libraries available from http://www.cs.princeton.edu/~traer/
import traer.physics.*;
import traer.animation.*;
 
final float EDGE_LENGTH = 15;
final float EDGE_STRENGTH = 0.3;
final float SPACER_STRENGTH = 1000;
 
class ForceDirectedGraph extends ParticleSystem {
  Smoother3D centroid;
  ForceDirectedGraph() {
    this(0.25, 0.8);
  }
  ForceDirectedGraph(float friction, float smoothness) {
    super(0, friction);
    centroid = new Smoother3D(smoothness);
    reset();
  }
  void reset() {
    clear();
    centroid.setValue(0, 0, 1);
  }
  void position() {
    translate( width/2 , height/2 );
    if(centroid.z() != 1)
      scale(centroid.z());
    translate(-centroid.x(), -centroid.y());
  }
  Vector3D remap(float x, float y) {
    return new Vector3D(
      centroid.x() + (x - width/2) / centroid.z(),
      centroid.y() + (y - height/2) / centroid.z(),
      0);
  }
  Particle addVertex() { 
    Particle p = makeParticle();
    for(int i = 0; i < numberOfParticles(); i++) {
      Particle t = getParticle(i);
      if(t != p)
        makeAttraction(p, t, -SPACER_STRENGTH, 20);
    }
    return p;
  }
  Spring makeEdge(Particle a, Particle b) {
    return makeSpring(a, b, EDGE_STRENGTH, EDGE_STRENGTH, EDGE_LENGTH);
  }
  void updateCentroid() {
    float 
      xMax = Float.NEGATIVE_INFINITY, 
      xMin = Float.POSITIVE_INFINITY, 
      yMin = Float.POSITIVE_INFINITY, 
      yMax = Float.NEGATIVE_INFINITY;
 
    for(int i = 0; i < numberOfParticles(); i++) {
      Particle p = getParticle(i);
      xMax = max(xMax, p.position().x());
      xMin = min(xMin, p.position().x());
      yMin = min(yMin, p.position().y());
      yMax = max(yMax, p.position().y());
    }
 
    float deltaX = xMax - xMin;
    float deltaY = yMax - yMin;
    if (deltaY > deltaX)
      centroid.setTarget(xMin + 0.5 * deltaX, yMin + 0.5 * deltaY, constrain(height/(deltaY+50), 0, 1));
    else
      centroid.setTarget(xMin + 0.5 * deltaX, yMin + 0.5 * deltaY, constrain(width/(deltaX+50), 0, 1));
  }
  void time(float tickLength) {
    super.tick(tickLength);
    if(numberOfParticles() > 1)
      updateCentroid();
    centroid.tick();
  }
}



Musician.pde



class Musician {
  SortedQueue heard;
  Musician watching;
 
  ForceDirectedGraph fdg;
  Particle particle;
  Spring watchingSpring;
 
  boolean highlighted;
  String name;
  boolean clapping;
  int lastClap;
  int pitch;
  int reactionTime;
  Note lastNote;
  Musician(String name, int pitch, ForceDirectedGraph fdg) {
    this.name = name;
    this.heard = new SortedQueue();
    this.lastClap = -fadeOut;
    this.highlighted = false;
    this.pitch = pitch;
    this.reactionTime = reactionAvg + (int) random(-reactionVar, reactionVar);
    this.fdg = fdg;
    this.particle = fdg.addVertex();
    particle.makeFixed();
  }
  void watch(Musician watch) {
    if(watchingSpring != null)
      watchingSpring.turnOff();
    if(watch != null) {
      watchingSpring = fdg.makeEdge(particle, watch.particle);
      particle.makeFree();
    } else
      particle.makeFixed();
    watching = watch;
  }
  void clap() {
    if(!heard.isEmpty() && heard.peekInt() < millis()) {
      clapping = true;
      lastClap = heard.pop();
      sendClap();
    }
    else
      clapping = false;
  }
  void forceClap() {
    heard.push(millis());
  }
  void sendClap() {
    stopLastClap();
    lastNote = new Note(0, pitch, (int) random(minVelocity, maxVelocity));
    midiOut.sendNoteOn(lastNote);
  }
  void stopLastClap() {
    if(lastNote != null) {
      midiOut.sendNoteOff(lastNote);
      lastNote = null;
    }
  }
  void watch() {
    if(follower() && watching.clapping) 
      heard.push(millis() + reactionTime + (int) random(-reactionMod, reactionMod));
  }
  void highlight() {
    highlighted = highlighted ? false : true;
  }
  void drawArrow() {
    if(follower()) {
      stroke(0);
      fill(1);
      Vector3D
        axy = particle.position(),
        bxy = watching.particle.position();
      arrow(axy.x(), axy.y(), bxy.x(), bxy.y(), musicianSize);
    }
  }
  void drawNode() {
    fill(1);
    float clapFade = millis() - lastClap;
    if(clapFade < fadeOut) {
      fill(0, 1 - clapFade/fadeOut, 1);
    } else
      stopLastClap();
    if(highlighted)
      fill(.15, 1, 1);
    stroke(0);
    Vector3D xy = particle.position();
    if(follower())
      ellipse(xy.x(), xy.y(), musicianSize, musicianSize);
    else
      rect(xy.x()-musicianSize/2, xy.y()-musicianSize/2, musicianSize, musicianSize);
 
    fill(0);
    text(name, xy.x() - 2, xy.y() + 3);
  }
  boolean follower() {
    return watching != null;
  }
}
 
void arrow(float x1, float y1, float x2, float y2, float base) {
  float angle = atan2(y2 - y1, x2 - x1);
  float r = base / 2;
  float ax = x1 + cos(angle + HALF_PI) * r;
  float ay = y1 + sin(angle + HALF_PI) * r;
  float bx = x1 + cos(angle - HALF_PI) * r;
  float by = y1 + sin(angle - HALF_PI) * r;
  triangle(ax, ay, x2, y2, bx, by);
}



Musicians.pde



class Musicians extends Vector{
  ForceDirectedGraph fdg;
  Musician leader;
  Musicians(int total, ForceDirectedGraph fdg) {
    this.fdg = fdg; 
    leader = new Musician("a", notes[0], fdg);
    add(leader);
    for(int i = 1; i < total; i++) {
      Musician cur = new Musician(str(char(97 + i)), notes[i], fdg);
      Musician watched = getRandom();
      cur.watch(watched);
      Vector3D base = watched.particle.position();
      cur.particle.moveTo(
        base.x() + random(-1, 1),
        base.y() + random(-1, 1),
        0);
      add(cur);
    }
  }
  Musician get(int i) {
    return (Musician) super.get(i);
  }
  Musician get(String name) {
    for(int i = 0; i < size(); i++)
      if(get(i).name.equals(name))
        return get(i);
    return null;
  }
  Musician getRandom() {
    return get((int) random(size()));
  }
  void add(Musician m) {
    super.add(m);
  }
  void update() {
    fdg.time(1);
    for(int i = 0; i < size(); i++) get(i).clap();
    for(int i = 0; i < size(); i++) get(i).watch();
  }
  void render() {
    fdg.position(); 
    for(int i = 0; i < size(); i++) get(i).drawArrow();
    for(int i = 0; i < size(); i++) get(i).drawNode();
  }
  Musician at(float x, float y) {
    for(int i = 0 ; i < size(); i++) {
      Vector3D xy = get(i).particle.position();
      float d = dist(x, y, xy.x(), xy.y());
      if(d < musicianSize/2)
        return get(i);
    }
    return null;
  }
  void clap() {
    leader.forceClap();
  }
  void panic() {
    for(int i = 0; i < size(); i++)
      get(i).stopLastClap();
  }
  void connect(String a, String b) {
    if(a.equals(b))
      get(a).watch(null);
    else
      get(a).watch(get(b));
  }
}



SortedQueue.pde



class SortedQueue {
  LinkedList list = new LinkedList();
  void push(int v) {
    if(isEmpty())
      list.add(new Integer(v));
    else
      for(int i = size() - 1; i > -1; i--) 
        if(v > getInt(i)) {
          list.add(i + 1, new Integer(v));
          break;
        }
  }
  int size() {
    return list.size();
  }
  int pop() {
    return ((Integer) list.remove()).intValue();
  }
  int getInt(int i) {
    return ((Integer) list.get(i)).intValue();
  }
  int peekInt() {
    return getInt(0);
  }
  boolean isEmpty() {
    return list.isEmpty();
  }
}






Geshi (Generic Syntax Highlighter) released under GNU-GPL
Geshi Processing highlight plugin by Andy Best
Syntax Highlighter code by Alex Gorbatchev, released under LGPL3
Syntax Highlighter Processing Brush File by Sebastian Korczak
html2pdf library by : Laurent Minguet / Spipu, released under LGPL (based on FPDF library)
bookmarklet by Dotlassie :
javascript:var id=window.location.search.replace(/^.*visualID=(\d+).*/,'$1');if(id.length>0)window.open('http://emoc.org/opcode/'+id);void(0);


Glueing all together by emoc, december 2009 / updated on June 22, 2010