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
/**
* 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)
);
}
}
}