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

3次のベジェ曲線

ベジェ曲線
マウスドラッグで制御点を移動
カーソルキー左右でパラメータtを移動
カーソルキー上下で「分離」「連結」「2次」のタイプの切り替え
参考:Wikipedia:ベジェ曲線
http://ja.wikipedia.org/wiki/%E3%83%99%E3%82%B8%E3%82%A7%E6%9B%B2%E7%B7%9A
Get Adobe Flash player
by Nao_u 11 Oct 2009
// ベジェ曲線
//    マウスドラッグで制御点を移動
//    カーソルキー左右でパラメータtを移動
//    カーソルキー上下で「分離」「連結」「2次」のタイプの切り替え
//
// 参考:Wikipedia:ベジェ曲線
//        http://ja.wikipedia.org/wiki/%E3%83%99%E3%82%B8%E3%82%A7%E6%9B%B2%E7%B7%9A
//

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);     
            stage.addEventListener(KeyboardEvent.KEY_UP,   keyCheckUp);     
            stage.addEventListener(KeyboardEvent.KEY_DOWN, keyCheckDown);     
            stage.addEventListener(MouseEvent.MOUSE_UP,    MouseCheckUp);     
            stage.addEventListener(MouseEvent.MOUSE_DOWN,  MouseCheckDown);     
        }    
    }    
}            
   
import flash.display.Sprite;     
import flash.events.Event;    
import flash.events.KeyboardEvent;     
import flash.events.MouseEvent;     
import flash.ui.Keyboard;     
import flash.text.TextField;    
import flash.geom.*; 
var Main:Sprite;    
var SCREEN_W:Number = 465;   
var SCREEN_H:Number = 465;   
var Text:TextField   

var T:Number = 0.5;
var Mode:int = 0;
var Pnt:Vector.<ControlPoint> = new Vector.<ControlPoint>;
var Bezier2Ary:Vector.<Bezier2> = new Vector.<Bezier2>;
var Bezier3Ary:Vector.<Bezier3> = new Vector.<Bezier3>;

function initialize():void{    
    Text = new TextField();    
    Text.text = "----";  
    Text.autoSize = "left";  
    Main.addChild(Text);     
      
    graphicClear();  

    Pnt[0] = new ControlPoint( new Point(SCREEN_W/2-150, 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+0,   SCREEN_H/2-100) );
    Pnt[3] = new ControlPoint( new Point(SCREEN_W/2+100, SCREEN_H/2) );
    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+200) );
    Pnt[6] = new ControlPoint( new Point(SCREEN_W/2-100,  SCREEN_H/2+200) );

    Bezier2Ary[0] = new Bezier2( Pnt[0], Pnt[1], Pnt[2] );
    Bezier2Ary[1] = new Bezier2( Pnt[2], Pnt[3], Pnt[4] );
    Bezier2Ary[2] = new Bezier2( Pnt[4], Pnt[5], Pnt[6] );

    Bezier3Ary[0] = new Bezier3( Pnt[0], Pnt[1], Pnt[2], Pnt[3] );
    Bezier3Ary[1] = new Bezier3( Pnt[3], Pnt[4], Pnt[5], Pnt[6] );
}    

function update(e :Event):void{    
    graphicClear();  

    if( KeyData & KEY_LEFT  ) T -= 0.01;
    if( KeyData & KEY_RIGHT ) T += 0.01;
    if( T < 0.0 ) T = 0.0;
    if( T > 1.0 ) T = 1.0;

    if( KeyData & KEY_UP_TRG  ) Mode++;
    if( KeyData & KEY_DOWN_TRG  ) Mode--;
    if( Mode > 3 ) Mode = 0;
    if( Mode < 0 ) Mode = 3;

    var i:int;
    switch( Mode ){
    case 0:
        {
        Text.text = "3次のベジェ曲線 t=" + Math.round( T*100 ) / 100;  
        Bezier3Ary[0].drawGuideLine( T );
        Bezier3Ary[0].draw();
        Bezier3Ary[0].drawPoint( T );
        for( i=4; i<7; i++ ) Pnt[i].setEnable(false);
        break;
        }
    case 1:
        Text.text = "3次のベジェ曲線(分離) t=" + Math.round( T*100 ) / 100;  
        Bezier3Ary[0].drawGuideLine( T );
        Bezier3Ary[0].draw();
        Bezier3Ary[0].drawPoint( T );
        Bezier3Ary[1].drawGuideLine( T );
        Bezier3Ary[1].draw();
        Bezier3Ary[1].drawPoint( T );

        for( i=4; i<7; i++ ) Pnt[i].setEnable(true);
        break;

    case 2:
        Text.text = "3次のベジェ曲線(連結) t=" + Math.round( T*100 ) / 100;  
        Bezier3Ary[0].drawGuideLine( T );
        Bezier3Ary[0].draw();
        Bezier3Ary[0].drawPoint( T );
        Bezier3Ary[1].drawGuideLine( T );
        Bezier3Ary[1].draw();
        Bezier3Ary[1].drawPoint( T );

        Pnt[4].setEnable(false);
        Pnt[4].Sp.x = Pnt[3].Sp.x + Pnt[3].Sp.x - Pnt[2].Sp.x;
        Pnt[4].Sp.y = Pnt[3].Sp.y + Pnt[3].Sp.y - Pnt[2].Sp.y;
        break;

    case 3:
        Text.text = "2次のベジェ曲線 t=" + Math.round( T*100 ) / 100;  
        for each( var b2:Bezier2 in Bezier2Ary ){
            b2.drawGuideLine( T );
            b2.draw();
            b2.drawPoint( T );
        }
        for( i=4; i<7; i++ ) Pnt[i].setEnable(true);
        break;

    case 4:
        Mode = 0;
        break;
    }

    updateKey();

} 


class Bezier2{ 
    public var Cp:Vector.<ControlPoint> = new Vector.<ControlPoint>;
    public var DivNum:int = 60;
    public var p4:Point=new Point(), p5:Point=new Point(), p6:Point=new Point();
    public function Bezier2( p0:ControlPoint, p1:ControlPoint, p2:ControlPoint ){
        Cp[0] = p0; Cp[1] = p1; Cp[2] = p2;;
    }

    public function draw():void{
        var t:Number = 0;
        var tAdd:Number = 1.0 / DivNum;
        var pp:Point=new Point();
        pp.x = Cp[0].Sp.x, pp.y = Cp[0].Sp.y;
        for( var lp:int=0; lp<DivNum; lp++,t+=tAdd ){
            getPosition( t );
            drawLine( pp.x, pp.y, p6.x, p6.y, 1.0, 0x0000ff );
            pp.x = p6.x;
            pp.y = p6.y;
        }
    }

    public function drawGuideLine( t:Number ):void{
        for( var i:int=0; i<2; i++ ){
            drawLine( Cp[i].Sp.x, Cp[i].Sp.y, Cp[i+1].Sp.x, Cp[i+1].Sp.y, 1.0, 0x00ff00 );
        }

        getPosition( t );
        drawLine( p4.x, p4.y, p5.x, p5.y, 1.0, 0xf08000 );
        drawLine( p5.x, p5.y, p6.x, p6.y, 1.0, 0xf08000 );
        drawCircle( p4.x, p4.y, 0.5, 0x000000 );
        drawCircle( p5.x, p5.y, 0.5, 0x000000 );
    }

    public function drawPoint( t:Number ):void{
        getPosition( t );
        drawCircle( p6.x, p6.y, 2.5, 0xff0000 );
    }
    
    public function getPosition( t:Number ):void{
        p4.x = Cp[0].Sp.x + (Cp[1].Sp.x - Cp[0].Sp.x) * t;
        p4.y = Cp[0].Sp.y + (Cp[1].Sp.y - Cp[0].Sp.y) * t;
        p5.x = Cp[1].Sp.x + (Cp[2].Sp.x - Cp[1].Sp.x) * t;
        p5.y = Cp[1].Sp.y + (Cp[2].Sp.y - Cp[1].Sp.y) * t;
        p6.x = p4.x + (p5.x - p4.x) * t;
        p6.y = p4.y + (p5.y - p4.y) * t;
    }
}

class Bezier3{ 
    public var Pnt:Vector.<ControlPoint> = new Vector.<ControlPoint>;
    public var DivNum:int = 60;
    public var p4_x:Number, p4_y:Number, p5_x:Number, p5_y:Number, p6_x:Number, p6_y:Number;
    public var p7_x:Number, p7_y:Number, p8_x:Number, p8_y:Number, p9_x:Number, p9_y:Number;
    public function Bezier3( p0:ControlPoint, p1:ControlPoint, p2:ControlPoint, p3:ControlPoint ){
        Pnt[0] = p0; Pnt[1] = p1; Pnt[2] = p2; Pnt[3] = p3;
    }

    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( t:Number ):void{
        for( var i:int=0; i<3; i++ ){
            drawLine( Pnt[i].Sp.x, Pnt[i].Sp.y, Pnt[i+1].Sp.x, Pnt[i+1].Sp.y, 1.0, 0x00ff00 );
        }

        getPosition( t );
        drawLine( p4_x, p4_y, p5_x, p5_y, 1.0, 0xf08000 );
        drawLine( p5_x, p5_y, p6_x, p6_y, 1.0, 0xf08000 );
        drawLine( p7_x, p7_y, p8_x, p8_y, 1.0, 0xc0c000 );
        drawCircle( p4_x, p4_y, 0.5, 0x000000 );
        drawCircle( p5_x, p5_y, 0.5, 0x000000 );
        drawCircle( p6_x, p6_y, 0.5, 0x000000 );
        drawCircle( p7_x, p7_y, 0.5, 0x000000 );
        drawCircle( p8_x, p8_y, 0.5, 0x000000 );
    }

    public function drawPoint( t:Number ):void{
        getPosition( t );
        drawCircle( p9_x, p9_y, 2.5, 0xff0000 );
    }

    public function getPosition( t:Number ):Point{
        p4_x = Pnt[0].Sp.x + (Pnt[1].Sp.x - Pnt[0].Sp.x) * t;
        p4_y = Pnt[0].Sp.y + (Pnt[1].Sp.y - Pnt[0].Sp.y) * t;
        p5_x = Pnt[1].Sp.x + (Pnt[2].Sp.x - Pnt[1].Sp.x) * t;
        p5_y = Pnt[1].Sp.y + (Pnt[2].Sp.y - Pnt[1].Sp.y) * t;
        p6_x = Pnt[2].Sp.x + (Pnt[3].Sp.x - Pnt[2].Sp.x) * t;
        p6_y = Pnt[2].Sp.y + (Pnt[3].Sp.y - Pnt[2].Sp.y) * t;
        p7_x = p4_x + (p5_x - p4_x) * t;
        p7_y = p4_y + (p5_y - p4_y) * t;
        p8_x = p5_x + (p6_x - p5_x) * t;
        p8_y = p5_y + (p6_y - p5_y) * t;
        p9_x = p7_x + (p8_x - p7_x) * t;
        p9_y = p7_y + (p8_y - p7_y) * t;
        
        return new Point( p9_x, p9_y );
    }
}


class ControlPoint{ 
    public var Sp:Sprite; 
    public var isEnable:Boolean = false;
    public var Pos:Point;
    public function ControlPoint( p:Point ){ 
        Sp=new Sprite();   
        Pos = p; 
        Sp.x = Pos.x; 
        Sp.y = Pos.y;
        setEnable( true );
        Main.stage.addChild(Sp);  

        Sp.addEventListener(MouseEvent.MOUSE_UP,   function (event:MouseEvent):void{ Sp.stopDrag(); }); 
        Sp.addEventListener(MouseEvent.MOUSE_DOWN, function (event:MouseEvent):void{ if( isEnable ) Sp.startDrag(); });     
    } 

    public function setEnable( flg:Boolean ):void{    
        if( flg == true && isEnable == false ){
            Sp.graphics.clear();
            Sp.graphics.lineStyle(1.4,0x000000);       
            Sp.graphics.beginFill(0xe0d000,1);   
            Sp.graphics.drawCircle(0,0,8.0);   
            Sp.graphics.endFill();   
        }else if( flg == false && isEnable == true ){
            Sp.graphics.clear();
        }
        isEnable = flg;
    }
} 


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 );          
}   

function drawCircle( x:Number, y:Number, size:Number, col:int ):void{    
    Main.graphics.lineStyle(1.0,0x000000);       
    Main.graphics.beginFill( col, 1 );    
    Main.graphics.drawCircle( x, y, size );    
    Main.graphics.endFill();    
}   

var KEY_UP:int    = 0x01;    
var KEY_DOWN:int  = 0x02;    
var KEY_LEFT:int  = 0x04;    
var KEY_RIGHT:int = 0x08;    
var KEY_UP_TRG:int    = 0x10;    
var KEY_DOWN_TRG:int  = 0x20;    
var KEY_LEFT_TRG:int  = 0x40;    
var KEY_RIGHT_TRG:int = 0x80;    
var KeyData:int;    
function keyCheckDown(event:KeyboardEvent):void {     
    switch (event.keyCode){     
        case Keyboard.UP:      KeyData |= KEY_UP|KEY_UP_TRG; break;    
        case Keyboard.DOWN:    KeyData |= KEY_DOWN|KEY_DOWN_TRG; break;    
        case Keyboard.LEFT:    KeyData |= KEY_LEFT|KEY_LEFT_TRG; break;    
        case Keyboard.RIGHT:   KeyData |= KEY_RIGHT|KEY_RIGHT_TRG; break;    
    }    
}

function keyCheckUp(event:KeyboardEvent):void {     
    switch (event.keyCode){     
        case Keyboard.UP:      KeyData &= ~KEY_UP; break;    
        case Keyboard.DOWN:    KeyData &= ~KEY_DOWN; break;    
        case Keyboard.LEFT:    KeyData &= ~KEY_LEFT; break;    
        case Keyboard.RIGHT:   KeyData &= ~KEY_RIGHT; break;    
    }    
}     

function updateKey():void{    
    KeyData &= ~(KEY_UP_TRG|KEY_DOWN_TRG|KEY_LEFT_TRG|KEY_RIGHT_TRG);
}             

var MOUSE_LEFT:int = 0x01;    
var MOUSE_LEFT_TRG:int = 0x02;    
var MouseData:int;    
function MouseCheckDown(event:MouseEvent):void{    
    MouseData |= MOUSE_LEFT;    
    MouseData |= MOUSE_LEFT_TRG;    
}             

function MouseCheckUp(event:MouseEvent):void{    
    MouseData &= ~MOUSE_LEFT;    
}             

function MouseUpdate():void{    
    MouseData &= ~MOUSE_LEFT_TRG;    
}