「proce55ing-gr02/pg01」の編集履歴(バックアップ)一覧はこちら
追加された行は緑色になります。
削除された行は赤色になります。
[[Processingでgraph 02>proce55ing-gr02]]に戻る
#highlight(c){{//*- This program is VisualizingData's p239-243 -*//
int nodeCount;
Node[] nodes = new Node[100];
HashMap nodeTable = new HashMap();
int edgeCount;
Edge[] edges = new Edge[500];
static final color nodeColor = #F0C070; //node box background color
static final color selectColor = #FF3030; //dragging color
static final color fixedColor = #FF8080; //click->固定color
static final color edgeColor = #000000; //line color
PFont font;
void setup(){
size(600, 600);
loadData();
font = createFont("SansSerif", 10);
textFont(font);
smooth();
}
void loadData(){
String[] lines = loadStrings("huckfinn.txt");
// テキストを単一のStringオブジェクトにする
String line = join(lines, " ");
// 「--」を実際のemダッシュで置き換える
line = line.replaceAll("--", "\u2014");
// 指定のデリミタを区切りに句に分割
String[] phrases = splitTokens(line, ".,;:?!\u2014\"");
for (int i = 0; i < phrases.length; i++){
// この句を小文字にする
String phrase = phrases[i].toLowerCase();
// 各句を1つ以上のスペース文字で個々の単語に分割
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){
// 不要な単語を除去**
if (ignoreWord(fromLabel) || ignoreWord(toLabel)) return;
Node from = findNode(fromLabel);
Node to = findNode(toLabel);
from.increment(); // **
to.increment();
// このEdgeがすでに存在するかどうかをチェック**
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;
}
String[] ignore = { "a", "of", "the", "i", "it", "you", "and", "to"};
boolean ignoreWord(String what){
for (int i = 0; i < ignore.length; i++){
if (what.equals(ignore[i])){
return true;
}
}
return false;
}
// ラベルからノードを見つける
Node findNode(String label){
label = label.toLowerCase();
Node n = (Node) nodeTable.get(label);
if (n == null){
return addNode(label);
}
return n;
}
// 名前での検索を可能にするためnodeTableへの追加も
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();
}
for (int i = 0 ; i < nodeCount ; i++){
nodes[i].draw();
}
}
//*- マウスでノード操作できるように -*//
Node selection;
void mousePressed(){
// これ以上に離れているノードはすべて無視
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;
}
}
void mouseReleased(){
selection = null;
}
class Edge{
Node from;
Node to;
float len;
Edge(Node from, Node to){
this.from = from;
this.to = to;
this.len = 50;
}
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;
}
}
// **
int count;
void increment(){
count++;
}
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;
Node(String label){
this.label = label;
x = random(width);
y = random(height);
}
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) /2;
if (dlen > 0){
dx += ddx /dlen;
dy += ddy /dlen;
}
}
void update(){
if (!fixed){
x += constrain(dx, -5, 5);
y += constrain(dy, -5, 5);
x = constrain(x, 0, width);
y = constrain(y, 0, height);
}
dx /= 2;
dy /= 2;
}
// **
int count;
void increment(){
count++;
}
void draw(){
if (selection == this){
fill(selectColor);
} else if (fixed){
fill(fixedColor);
} else {
fill(nodeColor);
}
stroke(0);
strokeWeight(0.5);
rectMode(CORNER);
float w = textWidth(label) + 10;
float h = textAscent() + textDescent() + 4;
rect(x - w/2, y - h/2, w, h);
fill(0);
textAlign(CENTER, CENTER);
text(label, x, y);
}
}
}}
----
←←【[[Processingでgraph 02>proce55ing-gr02]]に戻る】
#highlight(c){{//*- This program is VisualizingData's p239-243 -*//
int nodeCount;
Node[] nodes = new Node[100];
HashMap nodeTable = new HashMap();
int edgeCount;
Edge[] edges = new Edge[500];
static final color nodeColor = #F0C070; //node box background color
static final color selectColor = #FF3030; //dragging color
static final color fixedColor = #FF8080; //click->固定color
static final color edgeColor = #000000; //line color
PFont font;
void setup(){
size(600, 600);
loadData();
font = createFont("SansSerif", 10);
textFont(font);
smooth();
}
void loadData(){
String[] lines = loadStrings("huckfinn.txt");
// テキストを単一のStringオブジェクトにする
String line = join(lines, " ");
// 「--」を実際のemダッシュで置き換える
line = line.replaceAll("--", "\u2014");
// 指定のデリミタを区切りに句に分割
String[] phrases = splitTokens(line, ".,;:?!\u2014\"");
for (int i = 0; i < phrases.length; i++){
// この句を小文字にする
String phrase = phrases[i].toLowerCase();
// 各句を1つ以上のスペース文字で個々の単語に分割
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){
// 不要な単語を除去**
if (ignoreWord(fromLabel) || ignoreWord(toLabel)) return;
Node from = findNode(fromLabel);
Node to = findNode(toLabel);
from.increment(); // **
to.increment();
// このEdgeがすでに存在するかどうかをチェック**
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;
}
String[] ignore = { "a", "of", "the", "i", "it", "you", "and", "to"};
boolean ignoreWord(String what){
for (int i = 0; i < ignore.length; i++){
if (what.equals(ignore[i])){
return true;
}
}
return false;
}
// ラベルからノードを見つける
Node findNode(String label){
label = label.toLowerCase();
Node n = (Node) nodeTable.get(label);
if (n == null){
return addNode(label);
}
return n;
}
// 名前での検索を可能にするためnodeTableへの追加も
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();
}
for (int i = 0 ; i < nodeCount ; i++){
nodes[i].draw();
}
}
//*- マウスでノード操作できるように -*//
Node selection;
void mousePressed(){
// これ以上に離れているノードはすべて無視
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;
}
}
void mouseReleased(){
selection = null;
}
class Edge{
Node from;
Node to;
float len;
Edge(Node from, Node to){
this.from = from;
this.to = to;
this.len = 50;
}
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;
}
}
// **
int count;
void increment(){
count++;
}
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;
Node(String label){
this.label = label;
x = random(width);
y = random(height);
}
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) /2;
if (dlen > 0){
dx += ddx /dlen;
dy += ddy /dlen;
}
}
void update(){
if (!fixed){
x += constrain(dx, -5, 5);
y += constrain(dy, -5, 5);
x = constrain(x, 0, width);
y = constrain(y, 0, height);
}
dx /= 2;
dy /= 2;
}
// **
int count;
void increment(){
count++;
}
void draw(){
if (selection == this){
fill(selectColor);
} else if (fixed){
fill(fixedColor);
} else {
fill(nodeColor);
}
stroke(0);
strokeWeight(0.5);
rectMode(CORNER);
float w = textWidth(label) + 10;
float h = textAscent() + textDescent() + 4;
rect(x - w/2, y - h/2, w, h);
fill(0);
textAlign(CENTER, CENTER);
text(label, x, y);
}
}
}}
----