ペジェ曲線
3次までのペジェ曲線を描くサンプル
クリックした場所を制御点に加えていきます。
/**
* Copyright Horiuchi_H ( http://wonderfl.net/user/Horiuchi_H )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4ooa
*/
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(width = 465, height = 465, frameRate = 60, backgroundColor = "#000000")]
/**
* 3次までのペジェ曲線を描くサンプル
* クリックした場所を制御点に加えていきます。
*/
public class BezierCurve extends Sprite
{
private static const CURVE_POINT:int = 4;
private static const DRAW_COUNT:Number = 100;
private var clickPoints:Array = [];
private var frame:Number = -1;
private var g:Graphics;
public function BezierCurve() {
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
g = this.graphics;
this.stage.addEventListener(MouseEvent.CLICK, stageClickEventHandler);
this.stage.addEventListener(Event.ENTER_FRAME, drawCurve);
}
private function stageClickEventHandler(event:MouseEvent):void {
var point:/*Number*/Array = [event.stageX, event.stageY];
frame = 0;
if (clickPoints.length >= CURVE_POINT) {
clearStage();
clickPoints = [];
frame = -1;
}
clickPoints.push(point);
g.lineStyle(1, 0xffffff);
g.drawCircle(point[0], point[1], 5.0);
if (true) {
// for debug
g.lineStyle(1, 0x66666666);
g.moveTo(clickPoints[0][0], clickPoints[0][1]);
for (var i:int = 1; i < clickPoints.length; i++) {
g.lineTo(clickPoints[i][0], clickPoints[i][1]);
}
}
if (clickPoints.length > 1) {
var from:/*Number*/Array = calcBezierCurvePoint(clickPoints, 0);
g.lineStyle(2, 0x33cc66);
g.moveTo(from[0], from[1]);
for (var index:int = 1; index <= DRAW_COUNT; index++) {
var to:/*Number*/Array = calcBezierCurvePoint(clickPoints, index / DRAW_COUNT);
g.lineTo(to[0], to[1]);
trace(to[0] + "," + to[1]);
}
}
}
private function clearStage():void {
g.clear();
}
private function drawCurve(event:Event = null):void {
if (frame < 0) return;
if (frame >= DRAW_COUNT) return;
var start:/*Number*/Array = calcBezierCurvePoint(clickPoints, frame / DRAW_COUNT);
var end:/*Number*/Array = calcBezierCurvePoint(clickPoints, (frame + 1)/ DRAW_COUNT);
g.lineStyle(1, 0xffffff);
g.moveTo(start[0], start[1]);
g.lineTo(end[0], end[1]);
frame++;
}
private function calcBezierCurvePoint(points:Array, t:Number):/*Number*/Array {
var ps:Array = points;
while (ps.length > 1) {
var next:Array = [];
for (var index:int = 0; index < ps.length - 1; index++) {
next[index] = calcCutoffPoint(ps[index], ps[index + 1], t);
}
ps = next;
}
return ps[0];
}
private function calcCutoffPoint(startPoint:/*Number*/Array, endPoint:/*Number*/Array, t:Number):/*Number*/Array {
return [
startPoint[0] + (endPoint[0] - startPoint[0]) * t,
startPoint[1] + (endPoint[1] - startPoint[1]) * t,
];
}
}
}