1: import java.awt.geom.Point2D; 2: import java.awt.geom.Rectangle2D; 3: import java.util.ArrayList; 5: /** 6: A style for a segmented line that indicates the number 7: and sequence of bends. 8: */ 9: public enum BentStyle 10: { 11: STRAIGHT, HV, VH, HVH, VHV; 13: /** 14: Gets the points at which a line joining two rectangles 15: is bent according to this bent style. 16: @param start the starting rectangle 17: @param end the ending rectangle 18: @return an array list of points at which to bend the 19: segmented line joining the two rectangles 20: */ 21: public ArrayList<Point2D> getPath(Rectangle2D start, Rectangle2D end) 22: { 23: ArrayList<Point2D> r = getPath(this, start, end); 24: if (r != null) return r; 26: if (this == HVH) r = getPath(VHV, start, end); 27: else if (this == VHV) r = getPath(HVH, start, end); 28: else if (this == HV) r = getPath(VH, start, end); 29: else if (this == VH) r = getPath(HV, start, end); 30: if (r != null) return r; 32: return getPath(STRAIGHT, start, end); 33: } 35: /** 36: Gets the four connecting points at which a bent line 37: connects to a rectangle. 38: */ 39: private static Point2D[] connectionPoints(Rectangle2D r) 40: { 41: Point2D[] a = new Point2D[4]; 42: a[0] = new Point2D.Double(r.getX(), r.getCenterY()); 43: a[1] = new Point2D.Double(r.getMaxX(), r.getCenterY()); 44: a[2] = new Point2D.Double(r.getCenterX(), r.getY()); 45: a[3] = new Point2D.Double(r.getCenterX(), r.getMaxY()); 46: return a; 47: } 49: /** 50: Gets the points at which a line joining two rectangles 51: is bent according to a bent style. 52: @param start the starting rectangle 53: @param end the ending rectangle 54: @return an array list of points at which to bend the 55: segmented line joining the two rectangles 56: */ 57: private static ArrayList<Point2D> getPath(BentStyle bent, 58: Rectangle2D s, Rectangle2D e) 59: { 60: ArrayList<Point2D> r = new ArrayList<Point2D>(); 61: if (bent == STRAIGHT) 62: { 63: Point2D[] a = connectionPoints(s); 64: Point2D[] b = connectionPoints(e); 65: Point2D p = a[0]; 66: Point2D q = b[0]; 67: double distance = p.distance(q); 68: //for (int i = 0; i < a.length; i++) 69: for (Point2D point1 : a) 70: //for (int j = 0; j < b.length; j++) 71: for (Point2D point2 : b) 72: { 73: double d = point1.distance(point2); 74: if (d < distance) 75: { 76: p = point1; q = point2; 77: distance = d; 78: } 79: } 80: r.add(p); 81: r.add(q); 82: } 83: else if (bent == HV) 84: { 85: double x1; 86: double x2 = e.getCenterX(); 87: double y1 = s.getCenterY(); 88: double y2; 89: if (x2 + MIN_SEGMENT <= s.getX()) 90: x1 = s.getX(); 91: else if (x2 - MIN_SEGMENT >= s.getMaxX()) 92: x1 = s.getMaxX(); 93: else return null; 94: if (y1 + MIN_SEGMENT <= e.getY()) 95: y2 = e.getY(); 96: else if (y1 - MIN_SEGMENT >= e.getMaxY()) 97: y2 = e.getMaxY(); 98: else return null; 99: r.add(new Point2D.Double(x1, y1)); 100: r.add(new Point2D.Double(x2, y1)); 101: r.add(new Point2D.Double(x2, y2)); 102: } 103: else if (bent == VH) 104: { 105: double x1 = s.getCenterX(); 106: double x2; 107: double y1; 108: double y2 = e.getCenterY(); 109: if (x1 + MIN_SEGMENT <= e.getX()) 110: x2 = e.getX(); 111: else if (x1 - MIN_SEGMENT >= e.getMaxX()) 112: x2 = e.getMaxX(); 113: else return null; 114: if (y2 + MIN_SEGMENT <= s.getY()) 115: y1 = s.getY(); 116: else if (y2 - MIN_SEGMENT >= s.getMaxY()) 117: y1 = s.getMaxY(); 118: else return null; 119: r.add(new Point2D.Double(x1, y1)); 120: r.add(new Point2D.Double(x1, y2)); 121: r.add(new Point2D.Double(x2, y2)); 122: } 123: else if (bent == HVH) 124: { 125: double x1; 126: double x2; 127: double y1 = s.getCenterY(); 128: double y2 = e.getCenterY(); 129: if (s.getMaxX() + 2 * MIN_SEGMENT <= e.getX()) 130: { 131: x1 = s.getMaxX(); 132: x2 = e.getX(); 133: } 134: else if (e.getMaxX() + 2 * MIN_SEGMENT <= s.getX()) 135: { 136: x1 = s.getX(); 137: x2 = e.getMaxX(); 138: } 139: else return null; 140: if (Math.abs(y1 - y2) <= MIN_SEGMENT) 141: { 142: r.add(new Point2D.Double(x1, (y1 + y2) / 2)); 143: r.add(new Point2D.Double(x2, (y1 + y2) / 2)); 144: } 145: else 146: { 147: r.add(new Point2D.Double(x1, y1)); 148: r.add(new Point2D.Double((x1 + x2) / 2, y1)); 149: r.add(new Point2D.Double((x1 + x2) / 2, y2)); 150: r.add(new Point2D.Double(x2, y2)); 151: } 152: } 153: else if (bent == VHV) 154: { 155: double x1 = s.getCenterX(); 156: double x2 = e.getCenterX(); 157: double y1; 158: double y2; 159: if (s.getMaxY() + 2 * MIN_SEGMENT <= e.getY()) 160: { 161: y1 = s.getMaxY(); 162: y2 = e.getY(); 163: } 164: else if (e.getMaxY() + 2 * MIN_SEGMENT <= s.getY()) 165: { 166: y1 = s.getY(); 167: y2 = e.getMaxY(); 169: } 170: else return null; 171: if (Math.abs(x1 - x2) <= MIN_SEGMENT) 172: { 173: r.add(new Point2D.Double((x1 + x2) / 2, y1)); 174: r.add(new Point2D.Double((x1 + x2) / 2, y2)); 175: } 176: else 177: { 178: r.add(new Point2D.Double(x1, y1)); 179: r.add(new Point2D.Double(x1, (y1 + y2) / 2)); 180: r.add(new Point2D.Double(x2, (y1 + y2) / 2)); 181: r.add(new Point2D.Double(x2, y2)); 182: } 183: } 184: else return null; 185: return r; 186: } 188: private static final int MIN_SEGMENT = 10; 189: }