/** * こりずにまたカオスです * * 名前は知らないけど、個人的にはこのアトラクタが一番好きだったりします * かっこいいよね! * * パラメータによっては描画に時間がかかるので * もう一度画面をクリックしてください * * @author alumican.net */ package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.events.Event; import flash.events.MouseEvent; import flash.display.Sprite; import flash.filters.BlurFilter; import flash.geom.ColorTransform; import flash.geom.Point; import com.flashdynamix.utils.SWFProfiler; public class UnknownAttractor extends Sprite { private const ZEROS:Point = new Point(0, 0); //パーティクル数 private const N:uint = 10000; //linked listの先頭インスタンス private var _head:Particle; //描画用 private var _canvas:BitmapData; private var _buffer:BitmapData; private var _w:uint = 465; private var _h:uint = 465; private var _blur:BlurFilter = new BlurFilter(8, 8, 3); private var _trans:ColorTransform = new ColorTransform(1, 1, 1, 0.9); //パラメータ群 private var _a:Number; private var _b:Number; private var _c:Number; private var _d:Number; private var _theta:Number; private var _sin:Number; private var _cos:Number; private var _scale:Number; private var _color:uint; private var _count:uint = 0; //-------------------------------------------------- //コンストラクタ public function UnknownAttractor():void { Wonderfl.disable_capture(); stage.frameRate = 60; //パーティクル生成 var o:Particle = _head = new Particle(); for (var i:uint = 0; i < N; ++i) { o = o.next = new Particle(); } //イベントリスナ登録 addEventListener(Event.ENTER_FRAME, _update); stage.addEventListener(MouseEvent.CLICK, _reset); //描画用BitmapData生成 _canvas = new BitmapData(_w, _h, true, 0xffffff); _buffer = _canvas.clone(); addChild(new Bitmap(_canvas)); //パラメータ群の初期化 _reset(); _a = -1.47; _b = 0.9; _c = -4; _d = 30.0; _theta = 0; _sin = Math.sin(_theta); _cos = Math.cos(_theta); _scale = 10; //プロファイラの表示 SWFProfiler.init(this); } //-------------------------------------------------- //パラメータ群の再設定 private function _reset(e:MouseEvent = null):void { _buffer.fillRect(_buffer.rect, 0xffffff); //パラメータの再設定と調整 _a = Math.random() * (1.6 + 1.3) - 1.3; _b = Math.random() * (0.99 - 0.8) + 0.8; _c = -4.0; _d = 30.0; _theta = Math.random() * 2 * Math.PI; _sin = Math.sin(_theta); _cos = Math.cos(_theta); _scale = (Math.random() * 6 + 6) * _w / 465; _color = int(Math.random() * 0x66) << 16 | int(Math.random() * 0x66) << 8 | int(Math.random() * 0x66); _spreadParticle(); } //-------------------------------------------------- //パーティクルを分散させる private function _spreadParticle():void { var p:Particle = _head; do { p.x = (Math.random() - 0.5) * _w; p.y = (Math.random() - 0.5) * _h; } while (p = p.next); } //-------------------------------------------------- //毎フレーム更新 private function _update(e:Event):void { if (++_count % 120 == 0) { _count = 0; _spreadParticle(); } //パーティクルの座標を更新する _buffer.lock(); var p:Particle = _head; var x0:Number, y0:Number, x1:Number, y1:Number, x2:Number, y2:Number; do { //座標の更新 x0 = p.x; y0 = p.y; x1 = p.x = _a * x0 + _b * y0 + _c + _d / (1 + x0 * x0); y1 = p.y = -x0; //回転とスケール x2 = _w / 2 + _scale * (_cos * x1 - _sin * y1); y2 = _h / 2 + _scale * (_sin * x1 + _cos * y1); //描画 _buffer.setPixel32(x2, y2, (Math.min(0xff, (_buffer.getPixel32(x2, y2) >>> 24) + 0x03) << 24) | _color); } while (p = p.next); _buffer.unlock(); //キャンバスに描画する _canvas.lock(); _canvas.colorTransform(_canvas.rect, _trans); _canvas.applyFilter(_canvas, _canvas.rect, ZEROS, _blur); _canvas.draw(_buffer); _canvas.unlock(); } } } //-------------------------------------------------- //パーティクルクラス internal class Particle { public var x:Number; public var y:Number; public var next:Particle; } Unknown Attractor