KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > prefuse > action > distortion > BifocalDistortion


1 package prefuse.action.distortion;
2
3 import java.awt.geom.Point2D JavaDoc;
4 import java.awt.geom.Rectangle2D JavaDoc;
5
6 /**
7  * <p>
8  * Computes a bifocal distortion of space, magnifying a focus region of space
9  * and uniformly demagnifying the rest of the space. The affect is akin to
10  * passing a magnifying glass over the data.
11  * </p>
12  *
13  * <p>
14  * For more details on this form of transformation, see Y. K. Leung and
15  * M. D. Apperley, "A Review and Taxonomy of Distortion-Oriented Presentation
16  * Techniques", in Transactions of Computer-Human Interaction (TOCHI),
17  * 1(2): 126-160 (1994). Available online at
18  * <a HREF="portal.acm.org/citation.cfm?id=180173&dl=ACM">
19  * portal.acm.org/citation.cfm?id=180173&dl=ACM</a>.
20  * </p>
21  *
22  * @author <a HREF="http://jheer.org">jeffrey heer</a>
23  */

24 public class BifocalDistortion extends Distortion {
25     
26     private double rx, ry; // magnification ranges
27
private double mx, my; // magnification factor
28

29     /**
30      * Create a new BifocalDistortion with default range and magnification.
31      */

32     public BifocalDistortion() {
33         this(0.1,3);
34     }
35     
36     /**
37      * <p>Create a new BifocalDistortion with the specified range and
38      * magnification. The same range and magnification is used for both
39      * axes.</p>
40      *
41      * <p><strong>NOTE:</strong>if the range value times the magnification
42      * value is greater than 1, the resulting distortion can exceed the
43      * display bounds.</p>
44      *
45      * @param range the range around the focus that should be magnified. This
46      * specifies the size of the magnified focus region, and should be in the
47      * range of 0 to 1, 0 being no magnification range and 1 being the whole
48      * display.
49      * @param mag how much magnification should be used in the focal area
50      */

51     public BifocalDistortion(double range, double mag) {
52         this(range,mag,range,mag);
53     } //
54

55     /**
56      * <p>Create a new BifocalDistortion with the specified range and
57      * magnification along both axes.</p>
58      *
59      * <p><strong>NOTE:</strong>if the range value times the magnification
60      * value is greater than 1, the resulting distortion can exceed the
61      * display bounds.</p>
62      *
63      * @param xrange the range around the focus that should be magnified along
64      * the x direction. This specifies the horizontal size of the magnified
65      * focus region, and should be a value between 0 and 1, 0 indicating no
66      * focus region and 1 indicating the whole display.
67      * @param xmag how much magnification along the x direction should be used
68      * in the focal area
69      * @param yrange the range around the focus that should be magnified along
70      * the y direction. This specifies the vertical size of the magnified
71      * focus region, and should be a value between 0 and 1, 0 indicating no
72      * focus region and 1 indicating the whole display.
73      * @param ymag how much magnification along the y direction should be used
74      * in the focal area
75      */

76     public BifocalDistortion(double xrange, double xmag,
77                              double yrange, double ymag)
78     {
79         rx = xrange;
80         mx = xmag;
81         ry = yrange;
82         my = ymag;
83         m_distortX = !(rx == 0 || mx == 1.0);
84         m_distortY = !(ry == 0 || my == 1.0);
85     }
86     
87     /**
88      * @see prefuse.action.distortion.Distortion#distortX(double, java.awt.geom.Point2D, java.awt.geom.Rectangle2D)
89      */

90     protected double distortX(double x, Point2D JavaDoc a, Rectangle2D JavaDoc b) {
91         return bifocal(x, a.getX(), rx, mx, b.getMinX(), b.getMaxX());
92     }
93     
94     /**
95      * @see prefuse.action.distortion.Distortion#distortY(double, java.awt.geom.Point2D, java.awt.geom.Rectangle2D)
96      */

97     protected double distortY(double y, Point2D JavaDoc a, Rectangle2D JavaDoc b) {
98         return bifocal(y, a.getY(), ry, my, b.getMinY(), b.getMaxY());
99     }
100     
101     /**
102      * @see prefuse.action.distortion.Distortion#distortSize(java.awt.geom.Rectangle2D, double, double, java.awt.geom.Point2D, java.awt.geom.Rectangle2D)
103      */

104     protected double distortSize(Rectangle2D JavaDoc bbox, double x, double y,
105             Point2D JavaDoc anchor, Rectangle2D JavaDoc bounds)
106     {
107         boolean xmag = false, ymag = false;
108         double m;
109         
110         if ( m_distortX ) {
111             double cx = bbox.getCenterX(), ax = anchor.getX();
112             double minX = bounds.getMinX(), maxX = bounds.getMaxX();
113             m = (cx<ax ? ax-minX : maxX-ax);
114             if ( m == 0 ) m = maxX-minX;
115             if ( Math.abs(cx-ax) <= rx*m )
116                 xmag = true;
117         }
118         
119         if ( m_distortY ) {
120             double cy = bbox.getCenterY(), ay = anchor.getY();
121             double minY = bounds.getMinY(), maxY = bounds.getMaxY();
122             m = (cy<ay ? ay-minY : maxY-ay);
123             if ( m == 0 ) m = maxY-minY;
124             if ( Math.abs(cy-ay) <= ry*m )
125                 ymag = true;
126         }
127         
128         if ( xmag && !m_distortY ) {
129             return mx;
130         } else if ( ymag && !m_distortX ) {
131             return my;
132         } else if ( xmag && ymag ) {
133             return Math.min(mx,my);
134         } else {
135             return Math.min((1-rx*mx)/(1-rx), (1-ry*my)/(1-ry));
136         }
137     }
138     
139     private double bifocal(double x, double a, double r,
140                            double mag, double min, double max)
141     {
142         double m = (x<a ? a-min : max-a);
143         if ( m == 0 ) m = max-min;
144         double v = x - a, s = m*r;
145         if ( Math.abs(v) <= s ) { // in focus
146
return x = v*mag + a;
147         } else { // out of focus
148
double bx = r*mag;
149             x = ((Math.abs(v)-s) / m) * ((1-bx)/(1-r));
150             return (v<0?-1:1)*m*(x + bx) + a;
151         }
152     }
153
154     /**
155      * Returns the magnification factor for the x-axis.
156      * @return Returns the magnification factor for the x-axis.
157      */

158     public double getXMagnification() {
159         return mx;
160     }
161
162     /**
163      * Sets the magnification factor for the x-axis.
164      * @param mx The magnification factor for the x-axis.
165      */

166     public void setXMagnification(double mx) {
167         this.mx = mx;
168     }
169
170     /**
171      * Returns the magnification factor for the y-axis.
172      * @return Returns the magnification factor for the y-axis.
173      */

174     public double getYMagnification() {
175         return my;
176     }
177
178     /**
179      * Sets the magnification factor for the y-axis.
180      * @param my The magnification factor for the y-axis.
181      */

182     public void setYMagnification(double my) {
183         this.my = my;
184     }
185
186     /**
187      * Returns the range of the focal area along the x-axis.
188      * @return Returns the range of the focal area along the x-axis.
189      */

190     public double getXRange() {
191         return rx;
192     }
193
194     /**
195      * Sets the range of the focal area along the x-axis.
196      * @param rx The focal range for the x-axis, a value between 0 and 1.
197      */

198     public void setXRange(double rx) {
199         this.rx = rx;
200     }
201
202     /**
203      * Returns the range of the focal area along the y-axis.
204      * @return Returns the range of the focal area along the y-axis.
205      */

206     public double getYRange() {
207         return ry;
208     }
209
210     /**
211      * Sets the range of the focal area along the y-axis.
212      * @param ry The focal range for the y-axis, a value between 0 and 1.
213      */

214     public void setYRange(double ry) {
215         this.ry = ry;
216     }
217
218 } // end of class BifocalDistortion
219
Popular Tags