forked from: forked from: forked from: forked from: INK BLEED

by aobyrne forked from forked from: forked from: forked from: INK BLEED (diff: 7)
few changes form forked
♥0 | Line 658 | Modified 2012-04-22 18:19:00 | MIT License
play

ActionScript3 source code

/**
 * Copyright aobyrne ( http://wonderfl.net/user/aobyrne )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/nfEq
 */

package
{
    import flash.display.BlendMode;
    import flash.display.Graphics;
    import flash.display.Sprite;
    
    
    
    [SWF(width=465, height=465, frameRate=30)]
    
    /**
     * <p>Ink Bleed</p>
     * @author monoDreamer, aka ryo
     * @langversion ActionScript 3.0
     * @playerversion Flash 10.2+
     * @see 
     */
    public class InkBleedRectangleClient extends Sprite
    {
        public function InkBleedRectangleClient()
        {
            var tejido:Sprite = (new Tejido) as Sprite;
            var inkBleed:InkBleedEmbeded = new InkBleedEmbeded(tejido);
            //inkBleedRectangleEmbeded.blendMode = BlendMode.HARDLIGHT
            addChild(inkBleed);
            //addChild(tejido);
        }
    }
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.filters.DisplacementMapFilter;
import flash.filters.DisplacementMapFilterMode;
import flash.geom.ColorTransform;
import flash.geom.Point;
import flash.utils.Timer;
import net.hires.debug.Stats;
import flash.display.Sprite;
class InkBleedEmbeded extends Sprite
    {
        //----------------------------------------------------------------
        // Properties
        //----------------------------------------------------------------
        
        //----------------------------------------------------------------
        // Getter/Setter Method
        //----------------------------------------------------------------
        
        //----------------------------------------------------------------
        // Public method
        //----------------------------------------------------------------
        
        //----------------------------------------------------------------
        // Protected Method
        //----------------------------------------------------------------
        protected function timerHandler($e:TimerEvent):void
        {
            var i:int = _pnum;
            while (--i>-1) {
                _dots[i].diffuse();
            }
        }
        
        protected function render($e:Event):void
        {
            var d:Dot, i:int, c:uint;
            if (_isMouseDown) {
                i = _px + _py * _cw;
                _dots[i].cur += 0x2f0;
            }
            
            i = _pnum;
            while (--i>-1) {
                    c = _dots[i].cur;
                    _canvasData[i] = (c > 0xff ? 0xff : c) << 24;
            }
            _canvas.setVector(_canvas.rect, _canvasData);
        }
        
        protected function downHandler($e:MouseEvent):void
        {
            var mx:int = stage.mouseX>>DX, my:int = stage.mouseY>>DY;
            if (_canvas.rect.contains(mx, my)) {
                _px = mx;
                _py = my;
                _isMouseDown = true;
                stage.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
            }
        }
        
        protected function moveHandler($e:MouseEvent):void
        {
            if(_isMouseDown) {
                var mx:int = stage.mouseX>>DX, my:int = stage.mouseY>>DY;
                if (_canvas.rect.contains(mx, my))
                {
                    t_efla(_px, _py, mx, my, 0x1ff);
                    _px = mx;
                    _py = my;
                }
            }
        }
        
        protected function upHandler($e:MouseEvent):void
        {
            _isMouseDown = false;
            stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
        }
        
        protected function t_efla($sx:int, $sy:int, $ex:int, $ey:int, $color:uint):void
        {
            var shortLen:int = $ey - $sy;
            var longLen:int = $ex - $sx;
            if (!longLen) if (!shortLen) return;
            var i:int, id:int, inc:int;
            var multDiff:Number;
            var idx:int;
            
            // TODO: check for this above, swap x/y/len and optimize loops to ++ and -- (operators twice as fast, still only 2 loops)
            if ((shortLen ^ (shortLen >> 31)) - (shortLen >> 31) > (longLen ^ (longLen >> 31)) - (longLen >> 31)) {
                if (shortLen < 0) {
                    inc = -1;
                    id = -shortLen & 3;
                } else {
                    inc = 1;
                    id = shortLen & 3;
                }
                multDiff = !shortLen ? longLen : longLen / shortLen;
                if (id) {
                    idx = $sx + $sy*_cw;
                    _dots[idx].cur += $color;
                    
                    i += inc;
                    if (--id) {
                        idx = roundPlus($sx + i * multDiff) + ($sy + i)*_cw;
                        _dots[idx].cur += $color;
                        i += inc;
                        if (--id) {
                            idx = roundPlus($sx + i * multDiff) + ($sy + i)*_cw;
                            _dots[idx].cur += $color;
                            i += inc;
                        }
                    }
                }
                
                while (i != shortLen) {
                    idx = roundPlus($sx + i * multDiff) + ($sy + i) * _cw;
                    _dots[idx].cur += $color;
                    i += inc;
                    idx = roundPlus($sx + i * multDiff) + ($sy + i) * _cw;
                    _dots[idx].cur += $color;
                    i += inc;
                    idx = roundPlus($sx + i * multDiff) + ($sy + i) * _cw;
                    _dots[idx].cur += $color;
                    i += inc;
                    idx = roundPlus($sx + i * multDiff) + ($sy + i) * _cw;
                    _dots[idx].cur += $color;
                    i += inc;
                }
            } 
            else {
                if (longLen < 0) {
                    inc = -1;
                    id = -longLen & 3;
                } else {
                    inc = 1;
                    id = longLen & 3;
                }
                multDiff = !longLen ? shortLen : shortLen / longLen;
                
                if (id) {
                    idx = $sx + $sy * _cw;
                    _dots[idx].cur += $color;
                    i += inc;
                    if (--id) {
                        idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
                        _dots[idx].cur += $color;
                        i += inc;
                        if (--id) {
                            idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
                            _dots[idx].cur += $color;
                            i += inc;
                        }
                    }
                }
                
                while (i != longLen) {
                    idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
                    _dots[idx].cur += $color;
                    i += inc;
                    idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
                    _dots[idx].cur += $color;
                    i += inc;
                    idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
                    _dots[idx].cur += $color;
                    i += inc;
                    idx = $sx + i + roundPlus($sy + i * multDiff) * _cw;
                    _dots[idx].cur += $color;
                    
                    i += inc;
                }
                
            }
        }
        
        protected function roundPlus($value:Number):int {
            return ($value + BIG_ENOUGH_ROUND) - BIG_ENOUGH_INT;
        }
        
        //----------------------------------------------------------------
        // Private Method
        //----------------------------------------------------------------
        /** Constructor */
        public function InkBleedEmbeded(vectorCanvas:Sprite):void
        {
            this.vectorCanvas = vectorCanvas;
            //super();
            
            _cw = 200
            _ch = 200;
            _pnum = _cw * _ch;
            if (stage) init();
            else (addEventListener(Event.ADDED_TO_STAGE, doInit));
        }
        
        private function doInit(e:Event):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, doInit);
            init();
        }
        
        /** Initialize */
        private function init():void
        {
            initTimer();
            initDots();
            initCanvas();
            addListeners();
            
            _timer.start();
        }
        
        private function initTimer():void
        {
            _timer = new Timer(100);
            _timer.addEventListener(TimerEvent.TIMER, timerHandler);
        }
        
        private function initCanvas():void
        {
            _canvas = new BitmapData(_cw, _ch, true, 0);
            _canvasData = _canvas.getVector(_canvas.rect);
            _canvasData.fixed = true;
            
            var map:BitmapData = new BitmapData(_cw * SCX, _ch *SCY);
            map.perlinNoise(map.width * .4, map.height * .4, 8, Math.random()*100, true, true, 1, true);
            
            var bmp:Bitmap = new Bitmap(_canvas);
                bmp.smoothing = true;
                bmp.scaleX = SCX;
                bmp.scaleY = SCY;
                bmp.filters = [new DisplacementMapFilter(map, new Point(), 1, 1, 32, 32, DisplacementMapFilterMode.CLAMP)];
            addChild(bmp);
            
            graphics.lineStyle(1);
            graphics.drawRect(0, 0, _cw * SCX, _ch * SCY);
            
            var stat:Stats = new Stats();
                stat.x = 400;
            addChild(stat);
        }
        
        private function addListeners():void
        {
            addEventListener(Event.ENTER_FRAME, render);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
        }
        
        private function initDots():void
        {
            var absorbMap:BitmapData = new BitmapData(_cw, _ch, false, 0);
                absorbMap.perlinNoise(_cw/2, _ch/2, 5, 100*Math.random(), true, true, 1, true);
                absorbMap.colorTransform(absorbMap.rect, new ColorTransform(.2, .2, .2));
            var maxCapMap:BitmapData = new BitmapData(_cw, _ch, false, 0xffffff);
                maxCapMap.perlinNoise(_cw, _ch, 5, 100 * Math.random(), true, true, 1, true);
                maxCapMap.colorTransform(maxCapMap.rect, new ColorTransform(1.8, 1.8, 1.8));
            var d:Dot, i:int = _pnum;
            
            _dots = new Vector.<Dot>(_pnum, true);
            while(--i>-1) {
                _dots[i] = new Dot();
            }
            
            var neighbors:Array;
            for (var my:int=0; my<_ch; my++)
            {
                for (var mx:int=0; mx<_cw; mx++)
                {
                    i = mx + my*_cw;
                    d = _dots[i];
                    neighbors = [];
                    d.abs = absorbMap.getPixel(mx, my) & 0xff;
                    d.max = maxCapMap.getPixel(mx, my) & 0xff;
                    
                    if (mx>0) neighbors.push(_dots[i-1]);
                    if (mx<_cw-1) neighbors.push(_dots[i+1]);
                    if (my>0) neighbors.push(_dots[i-_cw]);
                    if (my<_ch-1) neighbors.push(_dots[i+_cw]);
                    
                    d.setNeighbors(neighbors);
                }
            }
            var bitmapData:BitmapData = new BitmapData(_cw, _ch,false,0);
            bitmapData.draw(vectorCanvas);
            var bitmap:Bitmap = new Bitmap(bitmapData);
            //addChild(bitmap);
            var vector:Vector.<uint> = bitmapData.getVector(bitmapData.rect);
            var k:int = _pnum;
            while (--k > -1) {
                _dots[k].cur = (vector[k] & 0xff) ? 200 + uint(400 * (vector[k] & 0xff) / 255):0;
            }
              
        }
        
        private const BIG_ENOUGH_INT:int = 16 * 1024;
        private const BIG_ENOUGH_ROUND:Number = BIG_ENOUGH_INT + 0.5;
        private const SCX:int = 2;
        private const SCY:int = 2;
        private var DX:int = 1;
        private var DY:int = 1;
        
        private var _canvasData:Vector.<uint>;
        private var _canvas:BitmapData;
        private var _pnum:int;
        private var _dots:Vector.<Dot>;
        private var _cw:int;
        private var _ch:int;
        private var _px:int;
        private var _py:int;
        private var _isMouseDown:Boolean;
        private var vectorCanvas:Sprite;
        private var _timer:Timer;
    }


class Dot
{
    public var max:uint;
    public var cur:uint;
    public var abs:uint;
    public var isOver:Boolean;
    
    public function setNeighbors($neighbors:Array):void
    {
        _neighbors = Vector.<Dot>($neighbors);
        _neighbors.fixed = true;
        _len = _neighbors.length;
    }
    
    public function diffuse():void
    {
        if (cur <= max) return;
        isOver = true;
        var d:Dot, l:int = _len;
        while (--l > -1) {
            d = _neighbors[l];
            if (d.isOver|| cur<d.abs) continue;
            d.cur += d.abs;
        }
        cur -= d.abs * .2;
    }
    
    private var _neighbors:Vector.<Dot>;
    private var _len:int;
}
    import com.bit101.components.CheckBox;
    import com.bit101.components.HUISlider;
    import com.bit101.components.VBox;
    import flash.display.Bitmap;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.system.fscommand;
    import flash.geom.Point;
    import flash.geom.Matrix;
    import flash.text.TextField;
    import flash.text.TextFormat;
 class Tejido extends Sprite 
    {
        static private const GOLDEN_RATIO:Number = 0.618;
        private var tejidoGrid:TejidoGrid;
        private var elementWidth:Number;
        private var gridWidth:int;
        private var gridHeight:int;
        private var isRandom:Boolean;
        private var isTransforming:Boolean;
        private var hUISliderRatio:HUISlider;
        private var checkBoxTransforming:CheckBox;
        private var perlinNoiseOffset:uint;
        private var pnOffsetPoint:Point;
        private var textTransformationMatrix:Matrix;
        
        public function Tejido():void 
        {
            init();
            //if (stage) 
            //else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, init);
            // entry point
            
            graphics.lineStyle(0,0xffffff);
            
            elementWidth = 28;
            isRandom = false;
            isTransforming = true;
            
            
            resetTejidoGrid();
            //tejidoGrid.bitmapData.fillRect(tejidoGrid.bitmapData.rect, 0xffffff);
            //tejidoGrid.bitmapData.fillRect(tejidoGrid.bitmapData.rect, 0);
            var number:Number = 2;
            //graphics.lineStyle(1);
            tejidoGrid.draw(graphics,isTransforming);
            
            //graphics.lineStyle(10);
            //graphics.drawRect(0, 0, gridWidth, gridHeight);
            //vBox.addChildAt(hUISliderRatio, vBox.numChildren);
            
            //hUISliderRatioAbility();
            pnOffsetPoint = new Point(perlinNoiseOffset, 0);    
            //addEventListener(Event.ENTER_FRAME, loopIt);
        }
        
        private function loopIt(e:Event):void 
        {
            if (isRandom) 
            {
            perlinNoiseOffset += 10;
            pnOffsetPoint.x=perlinNoiseOffset;
            tejidoGrid.bitmapData.perlinNoise(50, 50, 1, 1, false, true, 7, true, [pnOffsetPoint]);
            //tejidoGrid.bitmapData.draw(ve,textTransformationMatrix);
            clearGraphics();
            tejidoGrid.draw(graphics, isTransforming);
            }
        }
        
        private function onTransform(e:Event):void 
        {
            isTransforming = CheckBox(e.target).selected;
            clearGraphics();
            tejidoGrid.draw(graphics, isTransforming);
            hUISliderRatioAbility();
            hUISliderRatio.enabled = !isTransforming;
        }
        
        private function hUISliderRatioAbility():void 
        {
            
            hUISliderRatio.enabled = !tejidoGrid.isRandomRatio;
            checkBoxTransforming.enabled = !tejidoGrid.isRandomRatio;
            hUISliderRatio.enabled = !isTransforming && !tejidoGrid.isRandomRatio;
        }
        
        private function onRandom(e:Event):void 
        {
            clearGraphics();
            isRandom= tejidoGrid.isRandomRatio = CheckBox(e.target).selected;
            tejidoGrid.draw(graphics, isTransforming);
            hUISliderRatioAbility();
        }
        
        private function onRatio(e:Event):void 
        {
            clearGraphics();
            tejidoGrid.ratio = HUISlider(e.target).value;
            tejidoGrid.draw(graphics, isTransforming);
        }
        
        private function resetTejidoGrid():void 
        {
            var elementHeight:Number = GOLDEN_RATIO * elementWidth;
            var separation:Number = elementHeight * 0.5 + elementWidth * 0.5;
            //gridWidth = stage.stageWidth;
            gridWidth = 400;
            var columns:int = Math.ceil(gridWidth / separation);
            columns = columns % 2 ? columns + 1:columns;
            //gridHeight = stage.stageHeight;
            gridHeight = 400;
            var rows:int = Math.ceil(gridHeight / separation);
            rows++;
            var totalElements:int = columns * rows;
            if (!tejidoGrid) 
            {
                tejidoGrid = new TejidoGrid(columns, totalElements, elementWidth, elementHeight, 0.2,[0x00,0x555555],isRandom);
            }
            else
            {
                tejidoGrid.colsAmount = columns;
                tejidoGrid.totalAmount = totalElements;
                tejidoGrid.eWidth = elementWidth;
                tejidoGrid.eHeight = elementHeight;
                tejidoGrid.draw(graphics,isTransforming)
            }
        }
        
        private function clearGraphics():void 
        {
            graphics.clear();
            graphics.lineStyle(0);
        }
        
    }
    

import flash.display.BitmapData;
import flash.display.Graphics;
class TejidoGrid 
{
    private var _colsAmount:uint;
    private var _totalAmount:uint;
    private var _eWidth:Number;
    private var _eHeight:Number;
    private var separation:Number;
    private var _ratio:Number;
    private var colors:Array;
    public var bitmapData:BitmapData;
    private var _isRandomRatio:Boolean;
    private var rowsAmount:uint;
    
    public function TejidoGrid(colsAmount:uint, totalAmount:uint, width:Number, height:Number, ratio:Number, colors:Array,isRandomRatio:Boolean=false) 
    {
        this.isRandomRatio = isRandomRatio;
        this.colors = colors;
        this.ratio = ratio;
        this.eHeight = height;
        this.eWidth = width;
        this.totalAmount = totalAmount;
        this.colsAmount = colsAmount;
        setSeparation();
        rowsAmount = totalAmount / colsAmount;
        bitmapData = new BitmapData(colsAmount*separation, rowsAmount*separation);
        bitmapData.perlinNoise(50,50,1,1,false,true,1,true)
    }
    
    public function draw(g:Graphics, isTransforming:Boolean = true):void 
    {
        var orientation:Number;
        var actualRatio:Number;
        var yy:Number;
        var xx:uint;
        var fundamentalElement:FundamentalElement;
        for (var i:int = 0; i <= totalAmount; i++) 
        {
            yy = Math.floor(i / colsAmount);
            xx = uint(i % colsAmount);
            actualRatio = isTransforming?GaussianDistribution.getNormalizedValue(2 * xx / colsAmount - 1, 0, 0.25):ratio;
            actualRatio = isTransforming?GaussianDistribution.getNormalizedValueBivariate(2 * xx / colsAmount - 1, 2 * yy / rowsAmount - 1, -0.5, 0.25, -0.5, 0.25, 0):ratio;
            //actualRatio = isTransforming?SCMath.normalDistribution(2*xx / colsAmount-1, 0.5, 1):ratio;
            //actualRatio = isTransforming?xx / colsAmount:ratio;
            actualRatio = isRandomRatio?((bitmapData.getPixel(xx*separation, yy*separation) & 0xff) / 255):actualRatio;
            fundamentalElement = new FundamentalElement(separation * xx, separation * yy, eHeight, eWidth, actualRatio);
            orientation = (yy % 2 + i) % 2;
            //g.beginFill(colors[orientation]);
            //g.beginFill(0xcccccc);
            fundamentalElement.draw(g, orientation);
            
        }
        g.beginFill(0, 0);
    }
    
    private function setSeparation():void 
    {
        separation = _eWidth * 0.5 + _eHeight * 0.5;
    }
    
    public function get ratio():Number 
    {
        return _ratio;
    }
    
    public function set ratio(value:Number):void 
    {
        _ratio = value;
    }
    
    public function get colsAmount():uint 
    {
        return _colsAmount;
    }
    
    public function set colsAmount(value:uint):void 
    {
        _colsAmount = value;
        setRows();
    }
    
    public function get totalAmount():uint 
    {
        return _totalAmount;
    }
    
    public function set totalAmount(value:uint):void 
    {
        _totalAmount = value;
        setRows();
    }
    
    private function setRows():void 
    {
        rowsAmount = _totalAmount / _colsAmount;
    }
    
    public function get eWidth():Number 
    {
        return _eWidth;
    }
    
    public function set eWidth(value:Number):void 
    {
        _eWidth = value;
        setSeparation();
    }
    
    public function get eHeight():Number 
    {
        return _eHeight;
    }
    
    public function set eHeight(value:Number):void 
    {
        _eHeight = value;
        setSeparation();
    }
    
    public function get isRandomRatio():Boolean 
    {
        return _isRandomRatio;
    }
    
    public function set isRandomRatio(value:Boolean):void 
    {
        _isRandomRatio = value;
    }
    
    
}

import flash.display.Graphics;
import flash.geom.Matrix;
import flash.geom.Point;
class FundamentalElement 
{
    private var cx:Number;
    private var cy:Number;
    private var height:Number;
    private var width:Number;
    private var ratio:Number;
    private var AA:Point;
    private var BB:Point;
    private var matrix:Matrix;
    private var array:Array;
    
    public function FundamentalElement(cx:Number, cy:Number, height:Number, width:Number, ratio:Number) 
    {
        this.ratio = ratio;
        this.width = width;
        this.height = height;
        this.cy = cy;
        this.cx = cx;
        AA = new Point;
        BB = new Point;
        matrix = new Matrix;
        matrix.rotate(Math.PI * 0.5);
        
        doSet();
    }
    
    private function doSet():void 
    {
        AA.x = ratio * width * 0.5;
        AA.y = 0.5 * height;
        
        
        BB.x = 0.5 * width;
        array = [AA,BB,new Point(AA.x,-AA.y),new Point(-AA.x,-AA.y),new Point(-BB.x,BB.y),new Point(-AA.x,AA.y)];
    }
    
    public function draw(g:Graphics,isRotated:uint=0):void 
    {
        if (isRotated) 
        {
            for (var i:int = 0; i < array.length; i++) 
            {
                array[i] = matrix.transformPoint(array[i]);
            }
        }
        g.moveTo(cx + array[array.length-1].x, cy + array[array.length-1].y);
        for (var j:int = 0; j < array.length; j++) 
        {
            g.lineTo(cx+array[j].x, cy+array[j].y);
        }
    }
    
    
}
class SCMath
{
    static private var normalDistriutionFactor:Number = 1 / Math.sqrt(Math.PI * 2);
    static public function normalDistribution(x:Number, mu:Number, sigma:Number):Number
    {
        var s:Number = 1 / sigma;
        return s*normalDistriutionFactor*Math.pow(Math.E,-(x-mu)*(x-mu)*s*s*0.5);
    }
}
class GaussianDistribution 
{
    private var mu:Number;
    private var _sigma:Number;
    private var factor:Number;
    
    public function GaussianDistribution(mu:Number, sigma:Number) 
    {
        this.sigma = sigma;
        this.mu = mu;
        
        
    }
    
    public function getData():Array 
    {
        var gaussian:Number;
        var pow:Number;
        var xx:Number;
        var normal:Number;
        var steps:int = 100;
        var delta:Number = 1 / steps;
        var data:Array = [];
        var initxx:Number = -5;
        var finalxx:Number = 5;
        var size:Number = 10;
        size = finalxx > initxx?finalxx - initxx:initxx - finalxx;
        for (var i:int = 0; i < steps; i++) 
        {
            normal = i * delta;
            xx = size * (normal - 0.5);
            pow = -(xx - mu) * (xx - mu)/(2*sigma*sigma);
            gaussian = factor * Math.pow(Math.E, pow);
            data[i] = gaussian;
        }
        return data;
    
    }
    
    public static function getNormalizedValue(xx:Number, mu:Number, sigma:Number):Number
    {
        return getValue(xx, mu, sigma) / getValue(mu, mu, sigma);
    }
    public static function getValue(xx:Number, mu:Number, sigma:Number):Number
    {
        var gaussian:Number;
        var pow:Number;
        var s:Number = 1 / sigma;
        var factor:Number  = s / Math.sqrt(2 * Math.PI);
        pow = -(xx - mu) * (xx - mu)*s*s*0.5;            
        gaussian = factor * Math.pow(Math.E, pow);
        return gaussian
    }
    
    public function get sigma():Number 
    {
        return _sigma;
    }
    
    public function set sigma(value:Number):void 
    {
        _sigma = value;
        factor = 1 /( sigma * Math.sqrt(2 * Math.PI));
    }
    public static function getNormalizedValueBivariate(xx:Number, yy:Number, mux:Number, sigmax:Number, muy:Number, sigmay:Number, rho:Number):Number
    {
        return getBivariate(xx, yy, mux,sigmax,muy, sigmay, rho) / getBivariate(mux, muy, mux, sigmax, muy,sigmay, rho);
    }
    public static function getBivariate(xx:Number, yy:Number, mux:Number, sigmax:Number, muy:Number, sigmay:Number, rho:Number):Number
    {
        var s:Number = 1 / (sigmax * sigmay);
        var r:Number = 1 - rho * rho;
        var factor:Number = s / (2 * Math.PI * Math.sqrt(r));
        var dx:Number = xx - mux;
        var dy:Number = yy - muy;
        var sxy:Number = sigmax * sigmay;
        var squareBracket:Number = (dx * dx) / (sigmax * sigmax) + (dy * dy) / (sigmay * sigmay) - 2 * rho * (dx * dy) * s;
        var gaussian:Number = 0.5*s/(Math.PI*Math.sqrt(r))*Math.pow(Math.E, -0.5*squareBracket/r);
        return gaussian;
    }    
}