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

Catmull-Rom スプライン曲線

Get Adobe Flash player
by sanesashi 14 Sep 2010
/**
 * Copyright sanesashi ( http://wonderfl.net/user/sanesashi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/4IBM
 */

// Catmull-Rom スプライン曲線
// code from http://l00oo.oo00l.com/blog/archives/264
package {
    import flash.display.AVM1Movie;
  import __AS3__.vec.Vector;

  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.geom.Point;

  [SWF(width="400", height="400", backgroundColor="#ffffff")]
  public class spline extends Sprite
  {
    private var points:Array;

    public function spline()
    {
      if(stage) init();
      else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event=null):void
    {
      points = new Array();
      stage.scaleMode = StageScaleMode.NO_SCALE;
      stage.align = StageAlign.TOP_LEFT;
      setup();
    }

    private function setup():void
    {
      stage.addEventListener(MouseEvent.CLICK, onStageClick);
    }

    private function plot(x:Number, y:Number):void
    {
        var point:Sprite = new Sprite();
        point.x = x;//Math.round(Math.random() * stage.stageWidth);
        point.y = y;//Math.round(Math.random() * stage.stageHeight);
        point.graphics.beginFill(0xff3366);
        point.graphics.drawCircle(0, 0, 3);
        point.graphics.endFill();
        point.buttonMode = true;
        point.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownListener);
        addChild(point);
        points.push(point);
        
        setPoints();
    }

    private function setPoints():void
    {
      var v:Vector.<Point> = new Vector.<Point>();
      for(var i:uint; i<points.length; i++)
      {
        var point:Sprite = Sprite(points[i]);
        v[i] = new Point(point.x, point.y);
      }
      graphics.clear();
      drawSpline(v);
    }

    private function drawSpline(v:Vector.<Point>):void
    {
      if(v.length<2) return;
      v.splice(0,0,v[0]);
      v.push(v[v.length-1]);

      var numSegments:uint = 20;//曲線分割数(補完する数)
      for(var i:uint=0; i<v.length-3; i++)
      {
        var p0:Point = v[i];
        var p1:Point = v[i+1];
        var p2:Point = v[i+2];
        var p3:Point = v[i+3];
        splineTo(p0, p1, p2, p3, numSegments);
      }
    }

    private function splineTo(p0:Point, p1:Point, p2:Point,
      p3:Point, numSegments:uint):void
    {
      graphics.lineStyle(1, 0x666666);
      graphics.moveTo(p1.x, p1.y);
      for(var i:uint=0; i<numSegments; i++)
      {
        var t:Number = (i+1)/numSegments;
        graphics.lineTo(
          catmullRom(p0.x, p1.x, p2.x, p3.x, t),
          catmullRom(p0.y, p1.y, p2.y, p3.y, t)
        );
      }
    }

    public function catmullRom(p0:Number, p1:Number, p2:Number,
      p3:Number, t:Number):Number
    {
        var v0:Number = (p2 - p0) * 0.5;
        var v1:Number = (p3 - p1) * 0.5;
        return (2*p1 - 2*p2 + v0 + v1)*t*t*t +
        (-3*p1 + 3*p2 - 2*v0 - v1)*t*t + v0*t + p1;
    }
    
    private function onStageClick(e:MouseEvent):void
    {
        plot(mouseX, mouseY);
    }
    
    private function mouseDownListener(e:MouseEvent):void
    {
      var point:Sprite = Sprite(e.target);
      point.startDrag();
      point.addEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
      addEventListener(Event.ENTER_FRAME, enterFrameListener);
    }

    private function mouseUpListener(e:MouseEvent):void
    {
      var point:Sprite = Sprite(e.target);
      point.stopDrag();
      point.removeEventListener(MouseEvent.MOUSE_UP, mouseUpListener);
      removeEventListener(Event.ENTER_FRAME, enterFrameListener);
    }

    private function enterFrameListener(e:Event):void
    {
      setPoints();
    }

  }
}