http://www.esono.com/boris/projects/poetry06/
regards
^-^
fullscreen /*---------------------------------------------------------
Code by Diana Lange
http://www.diana-lange.de
http://vimeo.com/dianalange
http://www.flickr.com/photos/dianalange/
http://openprocessing.org/portal/?userID=5969
Fastblur by Mario Klingemann
Text by Friedrich Schiller
---------------------------------------------------------*/
import processing.pdf.*;
import processing.video.*;
Buergschaft vis;
MovieMaker mm;
boolean saveMov = false, savePDF = false;
String txtInputType = "utf", txtSource = "buergschaft.txt", txtTitle = "Schiller: Die Bürgschaft";
void setup ()
{
size(800, 800, JAVA2D);
//cursor(HAND);
colorMode(HSB, 360, 100, 100, 255);
background (0, 0, 97);
vis = new Buergschaft (new TextAnalyzer (txtSource, txtInputType, animate), txtTitle);
smooth();
frameRate (30);
}
void draw ()
{
if (savePDF) beginRecord (PDF, "export/" + timestamp() + ".pdf");
vis.display();
if (saveMov) mm.addFrame();
if (savePDF) {
savePDF = false;
endRecord();
}
}
class Buergschaft
{
private Word [] txt;
private int fullSize, aninmationCount, animationMode = 1;
private PVector pos = new PVector (width /2, height / 2);
private float measure = 0.25;
private float dBig = 300, dSmal = 150;
private float strokeW = 0.5;
private TextDisplayer rawTxt, listed;
private PGraphics pg;
private HashMap colors;
private String title;
private PFont font;
private boolean showText, showHeadline, animate;
private TextAnalyzer textAnalyzer;
public Buergschaft (TextAnalyzer txt, String title)
{
this.animate = txt.getMode();
this.txt = txt.getWordArray();
this.title = title;
this.font = createFont ("Rockwell", 24);
fullSize = txt.getFullSize();
showText = false;
showHeadline = true;
if (animate) {
this.textAnalyzer = txt;
aninmationCount = 0;
}
HashMap txtColors = new HashMap();
txtColors.put ("text", new Integer (color (0, 0, 20)));
txtColors.put ("highlight", new Integer (color (355, 95, 50)));
txtColors.put ("bg", new Integer (color (0, 0, 97, 15)));
txtColors.put ("scrollbar", new Integer (color (0, 0, 3, 150)));
txtColors.put ("scrollbarBG", new Integer (color (0, 0, 3, 60)));
int [] bordersBlock = {
110, 70, 350, 600, 15
};
int [] bordersList = {
500, 70, 250, 600, 15
};
pg = createGraphics (width, height, JAVA2D);
rawTxt = new TextDisplayer (txt.getRawTxt(), bordersBlock, 12, txtColors, false);
listed = new TextDisplayer (wordArrayToStringArray(this.txt), bordersList, 12, txtColors, true);
colors = new HashMap();
colors.put ("stroke", new Integer (color (0, 0, 3, 80)));
colors.put ("bg", new Integer (color (0, 0, 97)));
colors.put ("bgRect", new Integer (color (0, 0, 92)));
colors.put ("highlight", new Integer (color (355, 95, 50)));
colors.put ("ellipse", new Integer (color (0, 0, 20)));
colors.put ("ellipseStroke", new Integer (color (355, 95, 50, 200)));
colors.put ("connections", new Integer (color (0, 0, 3, 30)));
if (showText) createBluredBG();
}
// ----------------------------------------------------------------------------------------------------
// IO / Set / Get
// ----------------------------------------------------------------------------------------------------
public void measureUp ()
{
measure += 0.01;
if (measure > 1.0) measure = 1.0;
}
public void measureDown ()
{
measure -= 0.01;
if (measure < 0.0) measure = 0.0;
}
public void displayMode ()
{
showText = !showText;
if (showText) createBluredBG ();
else colorMode (HSB, 360, 100, 100, 255);
}
public void toggleHeadline ()
{
showHeadline = !showHeadline;
createBluredBG ();
}
public void toggleAnimationMode ()
{
animationMode++;
if (animationMode > 1) animationMode = 0;
}
private void createBluredBG ()
{
colorMode (RGB, 255, 255, 255, 255);
pg.beginDraw();
pg.smooth();
displayBG (true, 10);
displayGraph(true);
if (showHeadline) displayHeadline(true, 0, int (height/2.0 - height/5.0), 30, 15);
pg.endDraw();
rawTxt.setBG(createCroppedImg(pg, rawTxt.getX(), rawTxt.getY(), rawTxt.getWidth(), rawTxt.getHeight()));
listed.setTxt(wordArrayToStringArray(txt));
listed.setBG(createCroppedImg(pg, listed.getX(), listed.getY(), listed.getWidth(), listed.getHeight()));
}
private PImage createCroppedImg (PImage source, int x, int y, int w, int h)
{
PImage blur = createImage (source.width, source.height, ARGB);
System.arraycopy(source.pixels, 0, blur.pixels, 0, blur.pixels.length);
fastblur(blur, 30);
PImage result = createImage (w, h, ARGB);
source.loadPixels();
int count = 0;
for (int i = y; i < y+h; i++)
{
for (int j = x; j < x+w; j++)
{
int index = j+i*blur.height;
result.pixels[count] = blur.pixels[index];
count++;
}
}
result.updatePixels();
return result;
}
// ----------------------------------------------------------------------------------------------------
// Switch
// ----------------------------------------------------------------------------------------------------
public void display()
{
if (showText)
{
image (pg, 0, 0);
rawTxt.display();
listed.display();
}
else {
if (animate)
{
if (textAnalyzer.getAnimation())
{
textAnalyzer.createWordArrayList("utf", aninmationCount);
txt = textAnalyzer.getWordArray();
aninmationCount++;
}
}
displayBG(false, 10);
displayGraph(false);
if (showHeadline) displayHeadline(false, 0, int (height/2.0 - height/5.0), 30, 15);
}
}
private void displayBG (boolean writeToImage, int padd)
{
if (writeToImage)
{
pg.background ((Integer) colors.get("bg"));
pg.noStroke();
pg.fill ((Integer) colors.get("bgRect"));
pg.rect (padd, padd, width-padd*2, height-padd*2);
}
else
{
background ((Integer) colors.get("bg"));
noStroke();
fill ((Integer) colors.get("bgRect"));
rect (padd, padd, width-padd*2, height-padd*2);
}
}
private void displayHeadline (boolean writeToImage, int x, int y, int s, int padd)
{
color c = (Integer) colors.get("highlight");
if (writeToImage)
{
pg.textFont (this.font, s);
pg.textAlign (LEFT);
pg.noStroke();
pg.fill (red (c), green(c), blue (c), 200);
pg.rect (x, y, padd*2 + textWidth (title), s*1.4);
pg.fill ((Integer) colors.get("bgRect"));
pg.text (title, x+padd, y+s);
}
else {
textFont (this.font, s);
textAlign (LEFT);
noStroke();
fill (hue (c), saturation(c), brightness (c), 200);
rect (x, y, padd*2 + textWidth (title), s*1.4);
fill ((Integer) colors.get("bgRect"));
text (title, x+padd, y+s);
}
}
// ----------------------------------------------------------------------------------------------------
// Graph
// ----------------------------------------------------------------------------------------------------
private void displayGraph (boolean writeToImage)
{
textFont (font);
float angle = 0.0;
float steps = 360.0 / (float) fullSize;
if (animationMode == 1 && animate) {
if (textAnalyzer.getAnimation()) {
if (aninmationCount != 0) steps = 360.0 / (float) aninmationCount;
else steps = 360.0;
}
else steps = 360.0 / (float) fullSize;
}
boolean active = false, hover = false;
int id = -1;
int [] index;
for (int i = 0; i < txt.length; i++)
{
hover = false;
index = txt[i].getIndex();
angle += steps*(float) index.length/2.0;
PVector p1 = createPos (angle, dBig, pos);
if (!active && checkHover(p1.x, p1.y, steps*(float) index.length*2.0))
{
addText (str (txt[i].getCount()) + "x " + txt[i].getTxt(), pos.x, 40, 24, "center", 'u');
active = true;
hover = true;
id = i;
}
else {
hover = false;
}
showConnections (writeToImage, angle, index, i, p1);
showWordIndex (writeToImage, index, p1.x, p1.y, steps*(float) index.length*4.0, angle, strokeW, hover);
//addEllipse (p1.x, p1.y, steps*(float) index.length*4.0, txt[i].getLength(), hover);
angle += steps*(float) index.length/2.0;
}
angle = 0.0;
for (int i = 0; i < txt.length; i++)
{
index = txt[i].getIndex();
angle += steps*(float) index.length/2.0;
PVector p1 = createPos (angle, dBig, pos);
if (i == id) addEllipse (writeToImage, p1.x, p1.y, steps*(float) index.length*4.0, txt[i].getLength(), true);
else addEllipse (writeToImage, p1.x, p1.y, steps*(float) index.length*4.0, txt[i].getLength(), false);
angle += steps*(float) index.length/2.0;
}
}
private void showConnections (boolean writeToImage, float angle, int [] index, int i, PVector p1)
{
ArrayList apositions = new ArrayList();
float mangle = lerp (angle, 360.0 / (float) txt.length *txt [i].getLast(), 0.5);
if (angle - 360.0 / (float) txt.length *txt [i].getLast() > 180) mangle -= 180;
apositions.add (p1);
apositions.add (createPos (mangle, dBig + dBig / (float) index.length / 2.0, pos));
apositions.add (createPos (360.0 / (float) txt.length *txt [i].getLast(), dBig, pos));
if (angle - 360.0 / (float) txt.length *txt [i].getLast() > 90) apositions.add (2, createPos (lerp (angle, 360.0 / (float) txt.length *txt [i].getLast(), 0.75), dBig + abs (width-2*dBig) / (float) index.length, pos));
PVector [] positions = arrayListToPVector(apositions);
if (index.length > 2) addCurve (writeToImage, positions, (Integer) colors.get("connections"), strokeW+0.12*(float)index.length);
}
private void showWordIndex (boolean writeToImage, int [] index, float x, float y, float xd, float angle, float strokeW, boolean hover)
{
PVector [] positions = new PVector [4];
for (int j = 0; j < index.length; j++)
{
positions [0] = createPos (360.0 / (float) index.length * (float) j, xd/2, new PVector (x, y));
positions [3] = createPos (360.0 / (float) fullSize * (float) index [j], dSmal, pos);
positions [1] = createPos (lerp (angle, 360.0 / (float) fullSize * (float) index [j], measure), lerp (dBig, dSmal, (float) j / (float) index.length), pos);
positions [2] = createPos (lerp (360.0 / (float) fullSize * (float) index [j], angle, measure), lerp (dSmal, dBig, (float) j / (float) index.length), pos );
addCurve (writeToImage, positions, strokeW / (float) index.length, hover);
}
}
// ----------------------------------------------------------------------------------------------------
// Visuals
// ----------------------------------------------------------------------------------------------------
private void addText (String txt, float x, float y, int s, String align, char h)
{
noStroke ();
fill ((Integer) colors.get("highlight"));
if (align.equals ("left")) textAlign (LEFT);
else if (align.equals ("center")) textAlign (CENTER);
else textAlign (RIGHT);
if (h == 'u') txt = txt.toUpperCase();
textFont (this.font, s);
text (txt, x, y);
}
private void addCurve (boolean writeToImage, PVector [] positions, float sW, boolean hover)
{
if (hover)
{
sW = strokeW;
if (writeToImage) {
color t = (Integer) colors.get("highlight");
pg.stroke ((Integer) colors.get("highlight"));
}
else stroke ((Integer) colors.get("highlight"));
}
else {
if (writeToImage) {
color t = (Integer) colors.get("stroke");
pg.stroke ((Integer) colors.get("stroke"));
}
else stroke ((Integer) colors.get("stroke"));
}
if (writeToImage) {
pg.noFill();
pg.strokeWeight (sW);
pg.beginShape();
}
else {
noFill();
strokeWeight (sW);
beginShape();
}
for (int i = 0; i < positions.length; i++)
{
if (writeToImage) {
pg.curveVertex (positions[i].x, positions[i].y);
if (i == 0 ||i == positions.length-1) pg.curveVertex (positions[i].x, positions[i].y);
}
else {
curveVertex (positions[i].x, positions[i].y);
if (i == 0 ||i == positions.length-1) curveVertex (positions[i].x, positions[i].y);
}
}
if (writeToImage) pg.endShape();
else endShape();
}
private void addCurve (boolean writeToImage, PVector [] positions, int c, float sW)
{
if (writeToImage)
{
pg.strokeWeight (sW);
pg.stroke (c);
pg.noFill();
pg.beginShape();
}
else
{
strokeWeight (sW);
stroke (c);
noFill();
beginShape();
}
for (int i = 0; i < positions.length; i++)
{
if (writeToImage) {
pg.curveVertex (positions[i].x, positions[i].y);
if (i == 0 ||i == positions.length-1) pg.curveVertex (positions[i].x, positions[i].y);
}
else {
curveVertex (positions[i].x, positions[i].y);
if (i == 0 ||i == positions.length-1) curveVertex (positions[i].x, positions[i].y);
}
}
if (writeToImage) pg.endShape();
else endShape();
}
private void addEllipse (boolean writeToImage, float x, float y, float d, float sW, boolean hover)
{
if (writeToImage) {
if (hover) pg.fill ((Integer) colors.get("highlight"));
else pg.fill ((Integer) colors.get("ellipse"));
}
else
{
if (hover) fill ((Integer) colors.get("highlight"));
else fill ((Integer) colors.get("ellipse"));
}
if (sW < d)
{
if (writeToImage) {
pg.strokeWeight (sW);
pg.stroke ((Integer) colors.get("ellipseStroke"));
}
else {
strokeWeight (sW);
stroke ((Integer) colors.get("ellipseStroke"));
}
}
else {
if (writeToImage) pg.noStroke();
else noStroke();
}
if (writeToImage) pg.ellipse (x, y, d, d);
else ellipse (x, y, d, d);
}
}
class TextAnalyzer
{
private ArrayList fullTxt, words;
private Word [] wordArray;
private int last;
private String [] rawTxt;
private PFont font;
private boolean animate, isAnimating;
public TextAnalyzer (String loadPath, String inputFormat, boolean animate)
{
this.animate = animate;
if (animate) isAnimating = true;
fullTxt = new ArrayList();
words = new ArrayList();
this.font = createFont ("Verdana", 12);
splitText (loadStrings (loadPath));
if (!animate) createWordArrayList(inputFormat);
//createWordArray();
}
public TextAnalyzer (String loadString, boolean animate)
{
this.animate = animate;
if (animate) isAnimating = true;
fullTxt = new ArrayList();
words = new ArrayList();
this.font = createFont ("Verdana", 12);
String [] temp = {
loadString };
splitText (temp);
if (!animate) createWordArrayList("ansi");
//createWordArray();
}
public boolean getAnimation ()
{
if (animate && isAnimating) return true;
else return false;
}
public boolean getMode ()
{
return animate;
}
public int getFullSize()
{
return fullTxt.size();
}
public Word [] getWordArray()
{
createWordArray();
return wordArray;
}
public String getRawTxt ()
{
String raw = "";
for (int i = 0; i < rawTxt.length; i++)
{
raw += rawTxt [i] + " ";
}
return raw;
}
private void splitText (String [] rawTxt)
{
this.rawTxt = rawTxt;
String tokens = ",.;:-_!?&\"□▫¶~ +%=()[]{}«»#&%§'|";
for (int i = 0; i < rawTxt.length; i++)
{
String [] rowTxt = splitTokens (rawTxt [i], tokens);
for (int j = 0; j < rowTxt.length; j++)
{
fullTxt.add (new String (rowTxt [j]));
}
}
}
private String removeFirstChar (String word)
{
char [] c = new char [word.length()-1];
for (int k = 0; k < c.length; k++)
{
c [k] = word.charAt(k+1);
}
return new String (c);
}
private void createWordArrayList (String textFormat)
{
// ertser Eintrag
// words.add (new String ((String) fullTxt.get (0)));
boolean found = false;
for (int i = 0; i < fullTxt.size(); i++)
{
String full = (String) fullTxt.get(i);
//println(i + ", Words: " + words.size());
if (words.size() == 0)
{
//erster Eintrag
if (textFormat.equals("utf")) full = removeFirstChar(full);
words.add (new Word (full, 0, 0));
}
else {
found = false;
for (int j = 0; j < words.size(); j++)
{
Word temp = (Word) words.get (j);
if (temp.getTxt().equals ( full.toLowerCase()))
{
// wort in liste gefunden
temp.increase(i);
found = true;
}
if (found)
{
j = words.size();
continue;
}
}
if (!found)
{
//neues Wort
quicksort (full.toLowerCase(), words.size(), 0, i);
}
}
}
}
private void createWordArrayList (String textFormat, int count)
{
// ertser Eintrag
// words.add (new String ((String) fullTxt.get (0)));
boolean found = false;
if (count < fullTxt.size())
{
String full = (String) fullTxt.get(count);
//println(i + ", Words: " + words.size());
if (words.size() == 0)
{
//erster Eintrag
if (textFormat.equals("utf")) full = removeFirstChar(full);
words.add (new Word (full, 0, 0));
}
else {
found = false;
for (int j = 0; j < words.size(); j++)
{
Word temp = (Word) words.get (j);
if (temp.getTxt().equals ( full.toLowerCase()))
{
// wort in liste gefunden
temp.increase(count);
found = true;
}
if (found)
{
j = words.size();
continue;
}
}
if (!found)
{
//neues Wort
quicksort (full.toLowerCase(), words.size(), 0, count);
}
}
}
else {
isAnimating = false;
}
}
private void quicksort (String input, float iSize, float index, int txtIndex)
{
if (round (iSize) == 1)
{
int i = round (index);
Word listedWord = (Word) words.get (i);
String listed = listedWord.getTxt();
if (compareString (input, listed)) addWord (input, i+1, txtIndex);
else addWord (input, i, txtIndex);
}
else {
int i = floor (index+iSize/2.0);
Word listedWord = (Word) words.get (i);
String listed = listedWord.getTxt();
if (compareString (input, listed)) quicksort (input, iSize/2.0, index+iSize/2.0, txtIndex);
else quicksort (input, iSize/2.0, index, txtIndex);
}
}
private boolean compareString (String input, String listed)
{
int dir = input.compareTo(listed);
if (dir > 0 ) return true;
else return false;
}
private void addWord (String input, int pos, int txtIndex)
{
words.add (pos, new Word (input, txtIndex, last));
last = pos;
}
private void createWordArray()
{
wordArray = new Word [words.size()];
for (int i = 0; i < wordArray.length; i++)
{
wordArray [i] = (Word) words.get (i);
}
}
public void displayArrayList ()
{
textFont (this.font, 12);
fill (5);
noStroke();
float x = 20, y = 20;
for (int i = 0; i < words.size(); i++)
{
Word temp = (Word) words.get(i);
text (nf (i, 3, 0) + ". " + temp.getTxt() + ", " + str (temp.getCount()), x, y);
y+= 15;
if (y >= height -15)
{
y = 20;
x += 100;
}
}
}
public void display ()
{
textFont (this.font, 12);
fill (5);
noStroke();
float x = 20, y = 20;
for (int i = 0; i < wordArray.length; i++)
{
text (nf (i, 3, 0) + ". " + wordArray[i].getTxt() + ", " + str (wordArray[i].getCount()), x, y);
y+= 15;
if (y >= height -15)
{
y = 20;
x += 100;
}
}
}
}
class TextDisplayer
{
private PFont font;
private String txt;
private int s; // fontSize
private float totalHeight; // total height for displaying all text;
private float startY /* position of first row of the text*/, sliderY /*position of slider*/, sliderWidth;
private HashMap colors;
private int x, y, w, h, padding;
private String [] splitted;
private PImage bg;
private boolean listed;
TextDisplayer (String txt, int [] borders, int s, HashMap colors, boolean listed)
{
this.listed = listed;
this.s = s;
this.txt = txt;
this.font = createFont ("Arial", s);
bg = createImage (borders [2], borders [3], ARGB);
splitted = split (txt, " ");
x = borders [0];
y = borders [1];
w = borders [2];
h = borders [3];
padding = borders [4];
this.colors = colors;
startY = sliderY = borders [1] + borders [4];
createTotalHeight();
}
TextDisplayer (String [] txt, int [] borders, int s, HashMap colors, boolean listed)
{
this.listed = listed;
this.s = s;
this.txt = "";
bg = createImage (borders [2], borders [3], ARGB);
for (int i = 0; i < txt.length; i++)
{
this.txt += txt[i];
}
this.font = createFont ("Arial", s);
splitted = txt;
x = borders [0];
y = borders [1];
w = borders [2];
h = borders [3];
padding = borders [4];
this.colors = colors;
startY = sliderY = borders [1] + borders [4];
createTotalHeight(); // check if the text fits into the created window and / or calculate how much height the next needs == totalHeight
}
public void setTxt (String [] txt)
{
this.txt = "";
bg = createImage (w, h, ARGB);
for (int i = 0; i < txt.length; i++)
{
this.txt += txt[i];
}
splitted = txt;
createTotalHeight();
}
public void setBG (PImage img)
{
System.arraycopy(img.pixels, 0, bg.pixels, 0, bg.pixels.length);
bg.updatePixels();
}
public int getX ()
{
return x;
}
public int getY ()
{
return y;
}
public int getWidth ()
{
return w;
}
public int getHeight ()
{
return h;
}
public void createTotalHeight()
{
float textx = x + padding, texty = y + padding + s;
textFont (this.font, s);
textAlign (LEFT);
for (int i = 0; i < splitted.length; i++)
{
if (!listed)
{
textx += textWidth (splitted[i] + " ");
if (i < splitted.length-1 && checkNext (splitted [i+1], textx) )
{
textx = x + padding;
texty += s * 1.5;
}
}
else texty += s * 1.5;
}
if ( texty > h )
{
totalHeight = texty + padding;
sliderWidth = padding * 3/5;
}
else {
totalHeight = h;
sliderWidth = 0;
}
}
public void display()
{
image (bg, x, y);
fill ((Integer) colors.get("bg"));
rect (x, y, w, h);
fill ((Integer) colors.get("text"));
float textx = x + padding, texty = startY + s;
textFont (this.font, s);
textAlign (LEFT);
for (int i = 0; i < splitted.length; i++)
{
if (!listed)
{
if ( texty >= y + padding + s && texty < y + h - padding ) text (splitted [i]+ " ", textx, texty);
textx += textWidth (splitted[i] + " ");
if (i < splitted.length-1 && checkNext (splitted [i+1], textx) )
{
textx = x + padding;
texty += s * 1.5;
}
}
else {
if ( texty >= y + padding + s && texty < y + h - padding ) text (splitted [i]+ " ", textx, texty);
texty += s * 1.5;
}
}
if (totalHeight > h)
{
noStroke ();
fill ((Integer) colors.get("scrollbarBG"));
rect (x + w - sliderWidth, y + padding, sliderWidth, h - 2 * padding);
float mapped = ((float) h - 2.0 * (float) padding) / (float) totalHeight * 100; // == sliderBth height
if (mapped < 10) mapped = 10;
if (checkHover (x + w - sliderWidth, y + padding, sliderWidth, h - 2 * padding)) {
fill ((Integer) colors.get("highlight"));
if (mousePressed)
{
sliderY = mouseY;
if (sliderY + mapped > y + h - padding) sliderY = y + h - padding - mapped;
if (sliderY < y +padding) sliderY = y + padding;
startY = map (sliderY, y + padding, y + h - padding - mapped, y + padding, y - totalHeight + h + 2 * padding);
}
}
else fill ((Integer) colors.get("scrollbar"));
rect (x + w - sliderWidth, sliderY, sliderWidth, mapped);
}
}
private boolean checkNext (String next, float currentx)
{
if ( (currentx += textWidth (next)) > x - padding + w ) return true;
else return false;
}
}
class Word
{
private String txt;
private int count;
private int last;
private int letters;
private ArrayList index = new ArrayList();
public Word (String txt, int index, int last)
{
this.txt = txt.toLowerCase();
this.last = last;
letters = this.txt.length();
count = 1;
this.index.add (new Float (index));
}
public int [] getIndex ()
{
int [] indexArray = new int [index.size()];
for (int i = 0; i < index.size(); i++)
{
indexArray [i] = int ( (Float) index.get(i) );
}
return indexArray;
}
public int getLength()
{
return letters;
}
public int getLast()
{
return last;
}
public int getFirstIndex ()
{
return int ( (Float) index.get(0) );
}
public String getTxt ()
{
return txt;
}
public int getCount()
{
return count;
}
public void increase (int index)
{
this.index.add (new Float (index));
count++;
}
}
// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
void fastblur(PImage img,int radius){
if (radius<1){
return;
}
int[] pix=img.pixels;
int w=img.width;
int h=img.height;
int wm=w-1;
int hm=h-1;
int wh=w*h;
int div=radius+radius+1;
int r[]=new int[wh];
int g[]=new int[wh];
int b[]=new int[wh];
int rsum,gsum,bsum,x,y,i,p,yp,yi,yw;
int vmin[] = new int[max(w,h)];
int divsum=(div+1)>>1;
divsum*=divsum;
int dv[]=new int[256*divsum];
for (i=0;i<256*divsum;i++){
dv[i]=(i/divsum);
}
yw=yi=0;
int[][] stack=new int[div][3];
int stackpointer;
int stackstart;
int[] sir;
int rbs;
int r1=radius+1;
int routsum,goutsum,boutsum;
int rinsum,ginsum,binsum;
for (y=0;y<h;y++){
rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
for(i=-radius;i<=radius;i++){
p=pix[yi+min(wm,max(i,0))];
sir=stack[i+radius];
sir[0]=(p & 0xff0000)>>16;
sir[1]=(p & 0x00ff00)>>8;
sir[2]=(p & 0x0000ff);
rbs=r1-abs(i);
rsum+=sir[0]*rbs;
gsum+=sir[1]*rbs;
bsum+=sir[2]*rbs;
if (i>0){
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
} else {
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
}
}
stackpointer=radius;
for (x=0;x<w;x++){
r[yi]=dv[rsum];
g[yi]=dv[gsum];
b[yi]=dv[bsum];
rsum-=routsum;
gsum-=goutsum;
bsum-=boutsum;
stackstart=stackpointer-radius+div;
sir=stack[stackstart%div];
routsum-=sir[0];
goutsum-=sir[1];
boutsum-=sir[2];
if(y==0){
vmin[x]=min(x+radius+1,wm);
}
p=pix[yw+vmin[x]];
sir[0]=(p & 0xff0000)>>16;
sir[1]=(p & 0x00ff00)>>8;
sir[2]=(p & 0x0000ff);
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
rsum+=rinsum;
gsum+=ginsum;
bsum+=binsum;
stackpointer=(stackpointer+1)%div;
sir=stack[(stackpointer)%div];
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
rinsum-=sir[0];
ginsum-=sir[1];
binsum-=sir[2];
yi++;
}
yw+=w;
}
for (x=0;x<w;x++){
rinsum=ginsum=binsum=routsum=goutsum=boutsum=rsum=gsum=bsum=0;
yp=-radius*w;
for(i=-radius;i<=radius;i++){
yi=max(0,yp)+x;
sir=stack[i+radius];
sir[0]=r[yi];
sir[1]=g[yi];
sir[2]=b[yi];
rbs=r1-abs(i);
rsum+=r[yi]*rbs;
gsum+=g[yi]*rbs;
bsum+=b[yi]*rbs;
if (i>0){
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
} else {
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
}
if(i<hm){
yp+=w;
}
}
yi=x;
stackpointer=radius;
for (y=0;y<h;y++){
pix[yi]=0xff000000 | (dv[rsum]<<16) | (dv[gsum]<<8) | dv[bsum];
rsum-=routsum;
gsum-=goutsum;
bsum-=boutsum;
stackstart=stackpointer-radius+div;
sir=stack[stackstart%div];
routsum-=sir[0];
goutsum-=sir[1];
boutsum-=sir[2];
if(x==0){
vmin[y]=min(y+r1,hm)*w;
}
p=x+vmin[y];
sir[0]=r[p];
sir[1]=g[p];
sir[2]=b[p];
rinsum+=sir[0];
ginsum+=sir[1];
binsum+=sir[2];
rsum+=rinsum;
gsum+=ginsum;
bsum+=binsum;
stackpointer=(stackpointer+1)%div;
sir=stack[stackpointer];
routsum+=sir[0];
goutsum+=sir[1];
boutsum+=sir[2];
rinsum-=sir[0];
ginsum-=sir[1];
binsum-=sir[2];
yi+=w;
}
}
img.updatePixels();
}
boolean animate = false;
void keyPressed ()
{
if (keyCode == KeyEvent.VK_SPACE) vis.displayMode();
if (keyCode == KeyEvent.VK_RIGHT) vis.measureUp();
if (keyCode == KeyEvent.VK_LEFT) vis.measureDown();
if (keyCode == KeyEvent.VK_H) vis.toggleHeadline();
if (keyCode == KeyEvent.VK_S) vis.toggleAnimationMode();
if (keyCode == KeyEvent.VK_A)
{
animate = !animate;
vis = new Buergschaft (new TextAnalyzer (txtSource, txtInputType, animate), txtTitle);
}
/*
if (keyCode == KeyEvent.VK_M) {
saveMov = !saveMov;
if (saveMov) {
mm = new MovieMaker(this, width, height, "export/" + timestamp() + "_data.mov", 30, MovieMaker.ANIMATION, MovieMaker.HIGH);
vis = new Buergschaft (new TextAnalyzer (txtSource, txtInputType, animate), txtTitle);
}
}
if (keyCode == KeyEvent.VK_E)
{
if (saveMov) mm.finish();
saveMov = false;
}
if (keyCode == KeyEvent.VK_P) savePDF = !savePDF;
if (keyCode == KeyEvent.VK_O) saveFrame ( "export/" + timestamp() + ".png");
*/
}
// ----------------------------------------------------------------------------------------------------
// Tools
// ----------------------------------------------------------------------------------------------------
String [] wordArrayToStringArray(Word [] words)
{
String [] txt = new String [words.length];
for (int i = 0; i < txt.length; i++)
{
txt[i] = nf(i, 4, 0) + " [" + nf(words[i].getFirstIndex(), 4, 0) + "] " + words[i].getTxt() + " " + str(words[i].getCount()) + "x";
}
return txt;
}
PVector [] arrayListToPVector (ArrayList listed)
{
PVector [] vector = new PVector [listed.size()];
for (int i = 0; i < vector.length; i++)
{
vector [i] = (PVector) listed.get(i);
}
return vector;
}
int [] arrayListToInt (ArrayList listed)
{
int [] in = new int [listed.size()];
for (int i = 0; i < in.length; i++)
{
in [i] = (Integer) listed.get(i);
}
return in;
}
PVector createPos (float angle, float d, PVector pvCenter)
{
PVector position = new PVector (pvCenter.x + cos (radians (angle))*d, pvCenter.y + sin (radians (angle))*d);
return position;
}
boolean checkHover (float x, float y, float d)
{
if (dist (mouseX, mouseY, x, y) < d) return true;
else return false;
}
boolean checkHover (float x, float y, float w, float h)
{
if (mouseX >= x && mouseX <= x+w && mouseY >= y && mouseY <= y+h) return true;
else return false;
}
String timestamp()
{
String time, year, month, day, hour, minute, second;
year = nf( year(), 4 );
month = nf( month(), 2 );
day = nf( day(), 2 );
hour = nf( hour(), 2 );
minute = nf( minute(), 2 );
second = nf( second(), 2 );
time = year + "_" + month + "_" + day + "_" + hour + "_" + minute + "_" + second;
return time;
}
Playing again with text data. The goal was to write an effective and fast algorithm for sorting text in an alphabetical order using the 'divide and conquer' method / recursion which would work with my written 'Word' class.
Controls:
Hover circle = shows word and how often it was found in text
Space = Text on / off
H = Headline on / off
A = Animation on / off
S = Animation mode
Left / Right = Position of control points
Check video:
http://vimeo.com/31203226
Flickr:
http://www.flickr.com/photos/dianalange/sets/72157627657832455/