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

葉序開度 - Divergence of Phyllotaxy -

葉序開度 - Divergence of Phyllotaxy -
----------
参考:「黄金比」 創元社(アルケミスト双書) スコット・オルセン著・藤田優里子訳 P12 「葉序のパターン」
    http://www.amazon.co.jp/gp/product/4422214756?ie=UTF8&tag=laxcomplex-22&linkCode=as2&camp=247&creative=1211&creativeASIN=4422214756
参考:「フィボナッチ数列と葉序」 http://www.dainippon-tosho.co.jp/mathlab/flash/no_002/math2.html
参考:「フィボナッチ数と植物」 http://mshi.no.coocan.jp/pukiwiki/?%B8%A6%B5%E6%BC%BC%2F%A5%D5%A5%A3%A5%DC%A5%CA%A5%C3%A5%C1%BF%F4%A4%C8%BF%A2%CA%AA
----------
解説:http://aquioux.blog48.fc2.com/blog-entry-692.html
----------
@author Aquioux(Yoshida, Akio)
/**
 * Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/9NAw
 */

package {
	import com.bit101.components.HSlider;
	import com.bit101.components.RadioButton;
	import com.bit101.components.Label;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	import frocessing.color.ColorHSV;
	[SWF(width = "465", height = "465", frameGOLDEN_RATIO = "30", backgroundColor = "#000000")]
	
	/**
	 * 葉序開度 - Divergence of Phyllotaxy -
	 * ----------
	 * 参考:「黄金比」 創元社(アルケミスト双書) スコット・オルセン著・藤田優里子訳 P12 「葉序のパターン」
	 *     http://www.amazon.co.jp/gp/product/4422214756?ie=UTF8&tag=laxcomplex-22&linkCode=as2&camp=247&creative=1211&creativeASIN=4422214756
	 * 参考:「フィボナッチ数列と葉序」 http://www.dainippon-tosho.co.jp/mathlab/flash/no_002/math2.html
	 * 参考:「フィボナッチ数と植物」 http://mshi.no.coocan.jp/pukiwiki/?%B8%A6%B5%E6%BC%BC%2F%A5%D5%A5%A3%A5%DC%A5%CA%A5%C3%A5%C1%BF%F4%A4%C8%BF%A2%CA%AA
	 * ----------
	 * 解説:http://aquioux.blog48.fc2.com/blog-entry-692.html
	 * ----------
	 * @author Aquioux(Yoshida, Akio)
	 */
	public class Main extends Sprite {
		
		private const GOLDEN_RATIO:Number = (Math.sqrt(5) - 1) / 2;	// 黄金比(内率)
		private const NUM_OF_DOT:uint = 360;				// 生成する Dot の数
		private const RADIAN90:Number = Math.PI / 2;		// 90度のときのラジアン値
		private const CX:Number = stage.stageWidth / 2;
		private const CY:Number = stage.stageHeight / 2;

		private var dots:Array = [];	// Dot 格納配列
		
		private var label:Label;
		private var slider:HSlider;
		private var selectedRadioButton:RadioButton;
		
		private var isAuto:Boolean = false;
		private var autoValue:Number;
		private var timer:Timer;
		
		public function Main():void {
			// Dot の生成
			var hsv:ColorHSV = new ColorHSV();
			var dist:Number = 0.0;
			var n:uint = NUM_OF_DOT;
			var cx:Number = CX;
			var cy:Number = CY;
			var goldenRatio:Number = GOLDEN_RATIO;
			for (var i:int = 0; i < n; i++) {
				hsv.h = i;
				var dot:Dot = new Dot(Math.sqrt(dist) * goldenRatio, hsv.toRGB().value);
				dot.x = cx;
				dot.y = cy;
				addChild(dot);
				dots.push(dot);
				dist += goldenRatio;
			}
			
			// スライダー
			slider = new HSlider(this, 0, 0, sliderHandler);
			slider.width = stage.stageWidth;
			var max:Number = 360.0;
			var min:Number = 0.0;
			slider.setSliderParams(min, max, min);
			// ラベル
			label = new Label(this, 5, slider.height + 5);
			// ラジオボタン
			var labels:Array = [	// ラジオボタンラベル
				"degree : 180 (1/2 Phyllotaxis)",
				"degree : 120 (1/3 = 2/3 Phyllotaxis)",
				"degree : 144 (2/5 = 3/5 Phyllotaxis)",
				"degree : 135 (3/8 = 5/8 Phyllotaxis)",
				"degree : 138.5 (5/13 = 8/13 Phyllotaxis)",
				"degree : 137.3 (Fibonacci - 0.2)",
				"degree : 137.5 (Fibonacci)",
				"degree : 137.6 (Fibonacci + 0.1)",
				"degree : 222.5 (360 - Fibonacci)",
				"degree : 85 (360 - Fibonacci * 2)",
				"degree : 99.5 (Lucas)",
				"degree : 260.5 (360 - Lucas)",
				"degree : 161 (360 - Lucas * 2)",
				"degree : 61.5 (360 - Lucas * 3)",
				"degree : 237 (Fibonacci + Lucas)",
				"degree : 38 (Fibonacci - Lucas)",
				"autoStart(++0.1)"
			];
			n = labels.length;
			var handler:Function = radioHandler;
			for (i = 0; i < n; i++) {
				if (i == n - 1) handler = autoHandler;
				var radio:RadioButton = new RadioButton(this, 8, label.y + label.height + 5 + 17 * i, labels[i], false, handler);
			}
			
			// 初期配置
			dotPlace(min);
		}
		
		// ラジオボタンハンドラ
		private function radioHandler(e:MouseEvent):void {
			// 選ばれたラジオボタンの保持
			selectedRadioButton = e.currentTarget as RadioButton;
			// オートモードだったら停止
			if (isAuto) autoStop();
			// ラジオボタンで設定した角度の取得
			var str:String = selectedRadioButton.label;
			var degree:Number = Number(str.split(" ")[2]);
			// スライダーの設定
			slider.value = degree;
			// 配置実行
			dotPlace(degree);
		}
		
		// ラジオボタンハンドラ(自動)
		private function autoHandler(e:MouseEvent):void {
			// timer が未生成ならば生成する
			if (!timer) {
				timer = new Timer(50);
				timer.addEventListener(TimerEvent.TIMER, autoStart);
			}
			// 選ばれたラジオボタンの保持
			selectedRadioButton = e.currentTarget as RadioButton;
			// オートモードフラグ
			isAuto = true;
			// 角度の取得
			autoValue = slider.value;
			// オート開始
			autoStart(null);
			timer.start();
		}
		// オート開始
		private function autoStart(e:TimerEvent):void {
			// 角度更新
			autoValue += 0.1;
			autoValue %= 360;
			// スライダーの設定
			slider.value = autoValue;
			// 配置実行
			dotPlace(autoValue);
		}
		// オート停止
		private function autoStop():void {
			isAuto = false;
			timer.stop();
			timer.reset();
		}
		
		// スライダーハンドラ
		private function sliderHandler(e:Event):void {
			// ラジオボタンのリセット
			if (selectedRadioButton) selectedRadioButton.selected = false;
			// オートモードだったら停止
			if (isAuto) autoStop();
			// 配置実行
			dotPlace(e.target.value);
		}
		
		// Dot の配置
		private function dotPlace(degree:Number):void {
			// ラベルテキストの設定
			label.text = "degree : " + String(degree);

			// 配置の設定
			var radian:Number = degree * Math.PI / 180;
			var dist:Number = 0.0;
			var n:uint = NUM_OF_DOT;
			var cx:Number = CX;
			var cy:Number = CY;
			var radian90:Number = RADIAN90;
			var goldenRatio:Number = GOLDEN_RATIO;
			for (var i:int = 0; i < n; i++) {
				var dot:Dot = dots[i];
				var angle:Number = radian * i - radian90;
				dot.x = Math.cos(angle) * dist + cx;
				dot.y = Math.sin(angle) * dist + cy;
				dist += goldenRatio;
			}
		}
	}
}


	// Dot Class
	import flash.display.Graphics;
	import flash.display.Shape;
	class Dot extends Shape {
		public function Dot(radius:Number = 5, color:uint = 0x000000) {
			var g:Graphics = graphics;
			g.beginFill(color);
			g.drawCircle(0, 0, radius);
			g.endFill();
		}
	}