代码
//parameters
float w=800;
float h=600;
PVector [] nodes = {};
PVector [] weights = {};
Arrow [] arrows;
//data
float[][] pos = {{1*w/6, h/2},{2*w/6, h/2},{3*w/6, 2*h/6},
{3*w/6, 4*h/6},{4*w/6, 2*h/6},{4*w/6, 4*h/6},
{5*w/6, h/2}
};
int[][] edges = {{0,1,80},{1,2,50},{1,3,30},
{3,2,10},{2,4,20},{2,5,30},
{4,5,10},{5,3,5},{2,6,10},
{4,6,10},{3,6,25},{5,6,35}};
void setup(){
size(int(w),int(h));
background(255);
smooth();
//initialize nodes
for (int i = 0; i < pos.length; i++){
nodes = (PVector[]) append(nodes, new PVector(int(pos[i][0]),int(pos[i][1])));
}
// initialize weights and arrows
arrows = new Arrow[edges.length];
for (int i = 0; i < edges.length; i++) {
int start = int(edges[i][0]);
int end = int(edges[i][1]);
float x1=nodes[start].x;
float y1=nodes[start].y;
float x2=nodes[end].x;
float y2=nodes[end].y;
float dx=x2-x1;
float dy=y2-y1;
float r=sqrt(sq(dx)+sq(dy));
arrows[i] = new Arrow(x1+20*dx/r, y1+20*dy/r, x2-20*dx/r, y2-20*dy/r, color(100));
weights = (PVector[]) append(weights, new PVector(x1+dx/2,y1+dy/2,edges[i][2]));
}
// plot nodes, labels, weights, and arrows
for (int i = 0; i < nodes.length; i++) {
//nodes
noFill();
stroke(200);
ellipseMode(RADIUS);
ellipse(nodes[i].x,nodes[i].y,20,20);
//labels
fill(50);
textSize(16);
textAlign(CENTER);
text(str(i),nodes[i].x,nodes[i].y+5);
}
//weights
for (int i = 0; i < weights.length; i++) {
fill(50);
textSize(10);
text(nf(weights[i].z,0,0),weights[i].x-20,weights[i].y);
}
//plot arrows
for (int j = 0; j < arrows.length; j++) {
arrows[j].draw();
}
//save the figure
saveFrame("/Users/csid/Documents/Processing/experiments/exampleFlowNetwork/pngs/line-######.png");
}
class Arrow {
float x1, y1, x2, y2;
color lineColor, arrowColor;
// Contructor
Arrow(float x1Temp, float y1Temp, float x2Temp, float y2Temp, color cTemp1) {
x1 = x1Temp;
y1 = y1Temp;
x2 = x2Temp;
y2 = y2Temp;
lineColor = cTemp1;
}
// Custom method for drawing the object
void draw() {
arrowLine(x1,y1, x2, y2, 0, radians(10), true, lineColor);
}
}
// arrowline function copied from http://www.openprocessing.org/sketch/7029
void arrowLine(float x0, float y0, float x1, float y1,
float startAngle, float endAngle, boolean solid, color lineColor)
{
stroke(lineColor);
line(x0, y0, x1, y1);
if (startAngle != 0)
{
arrowhead(x0, y0, atan2(y1 - y0, x1 - x0), startAngle, solid, lineColor);
}
if (endAngle != 0)
{
arrowhead(x1, y1, atan2(y0 - y1, x0 - x1), endAngle, solid, lineColor);
}
}
/*
* Draws an arrow head at given location
* x0 - arrow vertex x-coordinate
* y0 - arrow vertex y-coordinate
* lineAngle - angle of line leading to vertex (radians)
* arrowAngle - angle between arrow and line (radians)
* solid - true for a solid arrow, false for an "open" arrow
*/
void arrowhead(float x0, float y0, float lineAngle,
float arrowAngle, boolean solid, color arrowColor)
{
float phi;
float x2;
float y2;
float x3;
float y3;
final float SIZE = 20;
x2 = x0 + SIZE * cos(lineAngle + arrowAngle);
y2 = y0 + SIZE * sin(lineAngle + arrowAngle);
x3 = x0 + SIZE * cos(lineAngle - arrowAngle);
y3 = y0 + SIZE * sin(lineAngle - arrowAngle);
if (solid)
{
noStroke();
fill(arrowColor);
triangle(x0, y0, x2, y2, x3, y3);
}
else
{
line(x0, y0, x2, y2);
line(x0, y0, x3, y3);
}
}