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

リマソン第2弾 (定義編)

Created: 2010-03-04 by tenasaku
Get Adobe Flash player
by tenasaku 04 Mar 2010
/**
 * Copyright tenasaku ( http://wonderfl.net/user/tenasaku )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/kA8r
 */

package 
{
	// Created: 2010-03-04 by tenasaku

	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;

	public class Main extends Sprite 
	{
		// リマソン(蝸牛線)の定義を説明するためのプログラムです
		// 円周 ( 直径: d ) の上に一点 O を固定し、
		// その点 O を通る直線 (緑色) と円周のもうひとつの
		// 交点 P から, 一定の距離 a だけ離れた点 Q を
		// その直線の延長上にとるとします
		// 直線をぐるっと360度動かしたとき 動点 Q の描く軌跡が
		// リマソンです
		// a = d のときの形はとくに カージオイド と呼ばれています

		private var _banner:TextField; // タイトルなどを表示
		private var _tf:TextField; // 時々刻々の情報を表示
		private var Li:Limacon; // 本日の主役リマソンさん
		private var Ray:Sprite; // ガイド役の直線
		
		// プログラム本体...
		public function Main():void 
		{
		[SWF(width="465",height="465",backgroundcolor="#000000")]
			// 前振りなしにいきなり主役が登場するのは、
			// 見出し用のテキストフィールドの値に
			// 主役 Li のプロパティを引用しているからです
			Li = new Limacon(180, 90, 0);
			Li.color = 0x800000;
			Li.thickness = 2;
			Li.x = 152;
			Li.y = 232;
			Li.showCircle = true;
			Li.circleColor = 0x000000;
			Li.draw();
			addChild(Li);
			// ガイド用の直線
			Ray = new Sprite();
			Ray.graphics.clear();
			addChild(Ray);
			// 見出し用テキストフィールド
			_banner = new TextField();
			_banner.background = true;
			_banner.backgroundColor = 0xffffff;
			_banner.text = "Pascal's Limaçon\n[ a = " + String(Li.a / Li.d) + "d ]";
			_banner.x = 10;
			_banner.y = 2;
			_banner.textColor = 0x800000;
			_banner.width = 200;
			_banner.height = 80;
			_banner.alpha = 0.6
			addChild(_banner);
			// 表示用テキストフィールド
			_tf = new TextField();
			_tf.text = "";
			_tf.x = 10;
			_tf.y = 40;
			_tf.width = 200;
			_tf.textColor = 0x000080;
			addChild(_tf);
			// 各フレームごとに表示を更新するハンドラーを登録
			addEventListener(Event.ENTER_FRAME, _as_time_passes);
		}
		
		// draw a straight line passing thru limaçon's origin and the mouse position ...
		// 原点とマウスの位置を通る直線を描きます (しかし妙にコムズカシくなってしまった...)
		private function draw_ray():void {
			var dx:Number = mouseX - Li.x; // <dx,dy> is the orientation of the line
			var dy:Number = mouseY - Li.y;
			var nx:Number; // <nx,ny> is the orthogonal direction
			var ny:Number;
			var Ax:Number; // at <Ax,Ay>, the line crosses the boundary.
			var Ay:Number;
			var Bx:Number; // <Bx,By> is the other cross point.
			var By:Number;
			Ray.graphics.clear();
			Ray.graphics.lineStyle(1,0x00ff00);
			// Draw only if <dx,dy> is not the zero vector...
			if (( dx != 0 ) || (dy != 0)) {
				// normalize <dx,dy>...
				var _r:Number = Math.sqrt(dx * dx + dy * dy);
				dx /= _r;
				dy /= _r;
				// a unit vector perpendicular to <dx,dy>
				nx = - dy;
				ny = + dx;
				// Determine where does the line cross the boundary of Stage.
				var _NW:Number = nx * (-Li.x) + ny * (-Li.y);
				var _SW:Number = nx * (-Li.x) + ny * (stage.stageHeight-Li.y);
				var _SE:Number = nx * (stage.stageWidth-Li.x) + ny * (stage.stageHeight-Li.y);
				var _NE:Number = nx * (stage.stageWidth-Li.x) + ny * (-Li.y);
				var _EAST:Boolean = ( _NE*_SE < 0 ); // if the line crosses the east end of stage.
				var _WEST:Boolean = ( _NW*_SW < 0 ); // if the line crosses the west end of stage.
				var _NORTH:Boolean = ( _NE*_NW <= 0 ); // if the line crosses the north end of stage.
				var _SOUTH:Boolean = ( _SE*_SW <= 0 ); // if the line crosses the south end of stage.
				if ( _EAST ) { // if _EAST, then dx can never be zero.
					Bx = stage.stageWidth;
					By = Li.y + (dy/dx)*(stage.stageWidth-Li.x);
					if ( _NORTH ) {
						Ax = Li.x - (dx/dy)*Li.y;
						Ay = 0;
					} else {
						if ( _SOUTH ) {
							Ax = Li.x + (dx/dy)*(stage.stageHeight-Li.y);
							Ay = stage.stageHeight;
						} else { // _WEST must be the case
							Ax = 0;
							Ay = Li.y - (dy/dx)*Li.x;
						}
					}
				} else { // if not _EAST, three cases remain...
					if ( _NORTH && _SOUTH ) {
						Ax = Li.x - (dx/dy)*Li.y;
						Ay = 0;
						Bx = Li.x + (dx/dy)*(stage.stageHeight-Li.y);
						By = stage.stageHeight;
					}
					if ( _NORTH && _WEST ) {
						Ax = Li.x - (dx/dy)*Li.y;
						Ay = 0;
						Bx = 0;
						By = Li.y - (dy/dx)*Li.x;
					}
					if ( _SOUTH && _WEST ) {
						Ax = Li.x + (dx/dy)*(stage.stageHeight-Li.y);
						Ay = stage.stageHeight;
						Bx = 0;
						By = Li.y - (dy/dx)*Li.x;
					}
				}
				Ray.graphics.moveTo(Ax,Ay);
				Ray.graphics.lineTo(Bx,By);
			}
		}

		// マウスがステージにあれば原点から直線を引き、
		// 方向(角度)をテキストフィールドに表示します
		private function _as_time_passes(e:Event):void {
			if ( ( mouseX >= 0)
			 && (mouseY >= 0)
			 && (mouseX < stage.stageWidth)
			 && (mouseY < stage.stageHeight) ) {
				draw_ray();
			}
			var deg:int = Math.round(Math.atan2( - (mouseY-Li.y), mouseX-Li.x) / Math.PI*180);
			_tf.text = "direction = " + String(deg) + " (deg)";
		}

	} // end of class Main
} // end of package

/* ===================== */

// Limacon: a class which embodies Pascal's Limaçon.
// --------
// Pascal's Limaçon is the plain curve determined by the polar equation 
//    r = d*cos(theta - phi) + a  [ where 0 <= theta <= 2*PI ].
// --------
// Note: 
//		Constructor doesn't draw.  You call draw() method explicitly.
// --------
import flash.display.Sprite;
class Limacon extends Sprite {
	public var d:Number; // Set by the constructor.
	public var a:Number; // ditto.
	public var phi:Number; // ditto. These three parameters are mandatory.
	public var thickness:uint; // default: 2
	public var color:uint; // default: 0x000000 ( black )
	public var showCircle:Boolean; // Want the circle displayed? (defalut: false) 
	public var showLine:Boolean; // Want the diameter displayed? (defalut: false) 
	public var circleColor:uint; // default: 0xffffff ( white )
	public var lineColor:uint; // default: 0xffffff ( white )
	// Draws the curve using given parameters
	public function draw():void {
		var i:int;
		var t:Number;
		var r:Number;
		this.graphics.clear();
		this.graphics.lineStyle(thickness, color);
		for ( i = 0; i <= 90; ++i ) {
			t = this.phi + i * Math.PI / 45;
			r = this.d * Math.cos(t - phi) + this.a;
			if (i == 0) {
				this.graphics.moveTo(r * Math.cos(t), r * Math.sin(t));
			}
			else {
				this.graphics.lineTo(r * Math.cos(t), r * Math.sin(t));
			}
		}
		if ( showCircle ) {
			this.graphics.lineStyle(1, this.circleColor);
			this.graphics.drawCircle(this.d / 2 * Math.cos(phi), - this.d / 2 * Math.sin(phi), d / 2);
		}
		if ( showLine ) {
			this.graphics.lineStyle(1, this.lineColor);
			graphics.moveTo(0, 0);
			graphics.lineTo((this.d + this.a * 1.2) * Math.cos(phi), (this.d + this.a * 1.2) * Math.sin(phi));
		}
	}
	// Constructor...
	public function Limacon(_d:Number, _a:Number, _phi:Number):void {
		this.d = _d;
		this.a = _a;
		while ( _phi < 0 ) { _phi += Math.PI * 2; }
		while ( _phi >= Math.PI * 2 ) { _phi -= Math.PI * 2; }
		this.phi = _phi;
		this.thickness = 2;
		this.showCircle = false;
		this.showLine = false;
		this.color = 0x000000;
		this.circleColor = 0xffffff;
		this.lineColor = 0xffffff;
	}
}