葉序開度 - 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();
}
}