class Edge {
Node from;
Node to;
float len;
int count;
Edge(Node from, Node to) {
this.from = from;
this.to = to;
this.len = 50;// vierkanten komen bij elkaar
}
void increment() {
count++;
}
void relax() {
float vx = to.x - from.x;
float vy = to.y - from.y;
float d = mag(vx, vy);
if (d > 0) {
float f = (len - d) / (d * 3);
float dx = f * vx;
float dy = f * vy;
to.dx += dx;
to.dy += dy;
from.dx -= dx;
from.dy -= dy;
}
}
void draw() {
stroke(edgeColor);
//strokeWeight(0.35);
//line(from.x, from.y, to.x, to.y);
}
}
class Node {
float x, y;
float dx, dy;
boolean fixed;
String label;
int count;
Node(String label) {
this.label = label;
x = random(width);
y = random(height);
}
void increment() {
count++;
}
void relax() {
float ddx = 0;
float ddy = 0;
for (int j = 0; j < nodeCount; j++) {
Node n = nodes[j];
if (n != this) {
float vx = x - n.x;
float vy = y - n.y;
float lensq = vx * vx + vy * vy;
if (lensq == 0) {
ddx += random(1);
ddy += random(1);
} else if (lensq < 100*100) {
ddx += vx / lensq;
ddy += vy / lensq;
}
}
}
float dlen = mag(ddx, ddy) / 150;// groote van de blokjes circel
if (dlen < 100) {
dx += ddx / dlen;
dy += ddy / dlen;
} else if (dlen < 100) {
dx += ddx / dlen;
dy += ddy / dlen;
}
}
void update() {
if (!fixed) {
x += constrain(dx, -5, 5);
y += constrain(dy, -5, 5);
x = constrain(x, 10, width);
y = constrain(y, 10, height);
} else if (!fixed) {
x += constrain(dx, -15, 25);
y += constrain(dy, -15, 25);
x = constrain(x, 20, width);
y = constrain(y, 20, height);
}else if (!fixed) {
x += constrain(dx, -20, 35);
y += constrain(dy, -25, 25);
x = constrain(x, 30, width);
y = constrain(y, 30, height);
}
//dx /= 2;
//dy /= 2;
}
void draw() { //vierkantje wordt getekend
fill(nodeColor);
stroke(0);
strokeWeight(1);
ellipse(x, y, count, count);
float w = textWidth(label);
if (count <= w-70) {
fill(0);
textAlign(CENTER, CENTER);
text(label, x, y);
println(edgeCount);
}
//test
else if (count > w-10) {
fill(#000000);
text(label, 50, y);
text(label, 950, y);
}
else if (count > w-20) {
fill(#000000);
text(label, 950, y);
}
else if (count > w-15) {
fill(#000000);
text(label, x, 50);
}
}
}
int nodeCount;
Node[] nodes = new Node[100];
HashMap nodeTable = new HashMap();
int edgeCount;
Edge[] edges = new Edge[100];
static final color nodeColor = #ffffff;
static final color selectColor = #FF3030;
static final color fixedColor = #FF8080;
static final color edgeColor = #00ff00;
PFont font;
int engines;
void setup() {
size(1000, 1000);
loadData();
println(edgeCount);
font = createFont("SansSerif", 10);
textFont(font);
smooth();
//engine = new ParticleEngine();
}
void loadData() {
String[] lines = loadStrings("huckfinn.txt");
// Make the text into a single String object
String line = join(lines, " ");
// Replace -- with an actual em dash
line = line.replaceAll("--", "\u2014");
// Split into phrases using any of the provided tokens
String[] phrases = splitTokens(line, ".,;:?!\u2014\"");
//println(phrases);
for (int i = 0; i < phrases.length; i++) {
// Make this phrase lowercase
String phrase = phrases[i].toLowerCase();
// Split each phrase into individual words at one or more spaces
String[] words = splitTokens(phrase, " ");
for (int w = 0; w < words.length-1; w++) {
addEdge(words[w], words[w+1]);
}
}
}
void addEdge(String fromLabel, String toLabel) {
// Filter out unnecessary words
Node from = findNode(fromLabel);
Node to = findNode(toLabel);
from.increment();
to.increment();
for (int i = 0; i < edgeCount; i++) {
if (edges[i].from == from && edges[i].to == to) {
edges[i].increment();
return;
}
}
Edge e = new Edge(from, to);
e.increment();
if (edgeCount == edges.length) {
edges = (Edge[]) expand(edges);
}
edges[edgeCount++] = e;
}
Node findNode(String label) {
label = label.toLowerCase();
Node n = (Node) nodeTable.get(label);
if (n == null) {
return addNode(label);
}
return n;
}
Node addNode(String label) {
Node n = new Node(label);
if (nodeCount == nodes.length) {
nodes = (Node[]) expand(nodes);
}
nodeTable.put(label, n);
nodes[nodeCount++] = n;
return n;
}
void draw() {
background(255);
for (int i = 0 ; i < edgeCount ; i++) {
edges[i].relax();
}
for (int i = 0; i < nodeCount; i++) {
nodes[i].relax();
}
for (int i = 0; i < nodeCount; i++) {
nodes[i].update();
}
for (int i = 0 ; i < edgeCount ; i++) {
edges[i].draw();
fill(#000000);
}
for (int i = 0 ; i < nodeCount ; i++) {
nodes[i].draw();
}
if (record) {
endRecord();
record = false;
}
}
boolean record;
void keyPressed() {
if (key == 'r') {
record = true;
}
}
Node selection;
void mousePressed() {
// println(wordsCount);
//engine.createExplosion(mouseX, mouseY);
// Ignore anything greater than this distance
float closest = 20;
for (int i = 0; i < nodeCount; i++) {
Node n = nodes[i];
float d = dist(mouseX, mouseY, n.x, n.y);
if (d < closest) {
selection = n;
closest = d;
}
}
if (selection != null) {
if (mouseButton == LEFT) {
selection.fixed = true;
} else if (mouseButton == RIGHT) {
selection.fixed = false;
}
}
}
void mouseDragged() {
if (selection != null) {
selection.x = mouseX;
selection.y = mouseY;
fill(#00ff00);
}
}
void mouseReleased() {
selection = null;
}