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

C曲線 (Levy C curve)

C曲線(Levy c curve)を描く
@author H.Horiuchi
Get Adobe Flash player
by Horiuchi_H 21 Nov 2009
/**
 * Copyright Horiuchi_H ( http://wonderfl.net/user/Horiuchi_H )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/tmnw
 */

package 
{
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.AntiAliasType;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;

	[SWF(width = 465, height = 465, frameRate = 30, backgroundColor = "#000000")]

	/**
	 * C曲線(Levy c curve)を描く
	 * @author H.Horiuchi
	 */
	public class Main extends Sprite 
	{
		private var counter_:int = 10;
		private var counterField_:TextField = new TextField();
		private var cachePoints_:Vector.<Vector.<Point>> = new Vector.<Vector.<Point>>();
		
		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);
			
			var width:int = this.stage.stageWidth;
			var height:int = this.stage.stageHeight;
			// 初期値だけ設定しておく
			var level0:Vector.<Point> = new Vector.<Point>();
			level0.push(new Point(width / 4, height * 2 / 3), new Point(width * 3 / 4, height * 2 / 3));
			cachePoints_.push(level0);
			
			configureCounterField();
			this.addChild(counterField_);
			
			// ClickでLevelを+1、Shiftを押してると-1
			this.stage.addEventListener(MouseEvent.CLICK, function(event:MouseEvent):void {
				counter_ += (event.shiftKey)? -1: 1;
				refresh();
			});
			// Wheelでも Levelを上下
			this.stage.addEventListener(MouseEvent.MOUSE_WHEEL, function(event:MouseEvent):void {
				counter_ += (event.delta > 0)? -1: 1;
				refresh();
			});
			refresh();
		}
		
		private function configureCounterField():void
		{
			counterField_.x = 0;
			counterField_.y = 465 - 60;
			counterField_.antiAliasType = AntiAliasType.ADVANCED;
			counterField_.autoSize = TextFieldAutoSize.CENTER;
			var format:TextFormat = new TextFormat();
			format.color = 0xCCCCCC;
			format.size = 36;
			counterField_.defaultTextFormat = format;
		}
		
		private function refresh():void 
		{
			if (counter_ < 0) {
				counter_ = 0;
			}
			drawCCurve(counter_);
			counterField_.text = counter_.toString();
		}
		
		private function drawCCurve(level:int):void
		{
			var g:Graphics = this.graphics;
			g.clear();
			g.lineStyle(1, 0xFFFFFF);
			
			// まだ座標計算してなかった時に計算する
			if (cachePoints_.length <= level) {
				createCCurve(level);
			}
			var points:Vector.<Point> = cachePoints_[level];
			g.moveTo(points[0].x, points[0].y);
			for (var index:int = 1; index < points.length; index++) {
				g.lineTo(points[index].x, points[index].y);
			}
		}
		
		private function createCCurve(level:int):void 
		{
			if (cachePoints_.length < level) {
				createCCurve(level - 1);
			}
			var points:Vector.<Point> = new Vector.<Point>();
			var prevPoints:Vector.<Point> = cachePoints_[level - 1];
			points.push(prevPoints[0]);
			for (var index:int = 1; index < prevPoints.length; index++) {
				var start:Point = prevPoints[index - 1];
				var end:Point = prevPoints[index];
				
				var distance:Number = Point.distance(start, end) / 2 * Math.SQRT2;
				var angle:Number = Math.atan2(end.y - start.y, end.x - start.x);
				var addPoint:Point = new Point(
					distance * Math.cos(angle-Math.PI / 4) + start.x,
					distance * Math.sin(angle-Math.PI / 4) + start.y
				);
				points.push(addPoint);
				points.push(end);
			}
			cachePoints_.push(points);
		}
		
	}
}