This code was written with the _ALPHA_ version of Processing
and it may not run correctly with the current vesion.


// Matchboxes
// by Schoenerwissen 

// Reassembling a movieclip database by using the properties of the 
// collected information to generate a new visual data matrix

// This program will not run if you cut and paste it into your Processing environment.
// It relies on the text file "sc.db", the font "Univers55.vlw.gz" 
// and the image "schoenerwissen.gif" String[] dataLines; String[][] finalData; ScreenMatrix[] sm; GeoLocation[] gl; String[] geoLocation; BFont fontA; BImage swLogo; int[] geoCount; static int NAME = 0, ACTIVITY = 1, GREYSCALE = 2, MOTION = 4, DISTANCE = 5, GEOLOCATION = 6, SUBJECT = 8; static float SGREY = 240; static char SEPARATOR = '\t'; static int TEXTSHOWTIME = 48; static float FAR, MEDIUM, CLOSE, VERYCLOSE, NODIST; static float fixedist = 6.6; int frameCounter = TEXTSHOWTIME + 1; int clipselect = 0; float maxgrey = 0; void setup() { size(640, 480); colorMode(RGB, 255); background(255, 255, 255); VERYCLOSE = width/fixedist; CLOSE = width/(fixedist*2); FAR = width/(fixedist*4); MEDIUM = width/(fixedist*8); NODIST = width/(fixedist*16); fontA = loadFont("Univers55.vlw.gz"); setFont(fontA); swLogo = loadImage("schoenerwissen.gif"); loadData(); computeGeolocations(); organizeLocations(); calculateMatrix(); } void loop() { for (int geolo = 0; geolo < gl.length; geolo++) { gl[geolo].draw(); } paintStandards(); for (int clips = 0; clips < sm.length; clips++) { sm[clips].update(); sm[clips].draw(); } if (frameCounter > TEXTSHOWTIME) { clipselect = (int)(random(sm.length)); frameCounter = 0; } frameCounter++; sm[clipselect].subject(finalData[clipselect][SUBJECT]); } void loadData() { dataLines = loadStrings("sc.db"); finalData = new String[dataLines.length][]; for (int dataline = 0; dataline < dataLines.length; dataline++) { finalData[dataline] = splitStrings(dataLines[dataline], SEPARATOR); } } void calculateMatrix() { sm = new ScreenMatrix[dataLines.length]; for (int dataline = 0; dataline < dataLines.length; dataline++) { float grey = Float.valueOf(finalData[dataline][GREYSCALE]).floatValue(); if (grey > maxgrey) { maxgrey = grey; } for (int geoline = 0; geoline < geoCount.length; geoline++) { if (gl[geoline].name.equals(finalData[dataline][GEOLOCATION])) { float distance = calculateDistance(finalData[dataline][DISTANCE]); float activity = Float.valueOf(finalData[dataline][ACTIVITY]).floatValue()*(width/800); Point motion = calculateMotion(finalData[dataline][MOTION]); sm[dataline] = new ScreenMatrix(distance * motion.x, distance * motion.y, gl[geoline].x, gl[geoline].y, distance, activity*100, motion, gl[geoline].c1, grey); } } } } void computeGeolocations() { String allGeolocations = ""; for(int dataline = 0; dataline < dataLines.length; dataline++) { if(allGeolocations.indexOf(finalData[dataline][GEOLOCATION]) == -1) { allGeolocations += finalData[dataline][GEOLOCATION] + SEPARATOR; } } geoLocation = splitStrings(allGeolocations, SEPARATOR); geoCount = new int[geoLocation.length]; for(int dataline = 0; dataline < dataLines.length; dataline++) { for(int geoline = 0; geoline < geoLocation.length; geoline++) { if (finalData[dataline][GEOLOCATION].equals(geoLocation[geoline])) { geoCount[geoline]++; } } } } void organizeLocations() { gl = new GeoLocation[geoCount.length]; float x, y = 0; int[] geoCountBuffer = new int[geoCount.length]; String[] geoLocationBuffer = new String[geoCount.length]; for (int geoline = 0; geoline < geoCount.length; geoline++) { int maximl = maxPoint(geoCount); geoCountBuffer[geoline] = geoCount[maximl]; geoLocationBuffer[geoline] = geoLocation[maximl]; geoCount[maximl] = 0; } int halfArray = (int)(geoCount.length/2); for (int geoline = 0; geoline < geoCount.length; geoline = geoline+2) { geoCount[halfArray] = geoCountBuffer[geoline]; geoLocation[halfArray] = geoLocationBuffer[geoline]; halfArray--; } halfArray = geoCount.length-1; for (int geoline = geoCount.length-2; geoline > 0; geoline = geoline-2) { geoCount[halfArray] = geoCountBuffer[geoline]; geoLocation[halfArray] = geoLocationBuffer[geoline]; halfArray--; } for (int geoline = 0; geoline < geoCount.length; geoline++) { x = (width/(geoCount.length))*geoline+((width/(geoCount.length))/2); y = (height/(geoCount.length))*geoline+((height/(geoCount.length))/2); float c1 = random(255), c2 = random(255), c3 = random(255); gl[geoline] = new GeoLocation(x, y, geoLocation[geoline], c1, c2, c3); } } class GeoLocation { float x, y, c1, c2, c3, cross; String name; GeoLocation(float ix, float iy, String iname, float ic1, float ic2, float ic3) { x = ix; y = iy; name = iname; c1 = ic1; c2 = ic2; c3 = ic3; cross = 15; if (name.length() > 6) { cross = 30; } } void draw() { stroke(SGREY); line(0, y, width, y); line(x, 0, x, height); fill(0); push(); scale(1.2); text(name, (x-cross)/1.2, (y-5)/1.2); pop(); } } class ScreenMatrix { float x, y, xc, yc, distance, activity, angle, cross, col, grey; Point motion; ScreenMatrix(float ix, float iy, float iw, float ih, float idistance, float iactivity, Point imotion, float icol, float igrey) { x = iw+ix; y = ih+iy; xc = iw; yc = ih; distance = idistance; activity = iactivity; motion = imotion; col = icol; grey = igrey; angle = 0; cross = distance/8; } void update() { x += (motion.x) * activity; y += (motion.y) * activity; if ( motion.x == 0 && motion.y == 0) { if (angle > 360) { angle = 0; } x = xc + (distance * sin(PI * angle)); y = yc + (-distance * cos(PI * angle)); angle += activity * .01; } else { if ( x > width ) { x = 0; } else if ( x < 0) { x = width; } else if ( y > height) { y = 0; } else if ( y < 0) { y = height; } } } void draw() { noStroke(); colorMode(HSB, 255); fill(col, 255-((grey*255)/maxgrey), 255-((grey*255)/maxgrey)); rect(x, y, cross, cross); colorMode(RGB, 255); } void subject(String txt) { stroke(160); rect(x, y, cross, cross); line(x, y, xc, yc); push(); scale(1.5); noStroke(); fill(255, 0, 255); text(txt, (x + 5)/1.5, (y - 5)/1.5); pop(); } } float calculateDistance(String distance) { float distf = 0; if (distance.equals("far")) { distf = FAR; } else if (distance.equals("medium")) { distf = MEDIUM; } else if (distance.equals("close")) { distf = CLOSE; } else if (distance.equals("very_close")) { distf = VERYCLOSE; } else { distf = NODIST; } return dist; } Point calculateMotion(String motion) { Point p = new Point(0,0); if (motion.equals("forward")) { p.x = 0; p.y = -1; } else if (motion.equals("right")) { p.x = 1; p.y = 0; } else if (motion.equals("left")) { p.x = -1; p.y = 0; } else if (motion.equals("away")) { p.x = 0; p.y = 1; } else { p.x = 0; p.y = 0; } return p; } int maxPoint(int[] value) { int maximum = Integer.MIN_VALUE; int mp = 0; for (int aset=0; aset < value.length; aset++) { if (value[aset] > maximum) { maximum = value[aset]; mp = aset; } } return mp; } void paintStandards() { stroke(SGREY); line(0, 0, width, height); unhint(SMOOTH_IMAGES); image(swLogo, 0, height-50); hint(SMOOTH_IMAGES); }