In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Lorenz Attractor - forked from: nengafl

Lorenz Attractor
@author Hiiragi

ビギナーの人が楽しめるのがルールということなので、考えてみたんですが、
Flashを始めて最初に衝撃を受けたのが、このきれいな模様を描いていく作品でした。
あまりの綺麗さに、ずっと見とれていた記憶があります。今でもそうですけど。
50 - 52行目の定数の値を弄ると動きが変わりますので
よかったら、ForkするなりDownloadするなりで試してみてください。

最近いろいろ凹み気味なので、初心を忘れないためにも、挑戦してみました。
なお、参考サイトをかなり参考にしました。(高校数学サボってた人なので数式判らん)
計算式は弄りようがないので、ほぼそのままです。

本当はcopyPixelsの第4引数以降のアルファを適用して、
奥に行くほどにアルファ値を下げるとかしたかったのですが、うまくいきませんでした・・・。

参考
http://www.procreo.jp/labo/labo08.html
http://ton-up.net/blog/archives/92
Get Adobe Flash player
by Hiiragi 20 Jan 2010
/**
 * Copyright Hiiragi ( http://wonderfl.net/user/Hiiragi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4DzZ
 */

// forked from nengafl's nengafl
package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.GradientType;
	import flash.display.PixelSnapping;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.filters.GlowFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Timer;
	import net.hires.debug.Stats;
	
	/**
	 * Lorenz Attractor
	 * @author Hiiragi
	 * 
	 * ビギナーの人が楽しめるのがルールということなので、考えてみたんですが、
	 * Flashを始めて最初に衝撃を受けたのが、このきれいな模様を描いていく作品でした。
	 * あまりの綺麗さに、ずっと見とれていた記憶があります。今でもそうですけど。
	 * 50 - 52行目の定数の値を弄ると動きが変わりますので
	 * よかったら、ForkするなりDownloadするなりで試してみてください。
	 * 
	 * 最近いろいろ凹み気味なので、初心を忘れないためにも、挑戦してみました。
	 * なお、参考サイトをかなり参考にしました。(高校数学サボってた人なので数式判らん)
	 * 計算式は弄りようがないので、ほぼそのままです。
	 *
	 * 本当はcopyPixelsの第4引数以降のアルファを適用して、
	 * 奥に行くほどにアルファ値を下げるとかしたかったのですが、うまくいきませんでした・・・。
	 * 
	 * 参考
	 * http://www.procreo.jp/labo/labo08.html
	 * http://ton-up.net/blog/archives/92
	 * 
	 */
	
	[SWF(width = 465, height = 465, frameRate = 120, backgroundColor = 0x000000)]
	public class Main extends Sprite 
	{
		//ピクセルそのままだと模様が荒くなるので、ステージを倍にしてます
		private const STAGE_SCALE:Number = 2;
		private const BMPD_SCALE:int = 16;
		
		//公式に使われる定数
		private var _p:Number = 10;
		private var _r:Number = 28;
		private var _b:Number = 8 / 3;
		
		//よくわかりません(汗
		private var _d:Number = 0.01;
		
		//描画用BitmapData
		private var _canvas:BitmapData;
		private var _forCopyBmpd:BitmapData;
		
		//copyPixels用Circle設定
		private var _particleSp:Sprite;
		private var _particleColor:int = 0x00FF00;
		private var _particleRadius:int = 3;
		
		//一時的に数値を保持するための変数
		private var _dx:Number;
		private var _dy:Number;
		private var _dz:Number;
		
		//現在の座標を保持する変数
		private var _nowX:Number = 1;
		private var _nowY:Number = 1;
		private var _nowZ:Number = 1;
		
		//Utils
		private var _rect:Rectangle;
		private var _perticleRect:Rectangle;
		private var _pt:Point;
		private var _ct:ColorTransform;
		
		public function Main():void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
		
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
			
			//setting
			_rect = new Rectangle(0, 0, this.stage.stageWidth * STAGE_SCALE, this.stage.stageHeight * STAGE_SCALE);
			_perticleRect = new Rectangle(0, 0, _particleRadius * 2, _particleRadius * 2);
			_pt = new Point();
			_ct = new ColorTransform(1, 1, 1, 0.99);
			
			//canvas
			_canvas = new BitmapData(this.stage.stageWidth * STAGE_SCALE, this.stage.stageHeight * STAGE_SCALE, true, 0);
			var bmp:Bitmap = new Bitmap(_canvas, PixelSnapping.AUTO, true);
			bmp.scaleX = bmp.scaleY = 1 / STAGE_SCALE;
			bmp.filters = [new GlowFilter(_particleColor, 1, 8, 8, 2, 1)];
			this.addChild(bmp);
			
			//forCopyBmpd(Circle)
			_forCopyBmpd = new BitmapData(_particleRadius * 2, _particleRadius * 2, true, 0);
			_particleSp = new Sprite();
			_particleSp.graphics.beginFill(_particleColor, 1);
			_particleSp.graphics.drawCircle(_particleRadius, _particleRadius, _particleRadius);
			_particleSp.graphics.endFill();
			_forCopyBmpd.draw(_particleSp);
			
			//debug
			this.addChild(new Stats());
			
			//EnterFrame
			this.addEventListener(Event.ENTER_FRAME, update);
			
			//Timer
			var timer:Timer = new Timer(400);
			timer.addEventListener(TimerEvent.TIMER, onTimerHandler);
			timer.start();
		}
		
		private function onTimerHandler(e:TimerEvent):void 
		{
			//色を少しずつ落とす
			_canvas.colorTransform(_rect, _ct);
		}

		private function update(e:Event):void 
		{
			//LorenzAttractorの公式
			//http://ja.wikipedia.org/wiki/%E3%83%AD%E3%83%BC%E3%83%AC%E3%83%B3%E3%83%84%E6%96%B9%E7%A8%8B%E5%BC%8F
			_dx = _p * (_nowY - _nowX);
			_dy = _nowX * (_r - _nowZ) - _nowY;
			_dz = _nowX * _nowY - _b * _nowZ;
			
			//現在の座標に適用(3Dを作り方を知らないので、Z軸は結局使ってない)
			_nowX += _d * _dx;
			_nowY += _d * _dy;
			_nowZ += _d * _dz;
			
			//その場所にCircleを描く(本当はアルファを設定したかった・・・)
			_canvas.copyPixels(_forCopyBmpd, _perticleRect,
								new Point(_nowX * BMPD_SCALE + this.stage.stageWidth * STAGE_SCALE / 2, _nowY * BMPD_SCALE + this.stage.stageHeight * STAGE_SCALE / 2)
								);
		}
	}
	
}