Ribon forked from: forked from: CatmullRom曲線
CatmullRom曲線
マウスドラッグで点を移動
参考:
http://markun.cs.shinshu-u.ac.jp/learn/cg/cg3/index5.html
// forked from Kay's forked from: CatmullRom曲線
// forked from Nao_u's CatmullRom曲線
//
// 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="0x222222", 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+150, SCREEN_H-50) );
Pnt[1] = new ControlPoint( new Point(SCREEN_W/2-100, SCREEN_H/2-130) );
Pnt[2] = new ControlPoint( new Point(SCREEN_W/2-175, SCREEN_H/2-75) );
Pnt[3] = new ControlPoint( new Point(SCREEN_W/2, SCREEN_H/2+100 ) );
Pnt[4] = new ControlPoint( new Point(SCREEN_W/2+175, SCREEN_H/2-75) );
Pnt[5] = new ControlPoint( new Point(SCREEN_W/2+100, SCREEN_H/2-130) );
Pnt[6] = new ControlPoint( new Point(SCREEN_W/2-150, SCREEN_H-50) );
CatumllRomAry[0] = new CatmullRom( Pnt[0], Pnt[0], Pnt[1], Pnt[2] );
CatumllRomAry[0].addPoint( Pnt[3] );
CatumllRomAry[0].addPoint( Pnt[4] );
CatumllRomAry[0].addPoint( Pnt[5] );
CatumllRomAry[0].addPoint( Pnt[6] );
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 = 120;
public var PntNum:int;
private var Pp:Vector.<Number> = new Vector.<Number>();
private var Pc:Vector.<int> = new Vector.<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;
// drawPath用に Pc (Point Control) 設定
Pc[0] = 1;
for ( var i:int = 0; i < DivNum; i++) {
Pc.push(2);
}
}
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;
Pp = new Vector.<Number>();
for( var lp:int=tAdd; lp<DivNum; lp++,t+=tAdd ){
ep = getPosition( t );
Pp.push( ep.x, ep.y);
sp = ep;
}
Pp.push( Cp[7].Sp.x, Cp[7].Sp.y );
Main.graphics.lineStyle( 5.0, 0xff00ff );
Main.graphics.drawPath( Pc, Pp );
// 複数の線で描画してみる
var radian:Number = 0;
var subPp1:Vector.<Number> = new Vector.<Number>();
var subPp2:Vector.<Number> = new Vector.<Number>();
var subPp3:Vector.<Number> = new Vector.<Number>();
var subPp4:Vector.<Number> = new Vector.<Number>();
var PpLen:uint = Pp.length/2;
for (var i:uint = 0; i < PpLen; i++) {
if (i < PpLen-1) {
var dx:Number = Pp[(i+1)*2] -Pp[(i+0)*2];
var dy:Number = Pp[(i+1)*2+1]-Pp[(i+0)*2+1];
radian = Math.atan2(dy, dx) + Math.PI/2;
}
var baseP:Point = new Point(Pp[i*2],Pp[i*2+1]);
var subP:Point = Point.polar(20,radian);
subP.offset(baseP.x, baseP.y);
subPp1.push(subP.x, subP.y);
subP = Point.polar(10,radian);
subP.offset(baseP.x, baseP.y);
subPp2.push(subP.x, subP.y);
subP = Point.polar(-10,radian);
subP.offset(baseP.x, baseP.y);
subPp3.push(subP.x, subP.y);
subP = Point.polar(-20,radian);
subP.offset(baseP.x, baseP.y);
subPp4.push(subP.x, subP.y);
}
Main.graphics.drawPath( Pc, subPp1 );
Main.graphics.drawPath( Pc, subPp2 );
Main.graphics.drawPath( Pc, subPp3 );
Main.graphics.drawPath( Pc, subPp4 );
}
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,0xffffff);
Sp.graphics.beginFill(0xffffff,0.75);
Sp.graphics.drawCircle(0,0,10.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();
}