Back to index

moin  1.9.0~rc2
ShortestDistanceConnector.java
Go to the documentation of this file.
00001 /*
00002  * @(#)ShortestDistanceConnector.java 5.1
00003  *
00004  */
00005 
00006 package CH.ifa.draw.figures;
00007 
00008 import java.awt.*;
00009 import CH.ifa.draw.framework.*;
00010 import CH.ifa.draw.standard.*;
00011 import CH.ifa.draw.util.Geom;
00012 
00021 public class ShortestDistanceConnector extends AbstractConnector {
00022 
00023     /*
00024      * Serialization support.
00025      */
00026     private static final long serialVersionUID = -2273446020593433887L;
00027 
00028     public ShortestDistanceConnector() { // only used for Storable implementation
00029         super();
00030     }
00031 
00032     public ShortestDistanceConnector(Figure owner) {
00033         super(owner);
00034     }
00035 
00036     public Point findStart(ConnectionFigure connection) {
00037         return findPoint(connection, true);
00038     }
00039 
00040     public Point findEnd(ConnectionFigure connection) {
00041         return findPoint(connection, false);
00042     }
00043 
00044     protected Point findPoint(ConnectionFigure connection, boolean getStart) {
00045         Figure startFigure = connection.start().owner();
00046         Figure endFigure = connection.end().owner();
00047 
00048         Rectangle r1 = startFigure.displayBox();
00049         Rectangle r2 = endFigure.displayBox();
00050 
00051         Insets i1 = startFigure.connectionInsets();
00052         Insets i2 = endFigure.connectionInsets();
00053 
00054         Point p1, p2;
00055         Point start = null, end = null, s = null, e = null;
00056         long len2 = Long.MAX_VALUE, l2;
00057         int x1, x2, y1, y2; // connection points
00058         int xmin, xmax, ymin, ymax;
00059 
00060         // X-dimension
00061         // constrain width connection insets
00062         int r1x, r1width, r2x, r2width, r1y, r1height, r2y, r2height;
00063         r1x = r1.x + i1.left;
00064         r1width = r1.width - i1.left - i1.right-1;
00065         r2x = r2.x + i2.left;
00066         r2width = r2.width - i2.left - i2.right-1;
00067 
00068         // find x connection point
00069         if (r1x + r1width < r2x) {
00070             x1 = r1x + r1width;
00071             x2 = r2x;
00072         } else if (r1x > r2x + r2width) {
00073             x1 = r1x;
00074             x2 = r2x + r2width;
00075         } else {
00076             xmax = Math.max(r1x, r2x);
00077             xmin = Math.min(r1x+r1width, r2x+r2width);
00078             x1 = x2 = (xmax + xmin) /2;
00079         }
00080 
00081         // Y-Dimension
00082         // constrain with connection insets
00083         r1y = r1.y + i1.top;
00084         r1height = r1.height - i1.top - i1.bottom-1;
00085         r2y = r2.y + i2.top;
00086         r2height = r2.height - i2.top - i2.bottom-1;
00087 
00088         // y connection point
00089         if (r1y + r1height < r2y) {
00090             y1 = r1y + r1height;
00091             y2 = r2y;
00092         } else if (r1y > r2y + r2height) {
00093             y1 = r1y;
00094             y2 = r2y + r2height;
00095         } else {
00096             ymax = Math.max(r1y, r2y);
00097             ymin = Math.min(r1y+r1height, r2y+r2height);
00098             y1 = y2 = (ymax + ymin) /2;
00099         }
00100         // find shortest connection
00101         for (int i = 0; i < 4; i++) {
00102             switch(i) {
00103             case 0:
00104                 // EAST-WEST
00105                 p1 = Geom.east(r1);
00106                 p2 = Geom.west(r2);
00107                 s = new Point(p1.x, y1);
00108                 e = new Point(p2.x, y2);
00109                 break;
00110             case 1:
00111                 // WEST-EAST
00112                 p1 = Geom.west(r1);
00113                 p2 = Geom.east(r2);
00114                 s = new Point(p1.x, y1);
00115                 e = new Point(p2.x, y2);
00116                 break;
00117             case 2:
00118                 // NORTH-SOUTH
00119                 p1 = Geom.north(r1);
00120                 p2 = Geom.south(r2);
00121                 s = new Point(x1, p1.y);
00122                 e = new Point(x2, p2.y);
00123                 break;
00124             case 3:
00125                 // SOUTH-NORTH
00126                 p1 = Geom.south(r1);
00127                 p2 = Geom.north(r2);
00128                 s = new Point(x1, p1.y);
00129                 e = new Point(x2, p2.y);
00130                 break;
00131             }
00132             l2 = Geom.length2(s.x, s.y, e.x, e.y);
00133             if (l2 < len2) {
00134                 start = s;
00135                 end = e;
00136                 len2 = l2;
00137             }
00138         }
00139         if (getStart)
00140             return start;
00141         return end;
00142     }
00143 
00144 }
00145