1
2
3
4
5
6
7
8
9
10 package edu.uci.ics.jung.visualization.renderers;
11
12 import java.awt.Shape;
13 import java.awt.geom.AffineTransform;
14 import java.awt.geom.GeneralPath;
15 import java.awt.geom.Line2D;
16 import java.awt.geom.PathIterator;
17 import java.awt.geom.Point2D;
18
19 import edu.uci.ics.jung.visualization.RenderContext;
20
21 public class CenterEdgeArrowRenderingSupport<V,E> implements EdgeArrowRenderingSupport<V,E> {
22
23 public AffineTransform getArrowTransform(RenderContext<V,E> rc, Shape edgeShape, Shape vertexShape) {
24 GeneralPath path = new GeneralPath(edgeShape);
25 float[] seg = new float[6];
26 Point2D p1=null;
27 Point2D p2=null;
28 AffineTransform at = new AffineTransform();
29
30 int middleSegment = 0;
31 int current = 0;
32 for(PathIterator i=path.getPathIterator(null,1); !i.isDone(); i.next()) {
33 current++;
34 }
35 middleSegment = current/2;
36
37 current = 0;
38 for(PathIterator i=path.getPathIterator(null,1); !i.isDone(); i.next()) {
39 current++;
40 int ret = i.currentSegment(seg);
41 if(ret == PathIterator.SEG_MOVETO) {
42 p2 = new Point2D.Float(seg[0],seg[1]);
43 } else if(ret == PathIterator.SEG_LINETO) {
44 p1 = p2;
45 p2 = new Point2D.Float(seg[0],seg[1]);
46 }
47 if(current > middleSegment) {
48 at = getArrowTransform(rc, new Line2D.Float(p1,p2),vertexShape);
49 break;
50 }
51
52 }
53 return at;
54 }
55
56 public AffineTransform getReverseArrowTransform(RenderContext<V,E> rc, Shape edgeShape, Shape vertexShape) {
57 return getReverseArrowTransform(rc, edgeShape, vertexShape, true);
58 }
59
60
61
62
63
64
65
66
67
68
69 public AffineTransform getReverseArrowTransform(RenderContext<V,E> rc, Shape edgeShape, Shape vertexShape,
70 boolean passedGo) {
71 GeneralPath path = new GeneralPath(edgeShape);
72 float[] seg = new float[6];
73 Point2D p1=null;
74 Point2D p2=null;
75 AffineTransform at = new AffineTransform();
76
77 int middleSegment = 0;
78 int current = 0;
79 for(PathIterator i=path.getPathIterator(null,1); !i.isDone(); i.next()) {
80 current++;
81 }
82 middleSegment = current/2;
83
84 current = 0;
85 for(PathIterator i=path.getPathIterator(null,1); !i.isDone(); i.next()) {
86 current++;
87 int ret = i.currentSegment(seg);
88 if(ret == PathIterator.SEG_MOVETO) {
89 p2 = new Point2D.Float(seg[0],seg[1]);
90 } else if(ret == PathIterator.SEG_LINETO) {
91 p1 = p2;
92 p2 = new Point2D.Float(seg[0],seg[1]);
93 }
94 if(current > middleSegment) {
95 at = getReverseArrowTransform(rc, new Line2D.Float(p1,p2),vertexShape);
96 break;
97 }
98 }
99 return at;
100 }
101
102 public AffineTransform getArrowTransform(RenderContext<V,E> rc, Line2D edgeShape, Shape vertexShape) {
103
104
105 Line2D left = new Line2D.Float();
106 Line2D right = new Line2D.Float();
107 this.subdivide(edgeShape, left, right);
108 edgeShape = right;
109 float dx = (float) (edgeShape.getX1()-edgeShape.getX2());
110 float dy = (float) (edgeShape.getY1()-edgeShape.getY2());
111 double atheta = Math.atan2(dx,dy)+Math.PI/2;
112 AffineTransform at =
113 AffineTransform.getTranslateInstance(edgeShape.getX1(), edgeShape.getY1());
114 at.rotate(-atheta);
115 return at;
116 }
117
118 protected AffineTransform getReverseArrowTransform(RenderContext<V,E> rc,
119 Line2D edgeShape, Shape vertexShape) {
120
121 Line2D left = new Line2D.Float();
122 Line2D right = new Line2D.Float();
123 this.subdivide(edgeShape, left, right);
124 edgeShape = right;
125 float dx = (float) (edgeShape.getX1()-edgeShape.getX2());
126 float dy = (float) (edgeShape.getY1()-edgeShape.getY2());
127
128 double atheta = Math.atan2(dx,dy)-Math.PI/2;
129 AffineTransform at = AffineTransform.getTranslateInstance(edgeShape.getX1(),edgeShape.getY1());
130 at.rotate(-atheta);
131 return at;
132 }
133
134
135
136
137
138
139
140
141 protected void subdivide(Line2D src,
142 Line2D left,
143 Line2D right) {
144 double x1 = src.getX1();
145 double y1 = src.getY1();
146 double x2 = src.getX2();
147 double y2 = src.getY2();
148
149 double mx = x1 + (x2-x1)/2.0;
150 double my = y1 + (y2-y1)/2.0;
151 if (left != null) {
152 left.setLine(x1, y1, mx, my);
153 }
154 if (right != null) {
155 right.setLine(mx, my, x2, y2);
156 }
157 }
158 }