View Javadoc
1   /*
2    * Copyright (c) 2003, The JUNG Authors
3    * All rights reserved.
4    * 
5    * This software is open-source under the BSD license; see either "license.txt"
6    * or https://github.com/jrtom/jung/blob/master/LICENSE for a description.
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   * MagnifyTransformer wraps a MutableAffineTransformer and modifies
18   * the transform and inverseTransform methods so that they create an
19   * enlarging projection of the graph points.
20   * 
21   * MagnifyTransformer uses an
22   * affine transform to cause translation, scaling, rotation, and shearing
23   * while applying a separate magnification filter in its transform and
24   * inverseTransform methods.
25   * 
26   * @author Tom Nelson 
27   */
28  public class MagnifyTransformer extends LensTransformer implements MutableTransformer {
29      /**
30       * Create an instance, setting values from the passed component
31       * and registering to listen for size changes on the component.
32       * 
33       * @param component the component used for rendering
34       */
35      public MagnifyTransformer(Component component) {
36          this(component, new MutableAffineTransformer());
37      }
38      
39      /**
40       * Create an instance with a possibly shared transform.
41       * 
42       * @param component the component used for rendering
43       * @param delegate the transformer to use
44       */
45      public MagnifyTransformer(Component component, MutableTransformer delegate) {
46      		super(component, delegate);
47          this.magnification = 3.f;
48     }
49      
50      /**
51       * override base class transform to project the fisheye effect
52       */
53      public Point2D transform(Point2D graphPoint) {
54          if(graphPoint == null) return null;
55          Point2D viewCenter = getViewCenter();
56          double viewRadius = getViewRadius();
57          double ratio = getRatio();
58          // transform the point from the graph to the view
59          Point2D viewPoint = delegate.transform(graphPoint);
60          // calculate point from center
61          double dx = viewPoint.getX() - viewCenter.getX();
62          double dy = viewPoint.getY() - viewCenter.getY();
63          // factor out ellipse
64          dx *= ratio;
65          Point2D pointFromCenter = new Point2D.Double(dx, dy);
66          
67          PolarPoint polar = PolarPoint.cartesianToPolar(pointFromCenter);
68          double theta = polar.getTheta();
69          double radius = polar.getRadius();
70          if(radius > viewRadius) return viewPoint;
71          
72          double mag = magnification;
73          radius *= mag;
74          
75          radius = Math.min(radius, viewRadius);
76          Point2D projectedPoint = PolarPoint.polarToCartesian(theta, radius);
77          projectedPoint.setLocation(projectedPoint.getX()/ratio, projectedPoint.getY());
78          Point2D translatedBack = new Point2D.Double(projectedPoint.getX()+viewCenter.getX(),
79                  projectedPoint.getY()+viewCenter.getY());
80          return translatedBack;
81      }
82      
83      /**
84       * override base class to un-project the fisheye effect
85       */
86      public Point2D inverseTransform(Point2D viewPoint) {
87          
88          Point2D viewCenter = getViewCenter();
89          double viewRadius = getViewRadius();
90          double ratio = getRatio();
91          double dx = viewPoint.getX() - viewCenter.getX();
92          double dy = viewPoint.getY() - viewCenter.getY();
93          // factor out ellipse
94          dx *= ratio;
95  
96          Point2D pointFromCenter = new Point2D.Double(dx, dy);
97          
98          PolarPoint polar = PolarPoint.cartesianToPolar(pointFromCenter);
99  
100         double radius = polar.getRadius();
101         if(radius > viewRadius) return delegate.inverseTransform(viewPoint);
102         
103         double mag = magnification;
104         radius /= mag;
105         polar.setRadius(radius);
106         Point2D projectedPoint = PolarPoint.polarToCartesian(polar);
107         projectedPoint.setLocation(projectedPoint.getX()/ratio, projectedPoint.getY());
108         Point2D translatedBack = new Point2D.Double(projectedPoint.getX()+viewCenter.getX(),
109                 projectedPoint.getY()+viewCenter.getY());
110         return delegate.inverseTransform(translatedBack);
111     }
112     
113     /**
114      * Magnifies the point, without considering the Lens.
115      * @param graphPoint the point to transform via magnification
116      * @return the transformed point
117      */
118     public Point2D magnify(Point2D graphPoint) {
119         if(graphPoint == null) return null;
120         Point2D viewCenter = getViewCenter();
121         double ratio = getRatio();
122         // transform the point from the graph to the view
123         Point2D viewPoint = graphPoint;
124         // calculate point from center
125         double dx = viewPoint.getX() - viewCenter.getX();
126         double dy = viewPoint.getY() - viewCenter.getY();
127         // factor out ellipse
128         dx *= ratio;
129         Point2D pointFromCenter = new Point2D.Double(dx, dy);
130         
131         PolarPoint polar = PolarPoint.cartesianToPolar(pointFromCenter);
132         double theta = polar.getTheta();
133         double radius = polar.getRadius();
134         
135         double mag = magnification;
136         radius *= mag;
137         
138 //        radius = Math.min(radius, viewRadius);
139         Point2D projectedPoint = PolarPoint.polarToCartesian(theta, radius);
140         projectedPoint.setLocation(projectedPoint.getX()/ratio, projectedPoint.getY());
141         Point2D translatedBack = new Point2D.Double(projectedPoint.getX()+viewCenter.getX(),
142                 projectedPoint.getY()+viewCenter.getY());
143         return translatedBack;
144     }
145 
146 }