1
2
3
4
5
6
7
8
9 package edu.uci.ics.jung.visualization.transform.shape;
10
11 import java.awt.Component;
12 import java.awt.Shape;
13 import java.awt.geom.GeneralPath;
14 import java.awt.geom.PathIterator;
15 import java.awt.geom.Point2D;
16
17 import edu.uci.ics.jung.algorithms.layout.PolarPoint;
18 import edu.uci.ics.jung.visualization.transform.HyperbolicTransformer;
19 import edu.uci.ics.jung.visualization.transform.MutableTransformer;
20
21
22
23
24
25
26
27
28
29
30
31
32 public class HyperbolicShapeTransformer extends HyperbolicTransformer
33 implements ShapeFlatnessTransformer {
34
35
36
37
38
39 public HyperbolicShapeTransformer(Component component) {
40 this(component, null);
41 }
42
43
44
45
46
47
48 public HyperbolicShapeTransformer(Component component, MutableTransformer delegate) {
49 super(component, delegate);
50 }
51
52
53
54
55
56
57
58
59 public Shape transform(Shape shape) {
60 return transform(shape, 0);
61 }
62 public Shape transform(Shape shape, float flatness) {
63 GeneralPath newPath = new GeneralPath();
64 float[] coords = new float[6];
65 PathIterator iterator = null;
66 if(flatness == 0) {
67 iterator = shape.getPathIterator(null);
68 } else {
69 iterator = shape.getPathIterator(null, flatness);
70 }
71 for( ;
72 iterator.isDone() == false;
73 iterator.next()) {
74 int type = iterator.currentSegment(coords);
75 switch(type) {
76 case PathIterator.SEG_MOVETO:
77 Point2D p = _transform(new Point2D.Float(coords[0], coords[1]));
78 newPath.moveTo((float)p.getX(), (float)p.getY());
79 break;
80
81 case PathIterator.SEG_LINETO:
82 p = _transform(new Point2D.Float(coords[0], coords[1]));
83 newPath.lineTo((float)p.getX(), (float) p.getY());
84 break;
85
86 case PathIterator.SEG_QUADTO:
87 p = _transform(new Point2D.Float(coords[0], coords[1]));
88 Point2D q = _transform(new Point2D.Float(coords[2], coords[3]));
89 newPath.quadTo((float)p.getX(), (float)p.getY(), (float)q.getX(), (float)q.getY());
90 break;
91
92 case PathIterator.SEG_CUBICTO:
93 p = _transform(new Point2D.Float(coords[0], coords[1]));
94 q = _transform(new Point2D.Float(coords[2], coords[3]));
95 Point2D r = _transform(new Point2D.Float(coords[4], coords[5]));
96 newPath.curveTo((float)p.getX(), (float)p.getY(),
97 (float)q.getX(), (float)q.getY(),
98 (float)r.getX(), (float)r.getY());
99 break;
100
101 case PathIterator.SEG_CLOSE:
102 newPath.closePath();
103 break;
104
105 }
106 }
107 return newPath;
108 }
109
110 public Shape inverseTransform(Shape shape) {
111 GeneralPath newPath = new GeneralPath();
112 float[] coords = new float[6];
113 for(PathIterator iterator=shape.getPathIterator(null);
114 iterator.isDone() == false;
115 iterator.next()) {
116 int type = iterator.currentSegment(coords);
117 switch(type) {
118 case PathIterator.SEG_MOVETO:
119 Point2D p = _inverseTransform(new Point2D.Float(coords[0], coords[1]));
120 newPath.moveTo((float)p.getX(), (float)p.getY());
121 break;
122
123 case PathIterator.SEG_LINETO:
124 p = _inverseTransform(new Point2D.Float(coords[0], coords[1]));
125 newPath.lineTo((float)p.getX(), (float) p.getY());
126 break;
127
128 case PathIterator.SEG_QUADTO:
129 p = _inverseTransform(new Point2D.Float(coords[0], coords[1]));
130 Point2D q = _inverseTransform(new Point2D.Float(coords[2], coords[3]));
131 newPath.quadTo((float)p.getX(), (float)p.getY(), (float)q.getX(), (float)q.getY());
132 break;
133
134 case PathIterator.SEG_CUBICTO:
135 p = _inverseTransform(new Point2D.Float(coords[0], coords[1]));
136 q = _inverseTransform(new Point2D.Float(coords[2], coords[3]));
137 Point2D r = _inverseTransform(new Point2D.Float(coords[4], coords[5]));
138 newPath.curveTo((float)p.getX(), (float)p.getY(),
139 (float)q.getX(), (float)q.getY(),
140 (float)r.getX(), (float)r.getY());
141 break;
142
143 case PathIterator.SEG_CLOSE:
144 newPath.closePath();
145 break;
146
147 }
148 }
149 return newPath;
150 }
151
152
153
154 private Point2D _transform(Point2D graphPoint) {
155 if(graphPoint == null) return null;
156 Point2D viewCenter = getViewCenter();
157 double viewRadius = getViewRadius();
158 double ratio = getRatio();
159
160 Point2D viewPoint = graphPoint;
161
162 double dx = viewPoint.getX() - viewCenter.getX();
163 double dy = viewPoint.getY() - viewCenter.getY();
164
165 dx *= ratio;
166 Point2D pointFromCenter = new Point2D.Double(dx, dy);
167
168 PolarPoint polar = PolarPoint.cartesianToPolar(pointFromCenter);
169 double theta = polar.getTheta();
170 double radius = polar.getRadius();
171 if(radius > viewRadius) return viewPoint;
172
173 double mag = Math.tan(Math.PI/2*magnification);
174 radius *= mag;
175
176 radius = Math.min(radius, viewRadius);
177 radius /= viewRadius;
178 radius *= Math.PI/2;
179 radius = Math.abs(Math.atan(radius));
180 radius *= viewRadius;
181 Point2D projectedPoint = PolarPoint.polarToCartesian(theta, radius);
182 projectedPoint.setLocation(projectedPoint.getX()/ratio, projectedPoint.getY());
183 Point2D translatedBack = new Point2D.Double(projectedPoint.getX()+viewCenter.getX(),
184 projectedPoint.getY()+viewCenter.getY());
185 return translatedBack;
186 }
187
188
189
190
191 private Point2D _inverseTransform(Point2D viewPoint) {
192
193 viewPoint = delegate.inverseTransform(viewPoint);
194 Point2D viewCenter = getViewCenter();
195 double viewRadius = getViewRadius();
196 double ratio = getRatio();
197 double dx = viewPoint.getX() - viewCenter.getX();
198 double dy = viewPoint.getY() - viewCenter.getY();
199
200 dx *= ratio;
201
202 Point2D pointFromCenter = new Point2D.Double(dx, dy);
203
204 PolarPoint polar = PolarPoint.cartesianToPolar(pointFromCenter);
205
206 double radius = polar.getRadius();
207 if(radius > viewRadius) return viewPoint;
208
209 radius /= viewRadius;
210 radius = Math.abs(Math.tan(radius));
211 radius /= Math.PI/2;
212 radius *= viewRadius;
213 double mag = Math.tan(Math.PI/2*magnification);
214 radius /= mag;
215 polar.setRadius(radius);
216 Point2D projectedPoint = PolarPoint.polarToCartesian(polar);
217 projectedPoint.setLocation(projectedPoint.getX()/ratio, projectedPoint.getY());
218 Point2D translatedBack = new Point2D.Double(projectedPoint.getX()+viewCenter.getX(),
219 projectedPoint.getY()+viewCenter.getY());
220 return translatedBack;
221
222 }
223 }