📄 bifocaldistortion.as
字号:
package flare.vis.operator.distortion
{
import flash.geom.Rectangle;
/**
* 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.
*
* <p>
* 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
* <a href="portal.acm.org/citation.cfm?id=180173&dl=ACM">
* portal.acm.org/citation.cfm?id=180173&dl=ACM</a>.
* </p>
*/
public class BifocalDistortion extends Distortion
{
private var _rx:Number;
private var _mx:Number;
private var _ry:Number;
private var _my:Number;
/**
* <p>Create a new BifocalDistortion with the specified range and
* magnification along both axes.</p>
*
* <p><strong>NOTE:</strong>if the range value times the magnification
* value is greater than 1, the resulting distortion can exceed the
* display bounds.</p>
*
* @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 function BifocalDistortion(xRange:Number=0.1, xMagnify:Number=3,
yRange:Number=0.1, yMagnify:Number=3)
{
_rx = xRange;
_mx = xMagnify;
_ry = yRange;
_my = yMagnify;
distortX = !(_rx == 0 || _mx == 1.0);
distortY = !(_ry == 0 || _my == 1.0);
}
/** @inheritDoc */
protected override function xDistort(x:Number):Number
{
return bifocal(x, layoutAnchor.x, _rx, _mx, _b.left, _b.right);
}
/** @inheritDoc */
protected override function yDistort(y:Number):Number
{
return bifocal(y, layoutAnchor.y, _ry, _my, _b.top, _b.bottom);
}
/** @inheritDoc */
protected override function sizeDistort(bb:Rectangle, x:Number, y:Number):Number
{
var xmag:Boolean = false, ymag:Boolean = false;
var m:Number, c:Number, a:Number, min:Number, max:Number;
if (distortX) {
c = (bb.left+bb.right)/2;
a = layoutAnchor.x;
min = _b.left;
max = _b.right;
m = c<a ? a-min : max-a;
if (m == 0) m = max-min;
xmag = (Math.abs(c-a) <= _rx*m )
}
if (distortY) {
c = (bb.top+bb.bottom)/2;
a = layoutAnchor.y;
min = _b.top;
max = _b.bottom;
m = c<a ? a-min : max-a;
if (m == 0) m = max-min;
ymag = (Math.abs(c-a) <= _ry*m);
}
if (xmag && !distortY) {
return _mx;
} else if (ymag && !distortX) {
return _my;
} else if (xmag && ymag) {
return Math.min(_mx, _my);
} else {
return Math.min((1-_rx*_mx)/(1-_rx), (1-_ry*_my)/(1-_ry));
}
}
private function bifocal(x:Number, a:Number, r:Number,
mag:Number, min:Number, max:Number):Number
{
var m:Number, v:Number, s:Number, bx:Number;
m = (x<a ? a-min : max-a);
if ( m == 0 ) m = max-min;
v = x - a, s = m*r;
if ( Math.abs(v) <= s ) { // in focus
return v*mag + a;
} else { // out of focus
bx = r*mag;
x = ((Math.abs(v)-s) / m) * ((1-bx)/(1-r));
return (v<0?-1:1)*m*(x + bx) + a;
}
}
} // end of class BifocalDistortion
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -