ベジェ曲線を均等に分割する。
NM_Irregularcircleにベジェ曲線を均等分割したPointを配列にして返すアクションを追加する。
BezierSegmentを操作して、ベジェ曲線の長さと分割点をループで強引に取得している。 精度を求めるとループ回数がとても多くなってしまうので引数で調整できるようにした。
SAMPLE VIEW CODE
package {
import flash.events.*;
import flash.display.*;
public class NMain extends MovieClip {
//-------------------------------------------------------------------------------- Properties
private var _this:*;
private var _stage:Stage;
private var _main:MovieClip;
//-------------------------------------------------------------------------------- Constractor
public function NMain() {
_this = this;
_this.addEventListener(Event.ADDED_TO_STAGE, Init);
}
//-------------------------------------------------------------------------------- Function
/**
* Init
*/
public function Init(eo:* = null):void {
_this.removeEventListener(Event.ADDED_TO_STAGE, Init);
_stage = stage;
_stage.scaleMode = StageScaleMode.NO_SCALE;
_stage.align = StageAlign.TOP_LEFT;
_main = new MovieClip();
_this.addChild(_main);
_stage.addEventListener(Event.RESIZE, stageresizeaction);
stageresizeaction();
initirregularcircle();
}
/**
* initialize irregularcircle
*/
private function initirregularcircle():void {
var args = {};
args.anchorlength = 6;
args.radius = 100;
args.irregular = .5;
args.linesize = 1;
args.linealpha = .1;
args.fillalpha = 0;
args.linecolor = 0x000000;
args.fillcolor = args.linecolor;
args.roundval = 80;
args.irregular_ap = 100;
args.irregular_cp = 60;
var irrcircle = new NM_Irregularcircle();
irrcircle.Init(args);
irrcircle.x = Math.round(_stage.stageWidth / 2);
irrcircle.y = Math.round(_stage.stageHeight / 2);
//_stage.addChild(irrcircle);
var points:Array = irrcircle.getSplitPoints(200, 20000, .01);
var _dot:MovieClip;
var nmg = new NM_Gradation();
var cols = nmg.Colors(0x00A0E9, 0xE4007F, points.length);
for(var i:uint = 0; i < points.length; i ++) {
_dot = dot(cols[i]);
_dot.x = points[i].x;
_dot.y = points[i].y;
_main.addChild(_dot);
}
}
/**
* dot
*/
private function dot(col:Number):MovieClip {
var size = 20;
var dot_mc = new MovieClip();
dot_mc.graphics.lineStyle(1, col, 1);
dot_mc.graphics.drawCircle(-size / 2, -size / 2, size);
//dot_mc.graphics.endFill();
return dot_mc;
}
/**
* stage resize
*/
private function stageresizeaction():void {
_main.x = Math.round(_stage.stageWidth / 2);
_main.y = Math.round(_stage.stageHeight / 2);
}
}
}
package {
import flash.display.*;
import flash.geom.*;
import flash.events.*;
import fl.motion.BezierSegment;
class NM_Irregularcircle extends MovieClip {
//-------------------------------------------------------------------------------- Properties
private var _this:MovieClip;
private var anchorlength:int;
private var radius:Number;
private var irregular:Number;
private var linecolor:Number;
private var fillcolor:Number;
private var linealpha:Number;
private var fillalpha:Number;
private var linesize:Number;
private var roundval:Number;
private var irregular_ap:Number;
private var irregular_cp:Number;
//-------------------------------------------------------------------------------- Constractor
public function NM_Irregularcircle() {
_this = this;
}
//-------------------------------------------------------------------------------- Function
/**
* Init
*/
public function Init(args:Object):void {
anchorlength = args.anchorlength;
irregular = args.irregular;
linesize = args.linesize;
linecolor = args.linecolor;
linealpha = args.linealpha;
fillcolor = args.fillcolor;
fillalpha = args.fillalpha;
radius = args.radius;
roundval = args.roundval;
irregular_ap = args.irregular_ap;
irregular_cp = args.irregular_cp;
setpoints();
drawirrcircle();
}
/**
* points
*/
private function setpoints() {
var angle = 360 / anchorlength;
for (var i:Number = 0; i < anchorlength; i++) {
var radian = (i * angle + 90) / 180 * Math.PI
var irr_ap = irregular_ap * Math.random();
var irr_cp = irregular_cp - irregular_cp * 2 * Math.random();
var tgtradius = radius + irr_ap;
var p_a = dot_a();
var p_l = dot_b();
var p_r = dot_c();
p_a.name = (i + 1) + "_a";
var a_mat = p_a.transform.matrix;
a_mat.translate(tgtradius, 0);
a_mat.rotate(radian);
p_a.transform.matrix = a_mat;
p_l.name = (i + 1) + "_l";
var l_mat:Matrix = new Matrix();
l_mat.translate(0, roundval);
l_mat.rotate(irr_cp / 180 * Math.PI);
l_mat.translate(tgtradius, 0);
l_mat.rotate(radian);
p_l.transform.matrix = l_mat;
p_r.name = (i + 1) + "_r";
var r_mat:Matrix = new Matrix();
r_mat.translate(0, -roundval);
r_mat.rotate(irr_cp / 180 * Math.PI);
r_mat.translate(tgtradius, 0);
r_mat.rotate(radian);
p_r.transform.matrix = r_mat;
_this.addChild(p_a);
_this.addChild(p_l);
_this.addChild(p_r);
}
}
/**
* draw
*/
private var beziersegarr:Array;
private function drawirrcircle() {
beziersegarr = [];
_this.graphics.clear();
_this.graphics.beginFill(fillcolor, fillalpha);
_this.graphics.lineStyle(linesize, linecolor, linealpha);
var startap = _this.getChildByName("1_a");
_this.graphics.moveTo(startap.x, startap.y);
var separate = 4;
var sep = 1 / separate;
for (var i:int = 0; i < anchorlength; i++) {
var pid = i + 1;
var nextpid = i + 2;
if(nextpid > anchorlength) nextpid = 1;
var obj_ap_1 = _this.getChildByName(pid + "_a");
var ap_1 = new Point(obj_ap_1.x, obj_ap_1.y);
var obj_cp_1 = _this.getChildByName(pid + "_l");
var cp_1 = new Point(obj_cp_1.x, obj_cp_1.y);
var obj_cp_2 = _this.getChildByName(nextpid + "_r");
var cp_2 = new Point(obj_cp_2.x, obj_cp_2.y);
var obj_ap_2 = _this.getChildByName(nextpid + "_a");
var ap_2 = new Point(obj_ap_2.x, obj_ap_2.y);
var bzseg = new BezierSegment(ap_1, cp_1, cp_2, ap_2);
beziersegarr.push(bzseg);
for(var t = (sep * 2); t <= 1; t += (sep * 2)) {
var a1 = bzseg.getValue(t - sep * 2);
var a2 = bzseg.getValue(t - sep);
var a3 = bzseg.getValue(t);
var cp = new Point(2 * a2.x - (a1.x + a3.x) * .5, 2 * a2.y - (a1.y + a3.y) * .5);
_this.graphics.curveTo(cp.x, cp.y, a3.x, a3.y);
}
}
_this.graphics.endFill();
}
/**
* draw splitpoint
*/
public function getSplitPoints(splitnum:int, accuracy:int = 10000, margin:Number = .1):Array {
var splitpointsarr = [];
var circlelength = getCircleLength(accuracy);
var splittick:Number = circlelength / splitnum;
var startpoint:Point = new Point(beziersegarr[0].getValue(0).x, beziersegarr[0].getValue(0).y);
//trace("splittick:" + splittick);
var _dot = new Point();
_dot.x = startpoint.x;
_dot.y = startpoint.y;
splitpointsarr.push(_dot);
//trace(_dot.x + " " + _dot.y);
var last_p:Point = startpoint;
var now_p:Point;
var now_leng:Number;
var bzseg:BezierSegment;
var checkleng:Number
for(var i:uint = 0; i < anchorlength; i ++) {
bzseg = beziersegarr[i];
for(var t:uint = 0; t < accuracy; t ++) {
now_p = bzseg.getValue(t / accuracy);
now_leng = Point.distance(last_p, now_p);
checkleng = now_leng - splittick;
if(checkleng < 0) checkleng *= -1;
if(checkleng < margin) {
//trace("now_leng:" + now_leng);
_dot = new Point();
_dot.x = now_p.x;
_dot.y = now_p.y;
splitpointsarr.push(_dot);
last_p = now_p;
}
}
}
//trace(_dot.x + " " + _dot.y);
//if(Point.distance(startpoint, last_p) < splittick * .5) splitpointsarr.pop();
if(pointdistance(startpoint, last_p) < splittick * .5) splitpointsarr.pop();
return splitpointsarr;
}
/**
* get bezirlength
*/
public function getCircleLength(accuracy:int):Number {
var circlelength = 0;
for(var i:uint = 0; i < beziersegarr.length; i ++ ) {
circlelength += getbezirlength(beziersegarr[i], accuracy);
}
return circlelength;
}
//
private function getbezirlength(bzseg:BezierSegment, accuracy:int):Number {
var last_p:Point = new Point(bzseg.getValue(0).x, bzseg.getValue(0).y);
var now_p:Point;
var bezlen = 0;
var bszpoint:Point;
for(var i:uint = 0; i <= accuracy ; i ++) {
bszpoint = bzseg.getValue(i / accuracy);
now_p = new Point(bszpoint.x, bszpoint.y);
//bezlen += Point.distance(last_p, now_p);
bezlen += pointdistance(last_p, now_p);
last_p = now_p;
}
return bezlen;
}
//
private function pointdistance(p1:Point, p2:Point):Number {
var dx:Number = p1.x - p2.x;
var dy:Number = p1.y - p2.y;
return Math.sqrt(dx * dx + dy * dy);
}
/**
* dot
*/
//
private function dot_a():MovieClip {
var size = 16;
var dot_mc = new MovieClip();
dot_mc.graphics.beginFill(0x000000);
dot_mc.graphics.drawRect(-size / 2, -size / 2, size, size);
dot_mc.graphics.endFill();
dot_mc.addEventListener(MouseEvent.CLICK, function(){trace(dot_mc.name +" x:" + dot_mc.x +", y:"+ dot_mc.y);});
return dot_mc;
}
//
private function dot_b():MovieClip {
var size = 10;
var dot_mc = new MovieClip();
dot_mc.graphics.beginFill(0xFF00FF);
dot_mc.graphics.drawRect(-size / 2, -size / 2, size, size);
dot_mc.graphics.endFill();
dot_mc.addEventListener(MouseEvent.CLICK, function(){trace(dot_mc.name +" x:" + dot_mc.x +", y:"+ dot_mc.y);});
return dot_mc;
}
//
private function dot_c():MovieClip {
var size = 10;
var dot_mc = new MovieClip();
dot_mc.graphics.beginFill(0x00FFFF);
dot_mc.graphics.drawRect(-size / 2, -size / 2, size, size);
dot_mc.graphics.endFill();
dot_mc.addEventListener(MouseEvent.CLICK, function(){trace(dot_mc.name +" x:" + dot_mc.x +", y:"+ dot_mc.y);});
return dot_mc;
}
}
}