Catmull-Rom スプライン曲線
/**
* Copyright sanesashi ( http://wonderfl.net/user/sanesashi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4IBM
*/
// Catmull-Rom スプライン曲線
// code from http://l00oo.oo00l.com/blog/archives/264
package {
import flash.display.AVM1Movie;
import __AS3__.vec.Vector;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
[SWF(width="400", height="400", backgroundColor="#ffffff")]
public class spline extends Sprite
{
private var points:Array;
public function spline()
{
if(stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event=null):void
{
points = new Array();
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
setup();
}
private function setup():void
{
stage.addEventListener(MouseEvent.CLICK, onStageClick);
}
private function plot(x:Number, y:Number):void
{
var point:Sprite = new Sprite();
point.x = x;//Math.round(Math.random() * stage.stageWidth);
point.y = y;//Math.round(Math.random() * stage.stageHeight);
point.graphics.beginFill(0xff3366);
point.graphics.drawCircle(0, 0, 3);
point.graphics.endFill();
point.buttonMode = true;
point.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener);
addChild(point);
points.push(point);
setPoints();
}
private function setPoints():void
{
var v:Vector.<Point> = new Vector.<Point>();
for(var i:uint; i<points.length; i++)
{
var point:Sprite = Sprite(points[i]);
v[i] = new Point(point.x, point.y);
}
graphics.clear();
drawSpline(v);
}
private function drawSpline(v:Vector.<Point>):void
{
if(v.length<2) return;
v.splice(0,0,v[0]);
v.push(v[v.length-1]);
var numSegments:uint = 20;//曲線分割数(補完する数)
for(var i:uint=0; i<v.length-3; i++)
{
var p0:Point = v[i];
var p1:Point = v[i+1];
var p2:Point = v[i+2];
var p3:Point = v[i+3];
splineTo(p0, p1, p2, p3, numSegments);
}
}
private function splineTo(p0:Point, p1:Point, p2:Point,
p3:Point, numSegments:uint):void
{
graphics.lineStyle(1, 0x666666);
graphics.moveTo(p1.x, p1.y);
for(var i:uint=0; i<numSegments; i++)
{
var t:Number = (i+1)/numSegments;
graphics.lineTo(
catmullRom(p0.x, p1.x, p2.x, p3.x, t),
catmullRom(p0.y, p1.y, p2.y, p3.y, t)
);
}
}
public function catmullRom(p0:Number, p1:Number, p2:Number,
p3:Number, t:Number):Number
{
var v0:Number = (p2 - p0) * 0.5;
var v1:Number = (p3 - p1) * 0.5;
return (2*p1 - 2*p2 + v0 + v1)*t*t*t +
(-3*p1 + 3*p2 - 2*v0 - v1)*t*t + v0*t + p1;
}
private function onStageClick(e:MouseEvent):void
{
plot(mouseX, mouseY);
}
private function mouseDownListener(e:MouseEvent):void
{
var point:Sprite = Sprite(e.target);
point.startDrag();
point.addEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
addEventListener(Event.ENTER_FRAME, enterFrameListener);
}
private function mouseUpListener(e:MouseEvent):void
{
var point:Sprite = Sprite(e.target);
point.stopDrag();
point.removeEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
removeEventListener(Event.ENTER_FRAME, enterFrameListener);
}
private function enterFrameListener(e:Event):void
{
setPoints();
}
}
}