package structure; import java.util.*; import java.awt.*; import java.lang.Math; import java.awt.geom.*; import javax.swing.*; public class Edge { Node from; Node to; double w,h; String lbl; String text; //dexcription Color clr; int type; // 2-- backward B 1-- forward 0--undirected Bubble hint; Point start, end; public Edge(){ hint = null; w=0; h=0; } public Bubble getHint(){ return hint; } public Bubble addBubbleAttr(String s, Color c){ String[]t = new String[1]; t[0]=s; hint=new Bubble(); hint.text = t; // dont forget to change Bubble constructor hint.setColor(c); return hint; } public boolean contains(Point p){ double dist; Line2D.Double line = new Line2D.Double(start.x,start.y,end.x,end.y); dist = line.ptSegDist(p); System.out.println(dist); if (dist > 15.0) return false; else return true; } public void setColor(Color c){ clr = c; } //draws the edge on the screen public void paintComponent(Graphics g){ Graphics2D g2 = (Graphics2D)g; BasicStroke stroke = new BasicStroke(4.0f); double slope; int x1,y1,x2,y2; // draw the lines x1 = (int)from.x; y1 = (int)from.y; x2 = (int)to.x; y2 = (int)to.y; g2.setStroke(stroke); g2.setPaint(clr); //slope determines the type of the line: vertical/horizontal/left/right if ((x1-x2)==0) slope=0.0; //vertical else if ((y1-y2)==0) slope=1.0; //horizontal else if ( (y1-y2)/(x1-x2)>0) slope =2.0; //right else slope =3; //left //System.out.println("slope" + slope); if(slope==0) // vertical switch (type){ case 1 : start = new Point(x1-4, y1); end = new Point(x2-4, y2); break; //F case 2 : start = new Point(x1+4, y1); end = new Point(x2+4, y2); break; //B case 0 : start = new Point (x1, y1); end = new Point(x2, y2); break; } else // horizontal if(slope == 1.0) // "--" switch (type){ case 1 : start = new Point(x1, y1-4); end = new Point(x2, y2-4); break; //F case 2 : start = new Point(x1, y1+4); end = new Point (x2, y2+4); break; //B case 0 : start = new Point (x1, y1); end = new Point( x2, y2); break; } else // "\" if(slope == 3.0) // "\" switch (type){ case 1 : start = new Point(x1-4, y1-4); end = new Point( x2-4, y2-4); break; //F case 2 : start = new Point(x1+4, y1+4); end = new Point(x2+4, y2+4); break; //B case 0 : start = new Point(x1, y1); end = new Point(x2, y2); break; } else // "\" if(slope==2.0) switch(type){ case 1 : start = new Point(x1-4, y1+4); end = new Point( x2-4, y2+4); break; //F case 2 : start = new Point(x1+4, y1-4); end = new Point(x2+4, y2-4); break; //B case 0 : start = new Point(x1, y1); end = new Point(x2, y2); break; } else System.out.println("error in slope"); to.w = to.w+10; to.h = to.h+10; from.w = from.w+10; from.h = from.h+10; //check the node side for intersection Line2D.Double line = new Line2D.Double(start.x,start.y,end.x,end.y); if (line.intersectsLine(to.x-to.w/2,to.y-to.h/2,to.x-to.w/2,to.y+to.h/2)) end =intersection(line.x1,line.y1,line.x2,line.y2,to.x-to.w/2, to.y-to.h/2,to.x-to.w/2,to.y+to.h/2); else if(line.intersectsLine(to.x+to.w/2,to.y-to.h/2,to.x+to.w/2,to.y+to.h/2)) end =intersection(line.x1,line.y1,line.x2,line.y2,to.x+to.w/2, to.y-to.h/2,to.x+to.w/2,to.y+to.h/2); else if(line.intersectsLine(to.x-to.w/2,to.y-to.h/2,to.x+to.w/2,to.y-to.h/2)) end =intersection(line.x1,line.y1,line.x2,line.y2,to.x-to.w/2, to.y-to.h/2,to.x+to.w/2,to.y-to.h/2); else if (line.intersectsLine(to.x-to.w/2,to.y+to.h/2,to.x+to.w/2,to.y+to.h/2)) end =intersection(line.x1,line.y1,line.x2,line.y2,to.x-to.w/2, to.y+to.h/2,to.x+to.w/2,to.y+to.h/2); else System.out.println("error: no end intersection"); if(line.intersectsLine(from.x-from.w/2,from.y-from.h/2,from.x-from.w/2,from.y+from.h/2)) start=intersection(line.x1,line.y1,line.x2,line.y2,from.x-from.w/2, from.y-from.h/2,from.x-from.w/2,from.y+from.h/2); else if(line.intersectsLine(from.x+from.w/2,from.y-from.h/2,from.x+from.w/2,from.y+from.h/2)) start=intersection(line.x1,line.y1,line.x2,line.y2,from.x+from.w/2, from.y-from.h/2,from.x+from.w/2,from.y+from.h/2); else if(line.intersectsLine(from.x-from.w/2,from.y-from.h/2,from.x+from.w/2,from.y-from.h/2)) start=intersection(line.x1,line.y1,line.x2,line.y2,from.x-from.w/2, from.y-from.h/2,from.x+from.w/2,from.y-from.h/2); else if(line.intersectsLine(from.x-from.w/2,from.y+from.h/2,from.x+from.w/2,from.y+from.h/2)) start=intersection(line.x1,line.y1,line.x2,line.y2,from.x-from.w/2, from.y+from.h/2,from.x+from.w/2,from.y+from.h/2); else System.out.println("error: no start intersection"); to.w = to.w-10; to.h = to.h-10; from.w = from.w-10; from.h = from.h-10; g2.draw(new Line2D.Double(start.x, start.y, end.x, end.y)); g2.draw(new Ellipse2D.Double(end.x-4, end.y-4, 8, 8)); } public void drawBubble(Graphics g){ Rectangle box = new Rectangle(new Point((int)Math.min(from.x,to.x),(int)Math.min(from.y,to.y))); int centerX,centerY; //calculate center pt of a line box.add(from.x,from.y); box.add(to.x,to.y); centerX = box.x+box.width/2; centerY = box.y+box.height/2; //check the node side for intersection Line2D.Double line = new Line2D.Double(from.x,from.y,to.x,to.y); /* g.setColor(Color.pink); g.drawRect(box.x,box.y,box.width,box.height); g.drawString("x",centerX,centerY); */ //draw bubble int dx = (int)from.x -(int)to.x; int dy = (int)from.y -(int)to.y; if(hint.text!=null){ if(dx==0) if (type==1) hint.paintComponent(g,centerX-30,centerY-20); else hint.paintComponent(g,centerX+20,centerY+20); else if (dy==0) if (type==1) hint.paintComponent(g,centerX,centerY-50); else hint.paintComponent(g,centerX,centerY+15); else { double slope = (double)dy/dx; if (slope < 0.0) if (type==1) hint.paintComponent(g,centerX-40,centerY-20); else hint.paintComponent(g,centerX+10,centerY+20); else if (type==1) hint.paintComponent(g,centerX-20,centerY+20); else hint.paintComponent(g,centerX+20,centerY-20); } } } public Point intersection(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4){ double slope1; double slope2; double x,y; if((x1-x2==0)&&(y3-y4==0)) return new Point((int)x1,(int)y3); if((x3-x4==0)&&(y1-y2==0)) return new Point((int)x3,(int)y1); if (x3-x4==0) { x=x3; slope1 = (y1-y2)/(x1-x2); y = y1+slope1*x-slope1*x1; return new Point((int)x,(int)y); } if (x1-x2==0) { slope2 = (y3-y4)/(x3-x4); x=x1; y=y3+slope2*x-slope2*x3; return new Point((int)x,(int)y); } slope2 = (y3-y4)/(x3-x4); slope1 = (y1-y2)/(x1-x2); /* will never be parallel if (slope1-slope2==0.0)&&(slope1!=0)&&(slope2!=0) { System.out.println("lines are parallel"); return new Point(50,50); } */ x = (y3-y1+slope1*x1-slope2*x3)/(slope1-slope2); y = y1+slope1*x-slope1*x1; return new Point((int)x,(int)y); } public void drawArrow(Graphics g){ Graphics2D g2 = (Graphics2D)g; BasicStroke stroke = new BasicStroke(4.0f); // Create a triangle using a general path object GeneralPath p = new GeneralPath(GeneralPath.WIND_NON_ZERO); p.moveTo( +100.0f, +100.0f); p.lineTo( +200.0f, +100.0f); p.lineTo( +150.0f, +200.0f); p.closePath(); // translate origin towards center of canvas //g2.translate(100.0f, 100.0f); // render the star's path g2.fill(p); } }