ペジェ曲線 for flash10
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/emFj
*/
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
[SWF(width = 465, height = 465, frameRate = 120, 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:Vector.<Point> = new Vector.<Point>();
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:Point = new Point(event.stageX, event.stageY);
frame = 0;
if (clickPoints.length >= CURVE_POINT) {
clearStage();
clickPoints.splice(0, clickPoints.length);
frame = -1;
}
clickPoints.push(point);
g.lineStyle(1, 0xffffff);
g.drawCircle(point.x, point.y, 5.0);
if (true) {
// for debug
g.lineStyle(1, 0x66666666);
g.moveTo(clickPoints[0].x, clickPoints[0].y);
for (var i:int = 1; i < clickPoints.length; i++) {
g.lineTo(clickPoints[i].x, clickPoints[i].y);
}
}
if (clickPoints.length > 1) {
var from:Point = calcBezierCurvePoint(clickPoints, 0);
g.lineStyle(2, 0x33cc66);
g.moveTo(from.x, from.y);
for (var index:int = 1; index <= DRAW_COUNT; index++) {
var to:Point = calcBezierCurvePoint(clickPoints, index / DRAW_COUNT);
g.lineTo(to.x, to.y);
//trace(to.x + "," + to.y);
}
}
}
private function clearStage():void {
g.clear();
}
private function drawCurve(event:Event = null):void {
if (frame < 0) return;
if (frame >= DRAW_COUNT) return;
var start:Point = calcBezierCurvePoint(clickPoints, frame / DRAW_COUNT);
var end:Point = calcBezierCurvePoint(clickPoints, (frame + 1)/ DRAW_COUNT);
g.lineStyle(1, 0xffffff);
g.moveTo(start.x, start.y);
g.lineTo(end.x, end.y);
frame++;
}
private function calcBezierCurvePoint(points:Vector.<Point>, t:Number):Point {
if (points.length == 0)
return new Point();
var ps:Vector.<Point> = points;
while (ps.length > 1) {
var next:Vector.<Point> = new Vector.<Point>();
for (var index:int = 0; index < ps.length - 1; index++) {
next.push(calcCutoffPoint(ps[index], ps[index + 1], t));
}
ps = next;
}
return ps[0];
}
private function calcCutoffPoint(startPoint:Point, endPoint:Point, t:Number):Point {
return Point.interpolate(endPoint, startPoint, t);
}
}
}