<label><input type="range" min=1 max=99 value=50 id="fSlider" >比率</label> <label><input type="range" min=1 max=10 value=2 id="NSlider" >歯数</label> <canvas id="CycCanvas1" width="300" height="300"></canvas> <script> /* サイクロイドポンプ曲線描画 原作:裏目小僧*/ var cvs = document.getElementById("CycCanvas1"); var c = cvs.getContext("2d"); var X0 =150; var Y0 =150; var rotc=0; var rad0=0; var f =(1+Math.trunc(Math.random() * 18))/20; var N = 3;//1+Math.trunc(Math.random() * 5); let fSlider = document.getElementById('fSlider'); fSlider.value = f*100; let NSlider= document.getElementById('NSlider'); NSlider.value = N; function cycDraw(n,x0,y0,r0,rot) {//一枚の歯車描画 let NN=2;//分解能大きくするほど荒い let r1 = r0 * f; //外転 let r2 = r0 * (1 - f); //内転 r0 = r0*n; let lap = 2 * Math.PI * r0; //円周 let psz = Math.trunc(lap/NN); rot=rot/n; c.beginPath(); for(let i = 0 ; i<psz ; i++){ let d0 = i*NN / r0; let d1 = d0 * n; d0 = d0 + rot+rad0/n; while( d1 > 2 * Math.PI) d1 = d1 - 2 * Math.PI; if ( d1 / (2 * Math.PI) <= f ){ //外転描画 d2 = d0 + d1 / f; x1 = x0 + Math.cos(d0) * (r0 + r1) - Math.cos(d2) * (r1); y1 = y0 + Math.sin(d0) * (r0 + r1) - Math.sin(d2) * (r1); } else { //内転 d2 = d0 - (d1 - 2 * Math.PI * f) / (1 - f); x1 = x0 + Math.cos(d0) * (r0 - r2) + Math.cos(d2) * (r2); y1 = y0 + Math.sin(d0) * (r0 - r2) + Math.sin(d2) * (r2); }; if(i == 0) c.moveTo(x1, y1); else c.lineTo(x1, y1); }; c.closePath(); //moveTo()で指定した始点に向けて線を引き、領域を閉じます。 return ; }; const WDRAW = function(){ let ra=rad0; f = Math.round(fSlider.value)/100; N = Math.round(NSlider.value); let r0 =((Y0 - 4) / ((N + 1) + f * 2)); c.fillStyle="#444444"; c.arc(X0,Y0,r0*(N+1+2*f),0,2*Math.PI); c.fill(); c.fillStyle="#FFFF00"; cycDraw(N+1,X0,Y0,r0,rotc * Math.PI / 180);//N+1枚の歯車描画 c.fill(); //stroke()では輪郭線を描き、fill()にすると中を塗りつぶします。
c.fillStyle="#000000"; cycDraw(N,X0+r0*Math.cos(ra),Y0+r0*Math.sin(ra),r0,rotc * Math.PI / 180-ra);//N枚の歯車描画 c.fill(); //stroke()では輪郭線を描き、fill()にすると中を塗りつぶします。
rotc+=3;//回転角を進めてゆく if(rotc>360) rotc-=360; }; const RDRAW = function(){//外側を固定し内側を回転 f = Math.round(fSlider.value)/100; N = Math.round(NSlider.value); let r0 =((Y0 - 4) / ((N + 1) + f * 2)); c.fillStyle="#444444"; c.arc(X0,Y0,r0*(N+1+2*f),0,2*Math.PI); c.fill(); c.fillStyle="#FFFF00"; cycDraw(N+1,X0,Y0,r0,0);//N+1枚の歯車描画 c.fill(); //stroke()では輪郭線を描き、fill()にすると中を塗りつぶします。 let rad = rotc * Math.PI / 180; let x1 = X0 + (r0 * Math.cos(rad)); let y1 = Y0 + (r0 * Math.sin(rad)); c.fillStyle="#000000"; cycDraw(N,x1,y1,r0,-rad);//N枚の歯車描画 c.fill(); //stroke()では輪郭線を描き、fill()にすると中を塗りつぶします。 rotc+=3;//回転角を進めてゆく if(rotc>360) rotc-=360; };
const VDRAW = function(){//内側の回転振動 f = Math.round(fSlider.value)/100; N = Math.round(NSlider.value); let r0 =((Y0 - 4) / ((N + 1) + f * 2)); c.fillStyle="#444444"; c.arc(X0,Y0,3+r0*(N+1+2*f),0,2*Math.PI); c.fill(); c.fillStyle="#FFFF00"; let rad = rotc * Math.PI / 180; cycDraw(N+1,X0,Y0,r0,rad);//N+1枚の歯車描画 c.fill(); let x1 = X0 + (r0 * Math.cos(rad)); let y1 = Y0 + (r0 * Math.sin(rad));
c.fillStyle="#000000"; cycDraw(N,x1,y1,r0,0);//N枚の歯車描画 c.fill(); rotc+=3;//回転角を進めてゆく if(rotc>360) rotc-=360; };
const VEDRAW = function(){//外側の回転振動 f = Math.round(fSlider.value)/100; N = Math.round(NSlider.value); let r0 =((Y0 - 4) / ((N + 2) + f * 2)); let rad = rotc * Math.PI / 180; let x1 = X0 - (r0 * Math.cos(rad)); let y1 = Y0 + (r0 * Math.sin(rad)); c.fillStyle="#ffffff"; c.fillRect(0, 0, cvs.width,cvs.height); c.fillStyle="#00ff00"; c.beginPath(); c.arc(X0,Y0,3+r0*(N+2+2*f),0,2*Math.PI); c.closePath(); c.stroke(); c.fillStyle="#444444"; c.beginPath(); c.arc(x1,y1,3+r0*(N+1+2*f),0,2*Math.PI); c.closePath(); c.fill(); c.fillStyle="#FFFF00"; cycDraw(N+1,x1,y1,r0,0);//N+1枚の歯車描画 c.fill(); //stroke()では輪郭線を描き、fill()にすると中を塗りつぶします。 c.fillStyle="#000000"; cycDraw(N,X0,Y0,r0,rad);//N枚の歯車描画 c.fill(); //stroke()では輪郭線を描き、fill()にすると中を塗りつぶします。 rotc+=3;//回転角を進めてゆく if(rotc>360) rotc-=360; };
var rotp=0; var rotSw=false; function RotPad(onoff,x,y) { let r=Math.atan2(X0-x,Y0-y); if(rotSw) rad0 -= r-rotp; rotp=r; rotSw=onoff; } cvs.addEventListener('mousemove', function(e){ RotPad(e.buttons>0, e.offsetX, e.offsetY); }); cvs.addEventListener('touchmove',function(e){ e.preventDefault(); let r= e.target.getBoundingClientRect(); if(e.touches.length=1){ let x=e.touches[0].pageX-r.left - window.pageXOffset; let y=e.touches[0].pageY-r.top - window.pageYOffset; RotPad(true,x,y); }; }); cvs.addEventListener('touchend' ,function(){rotSw=false;}); var IntVal= setInterval(WDRAW , 100); </script>
<INPUT TYPE="BUTTON" VALUE="外側を固定し内側を回転" onClick="clearInterval(IntVal);IntVal=setInterval(RDRAW , 100);"></INPUT> <INPUT TYPE="BUTTON" VALUE="外も内側も歯車のように回転" onClick="clearInterval(IntVal);IntVal=setInterval(WDRAW , 100);"></INPUT> <INPUT TYPE="BUTTON" VALUE="内側が回転振動" onClick="clearInterval(IntVal);IntVal=setInterval(VDRAW , 100);"></INPUT> <INPUT TYPE="BUTTON" VALUE="外側が回転振動" onClick="clearInterval(IntVal);IntVal=setInterval(VEDRAW , 100);"></INPUT>
<INPUT TYPE="BUTTON" VALUE="表示幅を4割増" onClick="cvs.width*=1.4142;cvs.height*=1.4142; X0 =cvs.width/2; Y0 =cvs.height/2; "></INPUT>
プライバシーポリシー本文は日本語以外に翻訳禁止