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

CatmullRom曲線

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