ランダムな多角形を作成し、頂点P(n)とP(n-1)の中点C(n)を始点、頂点P(n)をコントロールポイント、中点C(n+1)を終点としてgraphics.curveToメソッドで曲線を描画します。これを繰り返すとなんとなく有機的な形を作成できます。
ランダムな多角形は、原点を中心にランダムな距離と角度で頂点をプロットしていくと、辺の交差とかを考えなくていいので簡単です。点の間隔を狭めていくと円がベースになっていることがバレバレなので本当にランダムな多角形とは言えないですが。
package
{
import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.Event;
import flash.geom.Point;
import flash.text.TextField;
public class ClosedCurve extends Sprite
{
private var angle:Number = 0;
private var points:Array = [];
private var controls:Array = [];
private var RADIUS:Number = 0;
private var RADIUS_RANGE:Number = 0;
private var ARC:Number = 0;
private var ARC_RANGE:Number = 0;
private var DRAW_POINT:Boolean = true;
static const O:Point = new Point(0, 0);
public function ClosedCurve(_radius :Number = 100,
_r_range :Number = 50,
_arc :Number = 30,
_a_range :Number = 30,
_draw_point:Boolean=true)
{
RADIUS = _radius ;
RADIUS_RANGE = _r_range ;
ARC = _arc ;
ARC_RANGE = _a_range ;
DRAW_POINT = _draw_point;
initialize();
}
private function initialize():void
{
addEventListener(Event.ADDED, function(e:Event)
{
removeEventListener(Event.ADDED, arguments.callee);
createPoint();
});
}
private function createPoint():void
{
var d:Number = RADIUS + Math.random()*RADIUS_RANGE;
angle += ARC + Math.random()*ARC_RANGE;
if(angle<360)
{
var r:Number = angle*Math.PI/180;
var p:Point = Point.polar(d, r);
points.push(p);
createPoint();
} else {
createControlPoint();
draw(graphics);
drawOrigin(graphics);
}
}
private function createControlPoint():void
{
for(var i:uint=0; i<points.length; i++)
{
var p:Point, q:Point;
p = points[i];
if(i==0) q = points[points.length-1];
else q = points[i-1];
var xpos:Number = q.x+(p.x-q.x)/2;
var ypos:Number = q.y+(p.y-q.y)/2;
controls.push(new Point(xpos, ypos));
}
}
private function draw(g:Graphics):void
{
var i:uint = 0;
var len:uint = points.length;
var p:Point, q:Point, c:Point, d:Point;
g.lineStyle(0, 0x00ff00);
g.beginFill(0x333333, 0);
for(i=0; i<len; i++)
{
p = points[i];
c = controls[i];
if(i==len-1) d = controls[0];
else d = controls[i+1];
if(i==0) g.moveTo(c.x, c.y);
g.curveTo(p.x, p.y, d.x, d.y);
}
g.endFill();
if(DRAW_POINT)
{
for(i=0; i<len; i++)
{
p = points[i];
drawPoint("P"+i, p, g, 0x999999);
c = controls[i];
drawPoint("C"+i, c, g, 0xff0000);
if(i==0) q = points[points.length-1];
else q = points[i-1];
g.lineStyle(0, 0x999999, .5);
g.moveTo(q.x, q.y);
g.lineTo(p.x, p.y);
}
}
}
private function drawOrigin(g:Graphics):void
{
var size:uint = 3;
g.lineStyle(0, 0x000000, 1, true);
g.moveTo(-size, 0);
g.lineTo( size, 0);
g.moveTo(0, -size);
g.lineTo(0, size);
}
private function drawPoint(msg :String ,
p :Point ,
g :Graphics,
color:uint =0x000000):void
{
g.lineStyle(0, color);
g.drawCircle(p.x, p.y, 4);
numbering(msg, p.x, p.y, color);
}
private function numbering(msg: String,
xpos :Number,
ypos :Number,
color:uint =0x000000):void
{
var tfld:TextField = new TextField();
tfld.mouseEnabled = false;
tfld.selectable = false;
tfld.text = msg;
tfld.textColor = color;
addChild(tfld);
tfld.x = xpos;
tfld.y = ypos;
}
}
}