In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Ribon forked from: forked from: CatmullRom曲線

CatmullRom曲線
マウスドラッグで点を移動    
 参考:
http://markun.cs.shinshu-u.ac.jp/learn/cg/cg3/index5.html
Get Adobe Flash player
by Kay 19 Jun 2009
// 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();
}