スプラインとか

スプライン曲線を引くコードがあったのでAS3にサクッと移植
とりあえずザックリと表示までなのでいろいろと問題はあります。

  • ちなみに上の図は5つのコントロールポイントで表示しています。


  • CSprine.as
package
{
    import flash.display.*;	
	public class CSprine
	{
		public var x_arr:Array = null;
		public var y_arr:Array = null;
		public var z_arr:Array = null;
		
		public function CSprine()
		{
		}
		public function init(x:Array , y:Array):void
		{
			x_arr = x;
			y_arr = y;
			z_arr = new Array();
			
			var n:int = x_arr.length;
			var h_arr:Array = new Array;
			var d_arr:Array = new Array;
			z_arr[0] = z_arr[n-1] = 0;
			
			
			for(var i:int = 0; i<n-1; i++){
				h_arr[i] = x_arr[i+1] - x_arr[i];
				d_arr[i+1] = (y_arr[i+1] - y_arr[i]) / h_arr[i];
			}
			
			z_arr[1] = d_arr[2] - d_arr[1] - h_arr[0] * z_arr[0];
			d_arr[1] = 2 * ( x_arr[2] - x_arr[0] );
			
			for(var j:int = 1; j<n-2; j++){
				var t:Number = h_arr[j] / d_arr[j];
				z_arr[j+1] = d_arr[j+2] - d_arr[j+1] - z_arr[j] * t;
				d_arr[j+1] = 2 * (x_arr[j+2] - x_arr[j]) - h_arr[j] * t;
			}
			
			
			z_arr[n-2] -= h_arr[n-2] * z_arr[n-1];
			
			i = n -2;
			while(i>0){
				z_arr[i] = (z_arr[i] - h_arr[i] * z_arr[i+1]) / d_arr[i];
				i-=1;
			}
		}
		private function destroy():void{
			if(x_arr!=null)	x_arr = null;	
			if(y_arr!=null)	y_arr = null;	
			if(z_arr!=null)	z_arr = null;	
		}
   		public function interpolate(t:Number):Number{
		    var i:int = 0;
		    var j:int = x_arr.length - 1;
		    
		    while (i < j){
		      var k:int = (i + j) / 2;
		      if (x_arr[k] < t){
		        i = k + 1;
			  }else{
		        j = k;
		      }
		    }
		    
		    if( i > 0){
		      i -= 1;
		    }
		    
		    var h:Number = x_arr[i+1] - x_arr[i]
		    var d:Number = t - x_arr[i]
		    return (((z_arr[i+1] - z_arr[i]) * d / h + z_arr[i] * 3) * d + ((y_arr[i+1] - y_arr[i]) / h - (z_arr[i] * 2 + z_arr[i+1]) * h)) * d + y_arr[i]
   		}
   		
   		public function drawSprine(line:Shape, x:Array , y:Array, span:Number, color:uint):void{

			this.init(x,y);
			line.graphics.clear();
            line.graphics.lineStyle(0,color);
            line.graphics.moveTo(x_arr[0],y_arr[0]);
            
			var i:Number = 0;
			while (i <= x_arr[x_arr.length-1]){
              line.graphics.lineTo(i,this.interpolate(i));
			  i += span;
	   		}
	   		
	   		this.destroy();
   		}
	}
}

クラス内で宣言して

		private var curve:Shape = new Shape;
		private var sp:CSprine = new CSprine();

ShapeをaddChildして配列にXとYのポイントを突っ込んで描画する。

		addChild(curve);

		var cx:Array = new Array;		
		var cy:Array = new Array;
		cx.push(0,200,400,700);
		cy.push(200,80,50,150);
		sp.drawSprine(curve,cx,cy,5,0xff0000);

これで適当にとったスプラインが描画できる。
が。今は左から順番に並んだポイントだけに対応、あとで修正しまつ。