1
2
3
4
5
6
7
8
9 package edu.uci.ics.jung.visualization.transform;
10
11 import java.awt.Component;
12 import java.awt.geom.Point2D;
13
14 import edu.uci.ics.jung.algorithms.layout.PolarPoint;
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 public class HyperbolicTransformer extends LensTransformer implements MutableTransformer {
33
34
35
36
37
38
39
40 public HyperbolicTransformer(Component component) {
41 this(component, new MutableAffineTransformer());
42 }
43
44
45
46
47
48 public HyperbolicTransformer(Component component, MutableTransformer delegate) {
49 super(component, delegate);
50 }
51
52
53
54
55 public Point2D transform(Point2D graphPoint) {
56 if(graphPoint == null) return null;
57 Point2D viewCenter = getViewCenter();
58 double viewRadius = getViewRadius();
59 double ratio = getRatio();
60
61 Point2D viewPoint = delegate.transform(graphPoint);
62
63 double dx = viewPoint.getX() - viewCenter.getX();
64 double dy = viewPoint.getY() - viewCenter.getY();
65
66 dx *= ratio;
67 Point2D pointFromCenter = new Point2D.Double(dx, dy);
68
69 PolarPoint polar = PolarPoint.cartesianToPolar(pointFromCenter);
70 double theta = polar.getTheta();
71 double radius = polar.getRadius();
72 if(radius > viewRadius) return viewPoint;
73
74 double mag = Math.tan(Math.PI/2*magnification);
75 radius *= mag;
76
77 radius = Math.min(radius, viewRadius);
78 radius /= viewRadius;
79 radius *= Math.PI/2;
80 radius = Math.abs(Math.atan(radius));
81 radius *= viewRadius;
82 Point2D projectedPoint = PolarPoint.polarToCartesian(theta, radius);
83 projectedPoint.setLocation(projectedPoint.getX()/ratio, projectedPoint.getY());
84 Point2D translatedBack = new Point2D.Double(projectedPoint.getX()+viewCenter.getX(),
85 projectedPoint.getY()+viewCenter.getY());
86 return translatedBack;
87 }
88
89
90
91
92 public Point2D inverseTransform(Point2D viewPoint) {
93
94 Point2D viewCenter = getViewCenter();
95 double viewRadius = getViewRadius();
96 double ratio = getRatio();
97 double dx = viewPoint.getX() - viewCenter.getX();
98 double dy = viewPoint.getY() - viewCenter.getY();
99
100 dx *= ratio;
101
102 Point2D pointFromCenter = new Point2D.Double(dx, dy);
103
104 PolarPoint polar = PolarPoint.cartesianToPolar(pointFromCenter);
105
106 double radius = polar.getRadius();
107 if(radius > viewRadius) return delegate.inverseTransform(viewPoint);
108
109 radius /= viewRadius;
110 radius = Math.abs(Math.tan(radius));
111 radius /= Math.PI/2;
112 radius *= viewRadius;
113 double mag = Math.tan(Math.PI/2*magnification);
114 radius /= mag;
115 polar.setRadius(radius);
116 Point2D projectedPoint = PolarPoint.polarToCartesian(polar);
117 projectedPoint.setLocation(projectedPoint.getX()/ratio, projectedPoint.getY());
118 Point2D translatedBack = new Point2D.Double(projectedPoint.getX()+viewCenter.getX(),
119 projectedPoint.getY()+viewCenter.getY());
120 return delegate.inverseTransform(translatedBack);
121 }
122 }