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

せいき分布 forked from: Checkmate Vol.6 Amatuer

激しくこすって分散を小さくしよう!
/**
 * Copyright knd ( http://wonderfl.net/user/knd )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/soLw
 */

// forked from checkmate's Checkmate Vol.6 Amatuer
package {
	import flash.display.GraphicsPathCommand;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.utils.getTimer;
	
	/**
	 * 激しくこすって分散を小さくしよう!
	 */
    public class CheckmateAmatuer extends Sprite {
		private const N:uint = 20;
		private const _2N: uint = N << 1; //分割数
		private const W_2:uint = 232;
		private const D:Number = Number(232) / N; //x方向のプロット間隔
		private const Y0:Number = 288.0;
		private var pltPts:Vector.<Point> = new Vector.<Point>();
		private var ctrlPts:Vector.<Point> = new Vector.<Point>();
		private var prevPts:Vector.<Point> = new Vector.<Point>();
		private var work:Number = 0;
		private var prev1X:Number;
		private var prev1Y:Number;
		private var prev2X:Number;
		private var prev2Y:Number;
		private var mouseOut:Boolean = false;
		
		private const C_SQ:Number = 1.0; //波の伝播速度の二乗
		private const DIST:Number = 0.05; //減衰係数
		private const REF:Number = 0.8; //反射係数
		
            public function CheckmateAmatuer() {
            /*
            コードでエッチなものごとを描写してください。
            公序良俗は守ってください。
            
            Represent something sexual by codes.
            DO NOT be offensive to public order and morals.
            */
			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
			
			pltPts[i] = new Point(0,0);
			for (var i:uint = 0; i< _2N; i+=1) 
			{
				var xc:Number = D * i ;
				var xp:Number = D * (i + 0.5);
				ctrlPts[i] = new Point(xc, 0);
				prevPts[i] = new Point(xc, 0);
				pltPts[i + 1] = new Point(xp, 0);
			}
			ctrlPts[i] = new Point(2 * W_2, 0);
			prevPts[i] = new Point(2 * W_2, 0);
			pltPts[_2N + 1] = new Point(2 * W_2, 0);
			
			prev1X = prev2X = mouseX;
			prev1Y = prev2Y = mouseY;
			addEventListener(Event.ENTER_FRAME, loop);
			stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
		}
		
		private function mouseLeave(e:Event):void 
		{
			stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseExists);
		}
		
		private function mouseExists(e:MouseEvent):void 
		{
			mouseOut = true;
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseExists);
		}
		
		//drawPathで曲線を引く
		private function draw():void
		{
			var commands:Vector.<int> = new Vector.<int>();
			var data:Vector.<Number> = new Vector.<Number>();
			commands.push(GraphicsPathCommand.MOVE_TO);
			data.push(pltPts[0].x, Y0 + pltPts[0].y);
			for (var i:int = 0; i <= _2N; i ++)
			{
				commands.push(GraphicsPathCommand.CURVE_TO);
				data.push(ctrlPts[i].x, Y0 + ctrlPts[i].y, pltPts[i + 1].x, Y0 + pltPts[i + 1].y);
			}
			graphics.clear();
			graphics.lineStyle(0, 0x333333);
			graphics.drawPath(commands, data);
		}
		
		private function loop(e:Event):void 
		{
			//マウスの加速度を力積として
			if (mouseOut)
			{
				prev1X = prev2X = mouseX;
				prev1Y = prev2Y = mouseY;
				mouseOut = false;
			}
			var frcX:Number = mouseX - 2 * prev1X + prev2X;
			var frcY:Number = mouseY - 2 * prev1Y + prev2Y;
			work = 0.95 * (work + 0.3 * Math.sqrt(frcX * frcX + frcY * frcY));
			prev2X = prev1X;
			prev2Y = prev1Y;
			prev1X = mouseX;
			prev1Y = mouseY;
			
			//分散
			var tw_sgm_sq:Number = 100 - work * 0.25;
			tw_sgm_sq = 2 * tw_sgm_sq * tw_sgm_sq;
			
			var dy: Number = 0.07 * work;
			
			var i:int;
			var _x:Number;
			for (i = 0; i<= _2N; i++) 
			{
				_x = ctrlPts[i].x - W_2;
				ctrlPts[i].y = - work * Math.exp( - _x * _x / tw_sgm_sq) + (i & 1 == 0? dy* Math.random(): -dy* Math.random()) ;
			}
			
			pltPts[0].y = ctrlPts[0].y;
			for (i = 1; i<= _2N; i++) 
			{
				pltPts[i].y = (ctrlPts[i-1].y + ctrlPts[i].y) * 0.5;
			}
			pltPts[_2N + 1].y = ctrlPts[_2N].y;
			
			draw();
			
			if (work > Y0) 
			{
				removeEventListener(Event.ENTER_FRAME, loop);
				for (i = 0; i<= N; i++) 
				{
					prevPts[i].y = prevPts[_2N - i].y = ctrlPts[i].y;
				}
				addEventListener(Event.ENTER_FRAME, reduce);
			}
		}
		
		//爆ぜる
		private function reduce(e:Event):void 
		{
			var i:int;
			var nextY:Vector.<Number> = new Vector.<Number>();
			
			//波動方程式からゴニョゴニョ
			nextY[0] = ctrlPts[0].y + 1 / (1 + DIST) * 
				(C_SQ * (REF * ctrlPts[1].y - 2 * ctrlPts[0].y + ctrlPts[1].y) + ctrlPts[0].y - prevPts[0].y);
			for (i = 1; i< _2N; i+=1) 
			{
				nextY[i] = ctrlPts[i].y + 1 / (1 + DIST) * 
					(C_SQ * (ctrlPts[i - 1].y - 2 * ctrlPts[i].y + ctrlPts[i + 1].y) + ctrlPts[i].y - prevPts[i].y);
			}
			nextY[_2N] = ctrlPts[_2N].y + 1 / (1 + DIST) * 
				(C_SQ * (REF * ctrlPts[_2N - 1].y - 2 * ctrlPts[_2N].y + ctrlPts[_2N - 1].y) + ctrlPts[_2N].y - prevPts[_2N].y);
			
			prevPts[0].y = ctrlPts[0].y;
			ctrlPts[0].y = nextY[0];
			var max:Number = nextY[0], min:Number = nextY[0];
						
			pltPts[0].y = ctrlPts[0].y;
			for (i = 1; i<= _2N; i++) 
			{
				prevPts[i].y = ctrlPts[i].y;
				ctrlPts[i].y = nextY[i];
				pltPts[i].y = (ctrlPts[i - 1].y + ctrlPts[i].y) * 0.5;
				if (nextY[i] > max) max = nextY[i];
				if (nextY[i] < min) min = nextY[i];
			}
			pltPts[_2N + 1].y = ctrlPts[_2N].y;
			
			draw();
			
			if (max < 1 && min > -1)
			{
				removeEventListener(Event.ENTER_FRAME, reduce);
				prev1X = prev2X = mouseX;
				prev1Y = prev2Y = mouseY;
				work = 0;
				addEventListener(Event.ENTER_FRAME, loop);
			}
		}
		
	}
	
}