JavaScriptでカム曲線をつくる

Delphiでカム曲線のクラスはできた。

コレを、JavaScriptに移植する。
web上で実際に動作する状態を見せて説明文を書くためだ。

JavaScriptは新たに勉強する。
スクリプト言語というのは、簡単に使い始める事が出来るのだが、最近のそれはかなり奥が深い。
特にJavaScriptオブジェクト指向はクラスベースでなくて、プロトタイプベースなので勝手が少し違う。
そこでつまずく。
躓いたかと思ったら、単純ミス。
クラスの定義は問題なかったのだが、呼び出し側でIntで呼ばなくてはいけない関数を、文字列で呼んでいた。

とりあえず、今現在のJavaScriptバージョンのソース

function Camcrv(){
}

Camcrv.prototype.set_parametor = function(no){
	this.crvno = no;

		this.t0 = 0.0;
		this.t7 = 1.0;
		this.s0 = 0.0;
		this.s7 = 1.0;
		this.v0 = 0.0;
		this.v7 = 0.0;
		
		switch(this.crvno){
			case 1://停留 Stop
				this.t1=0.0;this.t2=0.0;this.t3=0.0;this.t4=0.0;this.t5=0.0;this.t6=0.0; break;
			case 11://等加速度 Parabolic
				this.t1=0.0;this.t2=0.5;this.t3=0.5;this.t4=0.5;this.t5=0.5;this.t6=1.0;break;
			case 2:
			case 22://サイクロイド 
				this.t1=0.25;this.t2=0.25;this.t3=0.5;this.t4=0.5;this.t5=0.75;this.t6=0.75;break;
			case 5:
			case 25://変形台形
				this.t1=0.125;this.t2=0.375;this.t3=0.5;this.t4=0.5;this.t5=0.625;this.t6=0.875;break;
			case 6:
			case 26://変形正弦
				this.t1=0.125;this.t2=0.125;this.t3=0.5;this.t4=0.5;this.t5=0.875;this.t6=0.875;break;
			case 7:
			case 27://変形等速度
				this.t1=0.0625;this.t2=0.0625;this.t3=0.25;this.t4=0.75;this.t5=0.9375;this.t6=0.9375;break;
			case 28://変形等速度 MCthis.v25
				this.t1=3.0/32.0;this.t2=this.t1;this.t3=0.375;this.t4=0.625;this.t5=1.0-this.t2;this.t6=1.0-this.t1;break;
			case 3:
			case 12://単弦 Simple harmonic
				this.t1=0.0;this.t2=0.0;this.t3=0.5;this.t4=0.5;this.t5=1.0;this.t6=1.0;break;
			case 33://非対称サイクロイド
				this.t1=0.2;this.t2=0.2;this.t3=0.4;this.t4=0.4;this.t5=0.7;this.t6=0.7;break;
			case 34://"非対称変形台形
				this.t1=0.1;this.t2=0.3;this.t3=0.4;this.t4=0.4;this.t5=0.55;this.t6=0.85;break;
			case 35://トラペクロイド 
				this.t1=0.125;this.t2=(1.25+0.125*Pi)/(2.0+Pi);this.t3=this.t2+0.125;
				this.t4=this.t3;this.t5=this.t2+0.25;this.t6=this.t5;
				break;
			case 43://片停留サイクロイド m=1
				this.t1=0.25;this.t2=0.25;this.t3=0.5;this.t4=0.5;this.t5=1.0;this.t6=1.0;break;
			case 44://片停留サイクロイド m=2/3
				this.t1=0.2;this.t2=0.2;this.t3=0.4;this.t4=0.4;this.t5=1.0;this.t6=1.0;break;
			case 45://片停留変形台形 m=1
				this.t1=0.125;this.t2=(7.0/16.0)-(0.125/Math.PI);
				this.t3=this.t2+0.125;this.t4=this.t3;this.t5=this.t2+0.25;this.t6=1.0;break;
			case 46://片停留変形台形ファーガソン
				this.t1=0.125;this.t2=0.375;this.t3=0.5;this.t4=0.5;this.t5=0.625;this.t6=1.0;break;
			case 47://片停留変形台形 m=2/3
				this.t1=0.125;this.t2=0.6*(1.0-7.0/(18.0*Math.PI))-5.0/24.0;
				this.t3=this.t2+0.125;this.t4=this.t3;this.t5=this.t2+5.0/24.0;this.t6=1.0;break;
			case 48://片停留変形正弦 
				this.t1=0.125;this.t2=0.125;this.t3=0.5;this.t4=0.5;this.t5=1.0;this.t6=1.0;break;
			case 49://片停留トラペクロイド
				this.t1=0.125;this.t2=(10.0+Pi)/(16.0+8.0*Math.PI);
				this.t3=this.t2+0.125;this.t4=this.t3;this.t5=1.0;this.t6=1.0;break;
			case 50://無停留単弦
				this.t1=0.0;this.t2=0.0;this.t3=0.5;this.t4=0.5;this.t5=1.0;this.t6=1.0;break;
			case 51://無停留変形台形
				this.t1=0.0;this.t2=0.25;this.t3=0.5;this.t4=0.5;this.t5=0.75;this.t6=1.0;break;
			case 52://無停留変形等速度
				this.t1=0.0;this.t2=0.0;this.t3=0.25;this.t4=0.75;this.t5=1.0;this.t6=1.0;break;
			case 92:NC2曲線
				this.t1=0.0;this.t2=0.25;this.t3=1.0/3.0;this.t4=this.t3;this.t5=5.0/6.0;this.t6=this.t5;break;
			case 99://universal ユニバーサル曲線
				break;
			case 125://"SMT−3"
				this.t1=0.125;this.t2=0.375;this.t3=0.5;this.t4=0.5;this.t5=0.625;this.t6=0.875;break;
			case 126://SMS−3
				this.t1=0.125;this.t2=0.125;this.t3=0.5;this.t4=0.5;this.t5=0.875;this.t6=0.875;break;
			case 127://SMCV50−3
				this.t1=0.0625;this.t2=0.0625;this.t3=0.25;this.t4=0.75;this.t5=0.9375;this.t6=0.9375;break;
			case 128://SMCV25−3
				this.t1=3.0/32.0;this.t2=this.t1;this.t3=0.375;this.t4=0.625;this.t5=1.0-this.t2;this.t6=1.0-this.t1;break;
			case 199://グローバル曲線
				break;
			default://Not defined
				this.t1=0.0;this.t2=0.0;this.t3=0.0;this.t4=0.0;this.t5=0.0;this.t6=0.0;break;
 				break;
			}	
	
		switch(this.crvno){
			case 2:
			case 3:
			case 5:
			case 6:
			case 7:
			case 11:
			case 12:
			case 22:
			case 25:
			case 26:
			case 27:
			case 33:
			case 34:
			case 35:
			case 43:
			case 44:
			case 45:
			case 46:
			case 47:
			case 48:
			case 49:
			case 50:
			case 51:
			case 52:
			case 92:
			case 99:
				this.c1= 2.0*(this.t1-this.t0)/Math.PI;
				//this.c1= 2.0*this.t1/Math.PI;
				this.c2 = this.t2-this.t1;
				this.c3 = 2.0*(this.t3-this.t2)/Math.PI;
				this.c4 = this.t4-this.t3;
				this.c5 = 2.0*(this.t5-this.t4)/Math.PI;
				this.c6 = this.t6-this.t5;
				this.c7 =2.0*(this.t7-this.t6)/Math.PI;
				//this.c7 =2.0*(1.0-this.t6)/Math.PI;
				this.k1=this.s7-this.s0-this.v0*(this.t7-this.t0);
				this.k2=this.v7-this.v0;
				this.a1=-this.c7*this.c7-0.5*this.c6*this.c6+this.c5*this.c5-this.c6*(this.t7-this.t6)-this.c5*(this.t7-this.t4);
				this.b1=this.c3*this.c3+0.5*this.c2*this.c2-this.c1*this.c1+this.c3*(this.t7-this.t3)+this.c2*(this.t7-this.t2)+this.c1*(this.t7-this.t0);
				this.a2=-this.c7-this.c6-this.c5;
				this.b2=this.c3+this.c2+this.c1;

				this.amm=(this.k1*this.b2-this.k2*this.b1)/(this.a1*this.b2-this.a2*this.b1);
				this.amp=(this.k1*this.a2-this.k2*this.a1)/(this.b1*this.a2-this.b2*this.a1);
				this.ratio=this.amm/this.amp;
				this.v1=this.c1*this.amp+this.v0;this.v2=this.c2*this.amp+this.v1;this.v3=this.c3*this.amp+this.v2;
				this.vm=this.v3;
				this.v4=this.v3;this.v5=-this.c5*this.amm+this.v4;this.v6=-this.c6*this.amm+this.v5;//this.v7=-this.c7*this.amm+this.v6;
				this.s1=-this.c1*this.c1*this.amp+this.v1*(this.t1-this.t0)+this.s0;
				this.s2=0.5*this.c2*this.c2*this.amp+this.c2*this.v1+this.s1;
				this.s3=this.c3*this.c3*this.amp+this.v2*(this.t3-this.t2)+this.s2;
				this.s4=this.c4*this.v3+this.s3;
				this.s5=this.c5*this.c5*this.amm+this.v5*(this.t5-this.t4)+this.s4;
				this.s6=-0.5*this.c6*this.c6*this.amm+this.c6*this.v5+this.s5;
				//this.s7=-this.c7*this.c7*this.amm+this.v6*(this.t7-this.t6)+this.s6;
				if (this.c1 != 0.0) {this.jmp=this.amp/this.c1;} else {this.jmp = Infinity;}
				if (this.c3 != 0.0) {this.jmm=-this.amp/this.c3;} else {this.jmm= -Infinity;}
				if (this.c7 != 0.0) {this.jh=this.amm/this.c7;} else {this.jh=Infinity;}
				if (this.c3 == 0.0) {
					this.tthis.qm=this.t2;
					this.qm=this.amp*this.v2;
					}
				else {
					this.snq=(-this.c2-this.c1+Math.sqrt((this.c2+this.c1)*(this.c2+this.c1)+8.0*this.c3*this.c3))/(4.0*this.c3);
					this.csq=Math.sqrt(1.0-this.snq*this.snq);
					this.thq=Math.atan2(this.snq,this.csq);
					this.tqm=this.t2+this.c3*this.thq;
					this.qm=this.amp*this.csq*(this.c3*this.amp*this.snq+this.v2);
					}
				break;
			case 4:
			case 10:
				this.c1=0.0;this.c2=0.0;this.c3=0.0;this.c4=1.0;this.c5=0.0;this.c6=0.0;this.c7=0.0;
				this.s1=0.0;this.s2=0.0;this.s3=0.0;this.s4=1.0;this.s5=1.0;this.s6=1.0;
				this.v1=0.0;this.v2=0.0;this.v3=1.0;this.v4=1.0;this.v5=0.0;this.v6=0.0;this.vm=1.0;
				this.a1=0.0;this.a2=0.0;this.amm=-Infinity;this.amp=Infinity;
				this.b1=0.0;this.b2=0.0;this.csq=0.0;this.jh=Infinity;this.jmm=-Infinity;this.jmp=Infinity;
				this.k1=1.0;this.k2=0.0;p=0.0;this.qm=Infinity;this.ratio=0.0;this.thq=0.0;this.tqm=0.0;
				break;
			default:
				this.c1=0.0;this.c2=0.0;this.c3=0.0;this.c4=0.0;this.c5=0.0;this.c6=0.0;this.c7=0.0;
				this.s1=0.0;this.s2=0.0;this.s3=0.0;this.s4=0.0;this.s5=0.0;this.s6=0.0;
				this.v1=0.0;this.v2=0.0;this.v3=0.0;this.v4=0.0;this.v5=0.0;this.v6=0.0;this.vm=0.0;
				this.a1=0.0;this.a2=0.0;this.amm=0.0;this.amp=0.0;
				this.b1=0.0;this.b2=0.0;this.csq=0.0;this.jh=0.0;this.jmm=0.0;this.jmp=0.0;
				this.k1=0.0;this.k2=0.0;p=0.0;this.qm=0.0;this.ratio=0.0;this.thq=0.0;this.qm=0.0;
				break;
		}

}

Camcrv.prototype.toString = function(){

		switch (this.crvno){
			case 1:
				return "停留 Stop";
				break;
			case 11:
				return "等加速度 Parabolic";
				break;
			case 2:
			case 22:
				return "サイクロイド ";
				break;
			case 5:
			case 25:
				return "変形台形 ";
				break;
			case 6:
			case 26:
				return "変形正弦 ";
				break;
			case 7:
			case 27:
				return "変形等速度 ";
			case 28:
				return "変形等速度 MCthis.v25";
				break;
			case 3:
			case 12:
				return "単弦 Simple harmonic";
				break;
			case 33:
				return "非対称サイクロイド ";
				break;
			case 34:
				return"非対称変形台形 ";
				break;
			case 35:
				return "トラペクロイド ";
				break;
			case 43:
				return "片停留サイクロイド m=1";
				break;
			case 44:
				return "片停留サイクロイド m=2/3";
				break;
			case 45:
				return "片停留変形台形 m=1";
				break;
			case 46:
				return"片停留変形台形ファーガソン ";
				break;
			case 47:
				return "片停留変形台形 m=2/3";
				break;
			case 48:
				return "片停留変形正弦 ";
				break;
			case 49:
				return "片停留トラペクロイド";
				break;
			case 50:
				return "無停留単弦 ";
				break;
			case 51:
				return "無停留変形台形 ";
				break;
			case 52:
				return "無停留変形等速度 ";
				break;
			case 92:
				return "NC2曲線 ";
				break;
			case 99:
				return"ユニバーサル曲線";
				break;
			case 125:
				return "SMT−3";
				break;
			case 126:
				return"SMS−3";
				break;
			case 127:
				return"SMCV50−3";
				break;
			case 128:
				return "SMCV25−3";
				break;
			case 199:
				return "グローバル曲線";
				break;
			default:
				return "Not defined";
				break;
		}
}

Camcrv.prototype.t_range = function(t){

		if (t<this.t0)  {return 0;}
		else if (t<this.t1) {return 1;}
		else if (t<this.t2){return 2;}
		else if (t<this.t3){return 3;}
		else if (t<this.t4){return 4;}
		else if (t<this.t5){return 5;}
		else if (t<this.t6){return 6;}
		else if (t<=this.t7){return 7;}
		else {return 8;}
}

Camcrv.prototype.s = function(t){
		switch(this.t_range(t)){
			case 0:
				return this.s0;
				break;
			case 1:
				p = (t-this.t0)/this.c1;
				return -this.c1*this.c1*this.amp*Math.sin(p)+this.v1*(t-this.t0)+this.s0;
				break;
			case 2:
				p = t-this.t1;
				return  0.5*this.amp*p*p+this.v1*p+this.s1;
				break;
			case 3:
				p = (t-this.t2)/this.c3
				return  -this.c3*this.c3*this.amp*(Math.cos(p)-1.0)+this.v2*(t-this.t2)+this.s2;
				break;
			case 4:
				return  this.v3*(t-this.t3)+this.s3;
				break;
			case 5:
				p = (t-this.t4)/this.c5;
				return  this.c5*this.c5*this.amm*Math.sin(p)+this.v5*(t-this.t4)+this.s4;
				break;
			case 6:
				p = t-this.t5;
				return  -0.5*this.amm*p*p+this.v5*p+this.s5;
				break;
			case 7:
				p = (t-this.t6)/this.c7;
				return  this.c7*this.c7*this.amm*(Math.cos(p)-1.0)+this.v6*(t-this.t6)+this.s6;
				break;
			case 8:
				return  this.s7+this.v7*(t-this.t7);
				break;
			default:
				return  0.0;
				break;
		}
}	    

Camcrv.prototype.v = function(t){
		switch (this.crvno){
			case 4:
			case 10:
				return 1.0;
				break;
			case 2:
			case 3:
			case 5:
			case 6:
			case 7:
			case 11:
			case 12:
			case 22:
			case 25:
			case 26:
			case 27:
			case 33:
			case 34:
			case 35:
			case 43:
			case 44:
			case 45:
			case 46:
			case 47:
			case 48:
			case 49:
			case 50:
			case 51:
			case 52:
			case 92:
			case 99:
				switch(this.t_range(t)){
					case 0:
						return this.v0;
						break;
					case 1:
						p=(t-this.t0)/this.c1;
						return -this.c1*this.amp*Math.cos(p)+this.v1;
						break;
					case 2:
						p=t-this.t1; 
						return this.amp*p+this.v1;
						break;
					case 3:
						p=(t-this.t2)/this.c3;
						return this.c3*this.amp*Math.sin(p)+this.v2;
						break;
					case 4:
						return this.v3;
						break;
					case 5:
						p=(t-this.t4)/this.c5;
						return  this.c5*this.amm*Math.cos(p)+this.v5;
						break;
					case 6:
						p=t-this.t5
						return -this.amm*p+this.v5;
						break;
					case 7:
						p=(t-this.t6)/this.c7;
						return -this.c7*this.amm*Math.sin(p)+this.v6;
						break;
					case 8:
						return this.v7;
						break;
					default:
						return 0.0;
						break;
					}
			default:
				return 0.0;
				break;
		}
}

Camcrv.prototype.a = function(t){
		switch(this.crvno){
			case 2:
			case 3:
			case 5:
			case 6:
			case 7:
			case 11:
			case 12:
			case 22:
			case 25:
			case 26:
			case 27:
			case 33:
			case 34:
			case 35:
			case 43:
			case 44:
			case 45:
			case 46:
			case 47:
			case 48:
			case 9:
			case 50:
			case 51:
			case 52:
			case 92:
			case 99:
				switch(this.t_range(t)){
					case 1: return this.amp*Math.sin((t-this.t0)/this.c1); break;
					case 2: return this.amp; break;
					case 3: return this.amp*Math.cos((t-this.t2)/this.c3); break;
					case 4: return 0.0; break;
					case 5: return -this.amm*Math.sin((t-this.t4)/this.c5); break;
					case 6: return -this.amm; break;
					case 7: return -this.amm*Math.cos((t-this.t6)/this.c7);break;
					default : return 0.0; break;
				}
			default: return 0.0; break;
		}
}

Camcrv.prototype.j = function(t){
		switch(this.crvno){
			case 2:
			case 3:
			case 5:
			case 6:
			case 7:
			case 11:
			case 12:
			case 22:
			case 25:
			case 26:
			case 27:
			case 33:
			case 34:
			case 35:
			case 43:
			case 44:
			case 45:
			case 46:
			case 47:
			case 48:
			case 9:
			case 50:
			case 51:
			case 52:
			case 92:
			case 99:
				switch(this.t_range(t)){
					case 1: return this.amp*Math.cos((t-this.t0)/this.c1)/this.c1; break;
					case 2: return 0.0; break;
					case 3: return -this.amp*Math.sin((t-this.t2)/this.c3)/this.c3; break;
					case 4: return 0.0; break;
					case 5: return -this.amm*Math.cos((t-this.t4)/this.c5)/this.c5; break;
					case 6: return 0.0; break;
					case 7: return this.amm*Math.sin((t-this.t6)/this.c7)/this.c7; break;
					default: return 0.0; break
				}
			default : return 0.0 ;
			break;
		}
}