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: }