package prefuse.action.distortion; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; /** *

* Computes a bifocal distortion of space, magnifying a focus region of space * and uniformly demagnifying the rest of the space. The affect is akin to * passing a magnifying glass over the data. *

* *

* For more details on this form of transformation, see Y. K. Leung and * M. D. Apperley, "A Review and Taxonomy of Distortion-Oriented Presentation * Techniques", in Transactions of Computer-Human Interaction (TOCHI), * 1(2): 126-160 (1994). Available online at * * portal.acm.org/citation.cfm?id=180173&dl=ACM. *

* * @author jeffrey heer */ public class BifocalDistortion extends Distortion { private double rx, ry; // magnification ranges private double mx, my; // magnification factor /** * Create a new BifocalDistortion with default range and magnification. */ public BifocalDistortion() { this(0.1,3); } /** *

Create a new BifocalDistortion with the specified range and * magnification. The same range and magnification is used for both * axes.

* *

NOTE:if the range value times the magnification * value is greater than 1, the resulting distortion can exceed the * display bounds.

* * @param range the range around the focus that should be magnified. This * specifies the size of the magnified focus region, and should be in the * range of 0 to 1, 0 being no magnification range and 1 being the whole * display. * @param mag how much magnification should be used in the focal area */ public BifocalDistortion(double range, double mag) { this(range,mag,range,mag); } // /** *

Create a new BifocalDistortion with the specified range and * magnification along both axes.

* *

NOTE:if the range value times the magnification * value is greater than 1, the resulting distortion can exceed the * display bounds.

* * @param xrange the range around the focus that should be magnified along * the x direction. This specifies the horizontal size of the magnified * focus region, and should be a value between 0 and 1, 0 indicating no * focus region and 1 indicating the whole display. * @param xmag how much magnification along the x direction should be used * in the focal area * @param yrange the range around the focus that should be magnified along * the y direction. This specifies the vertical size of the magnified * focus region, and should be a value between 0 and 1, 0 indicating no * focus region and 1 indicating the whole display. * @param ymag how much magnification along the y direction should be used * in the focal area */ public BifocalDistortion(double xrange, double xmag, double yrange, double ymag) { rx = xrange; mx = xmag; ry = yrange; my = ymag; m_distortX = !(rx == 0 || mx == 1.0); m_distortY = !(ry == 0 || my == 1.0); } /** * @see prefuse.action.distortion.Distortion#distortX(double, java.awt.geom.Point2D, java.awt.geom.Rectangle2D) */ protected double distortX(double x, Point2D a, Rectangle2D b) { return bifocal(x, a.getX(), rx, mx, b.getMinX(), b.getMaxX()); } /** * @see prefuse.action.distortion.Distortion#distortY(double, java.awt.geom.Point2D, java.awt.geom.Rectangle2D) */ protected double distortY(double y, Point2D a, Rectangle2D b) { return bifocal(y, a.getY(), ry, my, b.getMinY(), b.getMaxY()); } /** * @see prefuse.action.distortion.Distortion#distortSize(java.awt.geom.Rectangle2D, double, double, java.awt.geom.Point2D, java.awt.geom.Rectangle2D) */ protected double distortSize(Rectangle2D bbox, double x, double y, Point2D anchor, Rectangle2D bounds) { boolean xmag = false, ymag = false; double m; if ( m_distortX ) { double cx = bbox.getCenterX(), ax = anchor.getX(); double minX = bounds.getMinX(), maxX = bounds.getMaxX(); m = (cx