/*************************************************************************** Title: graphbrowser/Graph.java Author: Stefan Berghofer, TU Muenchen Options: :tabSize=4:
This class contains the core of the layout algorithm and methods for drawing and PostScript output.
***************************************************************************/
int vs=vertices.size(); boolean adj[][]=newboolean[vs][vs]; boolean adj2[][]=newboolean[vs][vs]; int i,j,k;
e1=getVertices(); for (i=0;i<vs;i++) {
vx1=(Vertex)(e1.nextElement());
e2=vx1.getChildren(); while (e2.hasMoreElements()) {
vx2=(Vertex)(e2.nextElement());
j=vertices.indexOf(vx2);
adj[i][j]=true;
adj2[i][j]=true;
}
}
/** compute transitive closure R+ **/
for (k=0;k<vs;k++) for (i=0;i<vs;i++) if (adj[i][k]) for (j=0;j<vs;j++)
adj[i][j] = adj[i][j] || adj[k][j];
/** compute R \ (R+)^2 **/
for (i=0;i<vs;i++) for (j=0;j<vs;j++) if (adj2[i][j]) {
vx1=(Vertex)(vertices.elementAt(i));
vx2=(Vertex)(vertices.elementAt(j)); for (k=0;k<vs;k++) if (adj[i][k] && adj[k][j]) {
vx1.removeChild(vx2); break;
}
}
}
public Vector insert_dummies(Vector v) {
Vector layers2=new Vector(10,10); int n_edges;
do {
Enumeration e1=v.elements(),e2;
Vector next=new Vector(10,10);
layers2.addElement(v);
n_edges=0; while (e1.hasMoreElements()) {
Vertex v1=(Vertex)(e1.nextElement());
e2=v1.getChildren(); while (e2.hasMoreElements()) {
n_edges++;
Vertex v2=(Vertex)(e2.nextElement()); if (v2.getDegree()!=v1.getDegree()+1) {
Vertex v3=new DummyVertex();
v3.addChild(v2);
v3.setDegree(v1.getDegree()+1);
v1.removeChild(v2);
v1.addChild(v3);
next.addElement(v3);
addVertex(v3);
} elseif (next.indexOf(v2)<0) next.addElement(v2);
}
}
v=next;
numEdges.addElement(Integer.valueOf(n_edges));
} while (!v.isEmpty()); return layers2;
}
/********************************************************************/ /* calculation of crossings */ /********************************************************************/
publicint count_crossings(Vector layers,int oldcr) { int i,j,y1,y2,cr=0,l; for (l=0;l<layers.size()-1;l++) {
Vector v1=(Vector)(layers.elementAt(l)); for (i=0;i<v1.size();i++) {
Enumeration e2=((Vertex)(v1.elementAt(i))).getChildren(); while (e2.hasMoreElements()) {
y1=((Vector)(layers.elementAt(l+1))).indexOf(e2.nextElement()); for (j=0;j<i;j++) {
Enumeration e3=((Vertex)(v1.elementAt(j))).getChildren(); while (e3.hasMoreElements()) {
y2=((Vector)(layers.elementAt(l+1))).indexOf(e3.nextElement()); if (y1<y2) {
cr++; if (cr>=oldcr) return cr;
}
}
}
}
}
} return cr;
}
/********************************************************************/ /* calculation of crossings where vertices vx1 and vx2 are involved */ /* vx1 and vx2 must be in same layer and vx1 is left from vx2 */ /********************************************************************/
/**** Intersection point of two lines (auxiliary function for calcSplines) ****/ /**** Calculate intersection point of line which is parallel to line (p1,p2) ****/ /**** and leads through p5, with line (p3,p4) ****/
Point intersect(Point p1,Point p2,Point p3,Point p4,Point p5) { float x=0,y=0,s1=0,s2=0;
if (p1.x!=p2.x)
s1=((float)(p2.y-p1.y))/(p2.x-p1.x); if (p3.x!=p4.x)
s2=((float)(p4.y-p3.y))/(p4.x-p3.x); if (p1.x==p2.x) {
x=p5.x;
y=s2*(p5.x-p3.x)+p3.y;
} elseif (p3.x==p4.x) {
x=p3.x;
y=s1*(p3.x-p5.x)+p5.y;
} else {
x=(p5.x*s1-p3.x*s2+p3.y-p5.y)/(s1-s2);
y=s2*(x-p3.x)+p3.y;
} returnnew Point(Math.round(x),Math.round(y));
}
/**** Calculate control points (auxiliary function for calcSplines) ****/
/*** Points p1 , p2 , p3 define a triangle which encloses the spline. ***/ /*** Check if adjacent boxes (specified by lboxx,rboxx and boxy) ***/ /*** collide with the spline. In this case p1 and p3 are shifted by an ***/ /*** appropriate offset before they are returned ***/
publicvoid draw(Graphics g) { if (box_height==0) layout(g);
g.translate(-min_x,-min_y);
Enumeration e1=vertices.elements(); while (e1.hasMoreElements())
((Vertex)(e1.nextElement())).draw(g);
e1=splines.elements(); while (e1.hasMoreElements())
((Spline)(e1.nextElement())).draw(g);
}
/********************************************************************/ /* return vertex at position (x,y) */ /********************************************************************/
public Vertex vertexAt(int x,int y) {
Enumeration e1=vertices.elements(); while (e1.hasMoreElements()) {
Vertex v=(Vertex)(e1.nextElement()); if (v.contains(x,y)) return v;
} returnnull;
}
/********************************************************************/ /* encode list of vertices (as array of vertice numbers) */ /********************************************************************/
public Vector encode(Vector v) {
Vector code=new Vector(10,10);
Enumeration e1=v.elements();
while (e1.hasMoreElements()) {
Vertex vx=(Vertex)(e1.nextElement()); if (vx.getNumber()>=0)
code.addElement(Integer.valueOf(vx.getNumber()));
} return code;
}
/********************************************************************/ /* get vertex with number n */ /********************************************************************/
public Vertex getVertexByNum(int x) {
Enumeration e1=vertices.elements();
while (e1.hasMoreElements()) {
Vertex vx=(Vertex)(e1.nextElement()); if (vx.getNumber()==x) return vx;
} returnnull;
}
/********************************************************************/ /* decode list of vertices */ /********************************************************************/
public Vector decode(Vector code) {
Enumeration e1=code.elements();
Vector vec=new Vector(10,10);
while (e1.hasMoreElements()) { int i=((Integer)(e1.nextElement())).intValue(); //Vertex vx=getVertexByNum(i); //if (vx!=null) vec.addElement(vx);
vec.addElement(vertices2[i]);
} return vec;
}
while (e1.hasMoreElements()) {
vx2=(Vertex)(e1.nextElement());
if (vs.indexOf(vx2)<0) {
e2=vx2.getParents(); while (e2.hasMoreElements()) {
vx3=(Vertex)(e2.nextElement()); if (vs.indexOf(vx3)>=0) { if (!vx1.isChild(vx2))
vx1.addChild(vx2);
vx3.removeChild(vx2);
}
}
e2=vx2.getChildren(); while (e2.hasMoreElements()) {
vx3=(Vertex)(e2.nextElement()); if (vs.indexOf(vx3)>=0) { if (!vx2.isChild(vx1))
vx2.addChild(vx1);
vx2.removeChild(vx3);
}
}
} else { nonempty=true; }
}
publicvoid PS(String fname,boolean printable) throws IOException {
FileOutputStream f = new FileOutputStream(fname);
PrintWriter p = new PrintWriter(f, true);
if (printable)
p.println("%!PS-Adobe-2.0\n\n%%BeginProlog"); else {
p.println("%!PS-Adobe-2.0 EPSF-2.0\n%%Orientation: Portrait");
p.println("%%BoundingBox: "+min_x+" "+min_y+" "+max_x+" "+max_y);
p.println("%%EndComments\n\n%%BeginProlog");
}
p.println("/m { moveto } def /l { lineto } def /n { newpath } def");
p.println("/s { stroke } def /c { curveto } def");
p.println("/b { n 0 0 m dup true charpath pathbbox 1 index 4 index sub");
p.println("7 index exch sub 2 div 9 index add 1 index 4 index sub 7 index exch sub");
p.println("2 div 9 index add 2 index add m pop pop pop pop");
p.println("1 -1 scale show 1 -1 scale n 3 index 3 index m 1 index 0 rlineto");
p.println("0 exch rlineto neg 0 rlineto closepath s pop pop } def");
p.println("%%EndProlog\n"); if (printable) { int hsize=max_x-min_x; int vsize=max_y-min_y; if (hsize>vsize) { // Landscape output double scale=Math.min(1,Math.min(750.0/hsize,500.0/vsize)); double trans_x=50+max_y*scale+(500-scale*vsize)/2.0; double trans_y=50+max_x*scale+(750-scale*hsize)/2.0;
p.println(trans_x+" "+trans_y+" translate");
p.println("-90 rotate");
p.println(scale+" "+(-scale)+" scale");
} else { // Portrait output double scale=Math.min(1,Math.min(500.0/hsize,750.0/vsize)); double trans_x=50-min_x*scale+(500-scale*hsize)/2.0; double trans_y=50+max_y*scale+(750-scale*vsize)/2.0;
p.println(trans_x+" "+trans_y+" translate");
p.println(scale+" "+(-scale)+" scale");
}
} else
p.println("0 "+(max_y+min_y)+" translate\n1 -1 scale");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.