Beautifl - Flash Gallery

Thumbnail : Dot Plot
Dot Plot
hycro 2010-07-16 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

// ランダムに生成した数式をプロットします。
// クリックで数式の生成をやり直します。
package
{
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.filters.BlurFilter;
    import flash.geom.ColorTransform;
    import flash.geom.Matrix3D;
    import flash.geom.Point;
    import flash.geom.Vector3D;
    
    [SWF(width="465", height="465", frameRate="60")]
    public class Sketch03 extends Sprite
    {
        private var _canvas:BitmapData;
        private var _points:Vector.<Number>;
        private var _colorTransform:ColorTransform;
        private var _blurFilter:BlurFilter;
        
        public function Sketch03()
        {
            init();
        }
        
        private function init():void
        {
            _canvas = new BitmapData(465, 465, true, 0xFF000000);
            addChild(new Bitmap(_canvas));
            
            _points = createPoint();
            
            _colorTransform = new ColorTransform(.9, .9, .9);
            _blurFilter = new BlurFilter(2, 2);
            
            addEventListener(Event.ENTER_FRAME, onEnterFrame);
            stage.addEventListener(MouseEvent.CLICK, onClick);
        }
        
        private function createPoint():Vector.<Number>
        {
            var points:Vector.<Number> = new Vector.<Number>();
            var fx:Function = createFunction();
            var fy:Function = createFunction();
            var fz:Function = createFunction();
            var nx:Number;
            var ny:Number;
            var nz:Number;
            var max:Array = [Number.MIN_VALUE, Number.MIN_VALUE, Number.MIN_VALUE];
            var min:Array = [Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE];
            for (var u:Number=0; u < 2*Math.PI; u += 0.07) {
                for (var v:Number=0; v < 2*Math.PI; v += 0.07) {
                    nx = fx(u, v);
                    ny = fy(u, v);
                    nz = fz(u, v);
                    
                    points.push(nx);
                    points.push(ny);
                    points.push(nz);
                    
                    if (max[0] < nx) {
                        max[0] = nx;
                    }
                    if (min[0] > nx) {
                        min[0] = nx;
                    }
                    if (max[1] < ny) {
                        max[1] = ny;
                    }
                    if (min[1] > ny) {
                        min[1] = ny;
                    }
                    if (max[2] < nz) {
                        max[2] = nz;
                    }
                    if (min[2] > nz) {
                        min[2] = nz;
                    }
                }
            }
            
            var scale:Number = 400 / Math.max(Math.abs(max[0] - min[0]),
                                               Math.abs(max[1] - min[1]),
                                               Math.abs(max[2] - min[2]));
            
            for (var i:uint = 0; i < points.length; i++) {
                points[i] *= scale;
            }
            
            return points;
        }
        
        private function createFunction():Function
        {
            var seed:Array = [];
            for (var i:uint = 0; i<8; i++) {
                seed.push(Math.random());
            }
            
            return function(u:Number, v:Number):Number
            {
                var v1:Number = randomOp(seed[0], v);
                var v2:Number = randomOp(seed[1], v);
                var v3:Number = randomOp(seed[2], v);
                var v4:Number = randomOp(seed[3], v);
                var u1:Number = randomOp(seed[4], u);
                var u2:Number = randomOp(seed[5], u);
                var u3:Number = randomOp(seed[6], u);
                var u4:Number = randomOp(seed[7], u);
                
                return randomOp2(seed[6],
                    randomOp2(seed[2], randomOp2(seed[1], randomOp2(seed[0], v1, v2), v3), v4),
                    randomOp2(seed[5], randomOp2(seed[4], randomOp2(seed[3], u1, u2), u3), u4));
            }
        }
        
        private function randomOp(seed:Number, v:Number):Number
        {
            if (seed < .25) {
                return Math.cos(v);
            } else if (seed < .5) {
                return Math.sin(v);
            } else if (seed < .75) {
                return Math.cos(v/2);
            } else {
                return Math.sin(v/2);
            }
        }
        
        private function randomOp2(seed:Number, v:Number, u:Number):Number
        {
            if (seed < .25) {
                return v + u;
            } else if (seed < .5) {
                return v * u;
            } else if (seed < .75) {
                return - v * u;
            } else {
                return v * v + u * u;
            }
        }
        
        private function onEnterFrame(evt:Event):void 
        {
            var mat:Matrix3D = new Matrix3D();
            mat.appendRotation(1, Vector3D.Y_AXIS);
            mat.transformVectors(_points, _points);
            
            var c:uint;
            var d:Number;
            var length:uint = _points.length;
            _canvas.lock();
            _canvas.colorTransform(_canvas.rect, _colorTransform);
            _canvas.applyFilter(_canvas, _canvas.rect, new Point(0, 0), _blurFilter);
            for (var i:uint=0; i < length; i += 3) {
                if (_points[i+2] > 0) {
                    d = 1 - Math.min(1, Math.abs(_points[i+2] / 200));
                    c = ((0xFF * d) << 16) | ((0xFF * d) << 8) | (0xFF * d);
                } else {
                    c = 0xFFFFFF;
                }
                if (_canvas.getPixel(_points[i] + 232, _points[i+1] + 232) < c) {
                    _canvas.setPixel(_points[i] + 232, _points[i+1] + 232, c);
                }
            }
            _canvas.unlock();
        }
        
        private function onClick(evt:MouseEvent):void
        {
            _points = createPoint();
        }
    }
}