Fugusashi
Posted: December 12th, 2007 | No Comments »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;
}
}
}

Leave a Reply