CatmullRom曲線
CatmullRom曲線
マウスドラッグで点を移動
参考:
http://markun.cs.shinshu-u.ac.jp/learn/cg/cg3/index5.html
//
// CatmullRom曲線
// マウスドラッグで点を移動
//
// 参考:
// http://markun.cs.shinshu-u.ac.jp/learn/cg/cg3/index5.html
//
package {
import flash.display.Sprite;
import flash.events.*;
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="60")]
public class FlashTest extends Sprite {
public function FlashTest() {
Main = this;
initialize();
stage.addEventListener(Event.ENTER_FRAME,update);
}
}
}
import flash.display.Sprite;
import flash.text.*;
import flash.events.*;
import flash.geom.*;
var SCREEN_W:Number = 465, SCREEN_H:Number = 465;
var Main:Sprite;
var Text:TextField
var Pnt:Vector.<ControlPoint> = new Vector.<ControlPoint>;
var CatumllRomAry:Vector.<CatmullRom> = new Vector.<CatmullRom>;
function initialize():void{
Text = new TextField();
Text.text = "CatmullRom曲線";
Text.autoSize = "left";
Main.addChild(Text);
Pnt[0] = new ControlPoint( new Point(SCREEN_W/2-200, SCREEN_H/2) );
Pnt[1] = new ControlPoint( new Point(SCREEN_W/2-100, SCREEN_H/2-100) );
Pnt[2] = new ControlPoint( new Point(SCREEN_W/2+100, SCREEN_H/2-150) );
Pnt[3] = new ControlPoint( new Point(SCREEN_W/2-50, SCREEN_H/2+50 ) );
Pnt[4] = new ControlPoint( new Point(SCREEN_W/2+100, SCREEN_H/2+100) );
Pnt[5] = new ControlPoint( new Point(SCREEN_W/2+0, SCREEN_H/2+180) );
Pnt[6] = new ControlPoint( new Point(SCREEN_W/2-80, SCREEN_H/2+200) );
CatumllRomAry[0] = new CatmullRom( Pnt[0], Pnt[1], Pnt[2], Pnt[3] );
CatumllRomAry[0].addPoint( Pnt[4] );
CatumllRomAry[0].addPoint( Pnt[5] );
CatumllRomAry[0].addPoint( Pnt[6] );
}
function update(e :Event):void{
graphicClear();
CatumllRomAry[0].drawGuideLine();
CatumllRomAry[0].draw();
}
class CatmullRom{
public var Cp:Vector.<ControlPoint> = new Vector.<ControlPoint>;
public var DivNum:int = 60;
public var PntNum:int;
public function CatmullRom( p0:ControlPoint, p1:ControlPoint, p2:ControlPoint, p3:ControlPoint ){
Cp[0] = p0; Cp[1] = p1; Cp[2] = p2; Cp[3] = p3;
PntNum = 1;
}
public function addPoint( p0:ControlPoint ):void{
Cp.push( p0 );
PntNum++;
}
public function draw():void{
var t:Number = 0;
var tAdd:Number = 1.0 / DivNum;
var sp:Point = getPosition( 0.0 ), ep:Point;
for( var lp:int=tAdd; lp<DivNum; lp++,t+=tAdd ){
ep = getPosition( t );
drawLine( sp.x, sp.y, ep.x, ep.y, 1.0, 0x0000ff );
sp = ep;
}
}
public function drawGuideLine():void{
var i:int = 0;
drawLine( Pnt[i].Sp.x, Pnt[i].Sp.y, Pnt[i+1].Sp.x, Pnt[i+1].Sp.y, 0.5, 0x80ff80 );
i = PntNum+1;
drawLine( Pnt[i].Sp.x, Pnt[i].Sp.y, Pnt[i+1].Sp.x, Pnt[i+1].Sp.y, 0.5, 0x80ff80 );
}
public function getPosition( t:Number ):Point{
var ret:Point = new Point();
var div:Number = (1 / PntNum);
var idx:int = t / div;
var tt:Number = (t - div*idx) / div;
ret.x = catmullRom( Cp[idx].Sp.x, Cp[idx+1].Sp.x, Cp[idx+2].Sp.x, Cp[idx+3].Sp.x, tt)
ret.y = catmullRom( Cp[idx].Sp.y, Cp[idx+1].Sp.y, Cp[idx+2].Sp.y, Cp[idx+3].Sp.y, tt)
return ret;
}
public function catmullRom( x0:Number, x1:Number, x2:Number, x3:Number, t:Number ):Number{
var v0:Number = (x2 - x0) / 2.0;
var v1:Number = (x3 - x1) / 2.0;
var t2:Number = t * t;
var t3:Number = t2 * t;
return ( 2.0 * x1 - 2.0 * x2 + v0 + v1 ) * t3 + ( -3.0 * x1 + 3.0 * x2 - 2.0 * v0 - v1 ) * t2 + v0 * t + x1;
}
}
class ControlPoint{
public var Sp:Sprite;
public var Pos:Point;
public function ControlPoint( p:Point ){
Sp=new Sprite();
Pos = p; Sp.x = Pos.x; Sp.y = Pos.y;
Sp.graphics.clear();
Sp.graphics.lineStyle(1.4,0x000000);
Sp.graphics.beginFill(0xe0d000,1);
Sp.graphics.drawCircle(0,0,8.0);
Sp.graphics.endFill();
Main.stage.addChild(Sp);
Sp.addEventListener(MouseEvent.MOUSE_UP, function(event:MouseEvent):void{ Sp.stopDrag(); });
Sp.addEventListener(MouseEvent.MOUSE_DOWN, function(event:MouseEvent):void{ Sp.startDrag(); });
}
}
function graphicClear():void{
Main.graphics.clear();
Main.graphics.lineStyle(1.2,0xb0b040);
Main.graphics.moveTo( SCREEN_W/2, 0 );
Main.graphics.lineTo( SCREEN_W/2, SCREEN_H );
Main.graphics.moveTo( 0, SCREEN_H/2 );
Main.graphics.lineTo( SCREEN_W, SCREEN_H/2 );
}
function drawLine( sx:Number, sy:Number, ex:Number, ey:Number, size:Number, col:int ):void{
Main.graphics.lineStyle(size,col);
Main.graphics.moveTo( sx, sy );
Main.graphics.lineTo( ex, ey );
}