スプラインとか
スプライン曲線を引くコードがあったので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);
これで適当にとったスプラインが描画できる。
が。今は左から順番に並んだポイントだけに対応、あとで修正しまつ。