Rose

http://www.7to3.net/lab/Fugusashi/

正多角形の各辺を同じ比率で内分する点をつなぎ合わせると、少し小さな正多角形が現れます。
それを入れ子にしてみました。

画面をクリックすると、四角形から五角形、六角形と、頂点が増えていきます。

上のスクリーンショットの内分比は黄金比に近い値。
ちょうど薔薇のように見えるのが不思議です。

Fugusashi.as

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;

	public class Fugusashi extends Sprite {
		private var _boxes:Array;
		private var _time:Number;

		public function Fugusashi(points:uint = 4, num:uint = 20, size:Number = 150, foreColor:uint = 0xFFFFFF, backColor:uint = 0x640000) {
			var rf:uint = foreColor >>> 16;
			var gf:uint = foreColor >>> 8 & 0xFF;
			var bf:uint = foreColor & 0xFF;
			var rb:uint = backColor >>> 16;
			var gb:uint = backColor >>> 8 & 0xFF;
			var bb:uint = backColor & 0xFF;

			_boxes = new Array();
			for (var i:uint = 0; i < num; i++) {
				var color:uint = uint(rf + (rb - rf) * (i) / num) << 16
							   | uint(gf + (gb - gf) * (i) / num) << 8
							   | uint(bf + (bb - bf) * (i) / num);
				var box:Box = new Box(points, size, 0, color, 1);
				if (i > 0) {
					_boxes[i - 1].addChild(box);
				} else {
					addChild(box);
				}
				_boxes.push(box);
			}

			_time = 0;
			addEventListener(Event.ENTER_FRAME, _enterFrameHandler);
		}

		private function _render(ratio:Number):void {
			var num:uint = _boxes.length;
			for (var i:uint = 1; i < num; i++) {
				var box:Box = _boxes[i];
				box.setRatio(ratio);
			}
		}

		private function _enterFrameHandler(evt:Event):void {
			_render((Math.cos(_time) + 1) / 2);
			_time += 0.05;
		}
	}	
}

Box.as

package {
	import flash.display.Sprite;

	public class Box extends Sprite {
		private var _r:Number;
		private var _points:uint;
		private var _angle:Number;
		private var _inner:Number;

		public function Box(points:uint = 4, r:Number = 100, ratio:Number = 0, fillColor:uint = 0x000000, fillAlpha:Number = 1, lineColor:uint = 0x000000, lineAlpha:Number = 0) {
			if (points > 2) {
				_r = r;
				_points = points;
				_angle = Math.PI * 2 / _points;
				_inner = Math.PI - _angle;

				graphics.clear();
				graphics.lineStyle(0.1, lineColor, lineAlpha);
				graphics.beginFill(fillColor, fillAlpha);
				var theta:Number = Math.PI / 2;
				graphics.moveTo(r * Math.cos(theta), r * Math.sin(theta));
				for (var i:uint = 0; i < _points; i++) {
					theta += _angle;
					graphics.lineTo(r * Math.cos(theta), r * Math.sin(theta));
				}
				setRatio(ratio);
			}
		}

		public function setRatio(ratio:Number):void {
			//余弦定理から親Boxの大きさとの比を求める
			scaleX = scaleY = Math.sqrt(2 * ratio * ratio - 2 * ratio + 1 - 2 * ratio * (1 - ratio) * Math.cos(_inner));
			//正弦定理から回転角を求める
			rotation = Math.asin(ratio * Math.sin(Math.PI * 2 / _points) / scaleX) * 180 / Math.PI;
		}
	}
}

Comments

*
*

Help