歯車について勉強する3 の履歴(No.3)
更新- 履歴一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- 工作/歯車について勉強する3 へ行く。
歯車を描く†
LANG: p5js_live const t=[];function e(e,n,i,r){let l=20*i+20,s=e.createSpan(n).position(20,l),a=e.createSpan(String(r.value));a.position(100,l);let h=e.createSlider(r.min,r.max,r.value,r.step);return h.position(150,l),h.size(300),h.elt.oninput=()=>a.html(String(h.value())),t.push(s,a,h),h}function n(e,i,r,l=0,s=!1){let a=100*l+20,h=20*r+20,o=e.createCheckbox();o.position(a,h),o.checked(s);let u=e.createSpan(i).position(a+20,h);return u.mouseClicked(()=>{o.checked(!o.checked()),o.elt.onchange&&o.elt.onchange()}),u.style("cursor","pointer "),t.push(u,o),o}class i{constructor(t,e){this.x=t,this.y=e}static polar(t,e){return new i(t*Math.cos(e),t*Math.sin(e))}angle(){return Math.atan2(this.y,this.x)}equal(t){return 1e-6>Math.abs(this.x-t.x)&&1e-6>Math.abs(this.y-t.y)}add(t){return new i(this.x+t.x,this.y+t.y)}sub(t){return new i(this.x-t.x,this.y-t.y)}mul(t){return new i(this.x*t,this.y*t)}rotate(t){let e=Math.cos(t),n=Math.sin(t);return new i(this.x*e-this.y*n,this.x*n+this.y*e)}addRotated(t,e){return this.add(e.rotate(t))}flipY(){return new i(this.x,-this.y)}flipX(){return new i(-this.x,this.y)}norm(){return Math.sqrt(this.x*this.x+this.y*this.y)}normalize(t=1){let e=this.norm()/t;return new i(this.x/e,this.y/e)}polar(){return[this.norm(),this.angle()]}inner(t){return this.x*t.x+this.y*t.y}outer(t){return this.x*t.y-this.y*t.x}}function r(t,e){return new i(t,e)}class l extends Array{constructor(t,...e){t instanceof i?(super(t,...e),this.option={}):(super(...e),this.option=t??{})}static extractPoints(t,e){if(t.length<=e)return t;let n=t.totalLength(),i=new l(t.option),r=0,s=0;for(let l=0;l<t.length-1;l++)s>=r&&(i.push(t[l]),r=n*i.length/e),s+=t[l].sub(t[l+1]).norm();return i.push(t[t.length-1]),i}static circle(t,e=r(0,0),n={},i=100){let s=new l(n);for(let n=0;n<=i;n++){let l=2*Math.PI*n/i;s.push(r(t*Math.cos(l),t*Math.sin(l)).add(e))}return s}totalLength(){let t=0;for(let e=0;e<this.length-1;e++)t+=this[e].sub(this[e+1]).norm();return t}draw(t,e=!1){if(void 0===this.option?.stroke?t.stroke("black"):t.stroke(this.option.stroke),void 0===this.option?.weight?t.strokeWeight(1):t.strokeWeight(this.option.weight),void 0===this.option?.dash?t.drawingContext.setLineDash([]):t.drawingContext.setLineDash(this.option.dash),void 0===this.option?.fill){t.noFill(),t.beginShape();for(let e=0;e<this.length;e++)t.vertex(this[e].x,this[e].y);t.endShape()}else{t.fill(this.option.fill),t.beginShape();for(let e=0;e<this.length;e++)t.vertex(this[e].x,this[e].y);t.endShape(t.CLOSE)}e&&this.forEach(e=>t.circle(e.x,e.y,1.5))}apply(t,e=this.option){return new l(e,...this.map(t))}crossPoint(t){return s(this[0],this[1],t[0],t[1])}direction(t=0){return this[t].sub(this[t+1]).normalize()}}function s(t,e,n,i){let r=e.sub(t),l=i.sub(n),s=n.sub(t),a=r.outer(l);if(0==a)return;let h=s.outer(r)/a,o=s.outer(l)/a;if(!(h<0)&&!(h>1)&&!(o<0)&&!(o>1))return t.add(r.mul(o))}function a(t,e,n){let i=n.sub(e),r=t.sub(e);return Math.abs(i.outer(r)/i.norm())}function h(t,e,n,i=1e-6){for(;t+i<e;){let i=t+(e-t)/3,r=e-(e-t)/3;n(i)<n(r)?e=r:t=i}return(t+e)/2}function o(t){let{m:e,z:n}=t={...t};t.inner&&([t.mk,t.mf]=[t.mf,t.mk],t.fillet=0);let o=e*n/2,{r1:c,r2:f,filletCenter:m,filletRadius:d}=function(t){let e,{m:n,z:i,alpha:l,shift:s,fillet:a,mf:h,mk:o}=t,u=i*n/2,{sin:c,cos:f,tan:m,min:d,max:g,PI:x}=Math;a=d(a,(h-o)/(1-c(l)));let b=g(0,(n*x/4-(n+h-o)*m(l))/m(x/4-l/2));return e=a>b?r(u-h+s+(a=b),-n*x/4):r(u-h+s+a,(-h+a)*m(l)-a/f(l)),{r1:r(u+s+h,h*m(l)),r2:r(u-o+s,-o*m(l)),filletCenter:e,filletRadius:a}}(t),g=(t,e)=>e.add(r(0,-o*t)).rotate(t),x=(t,e)=>{let{sin:n,cos:i,PI:l}=Math;return e.rotate(t+l/2).add(r(o*(n(t)+t*i(t)),o*(-i(t)+t*n(t))))},b=t=>{let e=g(t,c),n=g(t,f).sub(e),i=x(t,c),r=x(t,f).sub(i),l=i.outer(n)/r.outer(n);return[e.sub(n.mul(l)),l]},v=t=>{let e=g(t,m),n=x(t,m).normalize(d),i=e.addRotated(-Math.PI/2,n),r=e.addRotated(Math.PI/2,n);return i.x-i.y<r.x-r.y?i:r},{cInvolute:y,involuteT:k}=function(t,e){let{alpha:n,mk:i,mf:r,shift:s,z:a,m:o,backlash:u}=t,c=o*a/2,{abs:f,PI:m}=Math,d,g,x=[];d=h(0,90-n,t=>f(e(t)[0].norm()-c-i-s)),e(d)[0].angle()>m/a/2-u&&(d=h(0,d,t=>f(e(t)[0].angle()-(m/a/2-u)))),g=h(0,-2*n,t=>e(t)[0].norm()),e(g)[0].norm()&&(g=function(t,e,n,i=1e-6){let r=n(t),l=n(e);if(r*l>0)return Math.abs(r)<Math.abs(l)?t:e;for(r>l&&([t,e]=[e,t]);Math.abs(t-e)>i;){let i=(t+e)/2;0>n(i)?t=i:e=i}return(t+e)/2}(0,g,t=>e(t)[0].norm()-(c-r+s)));let b=new l;for(let t=0;t<300;t++){let n=d+(g-d)*t/300;b.push(e(n)[0]),x.push(n)}return{cInvolute:b,involuteT:x}}(t,b),M=new l,z=[];return t.inner||([M,z]=function(t,e,n,s,a,o){let u,c;let{abs:f,PI:m,ceil:d}=Math,{shift:g,alpha:x,m:b,z:v,mk:y,backlash:k}=t,M=b*v/2,z=M+y;for(u=0;!(s.add(r(0,-M*u)).rotate(u).norm()>z+g);u-=.05);for(c=.05;!(s.add(r(0,-M*c)).rotate(c).norm()>z+g);c+=.05);let w=h(u,c,t=>n(t).norm());e(w,s).norm()>M&&([u,c]=[c,u]),c=w;let P=!1,I=null,S=1,C=u,N=[],E=new l;for(let t=0;t<=60;t+=S){let r=u+(c-u)*t/60,l=n(r);P||l.norm()>o.norm()&&l.sub(o).angle()<x||(P=!0,C=r,I&&(E.push(I),N.push(r-(c-u)*S/60))),P&&(E.push(l),N.push(r));let h=e(r,s);if(t>0&&h.sub(e(w,s)).norm()<b/1e3){let t=f(l.sub(e(w,s)).angle()),n=m-m/v/2+k,r=d(f(n-t)/m*180);for(let l=1;l<=r;l++){let h=t+(n-t)*l/r;E.push(e(w,s).add(i.polar(a,h)))}break}t>0&&l.sub(I).norm()>b/20&&(S/=2),I=l}return u=C,[E,N]}(t,g,v,m,d,f),{cInvolute:y,involuteT:k,cFillet:M,filletT:z}=function(t,e,n,i,r,l){let[o,u,c]=function(t,e){let n=0,i=0;for(;n<t.length-1&&i<e.length-1;){if(t[n+1].x>e[i].x){n++;continue}if(t[n].x<e[i+1].x){i++;continue}let r=s(t[n],t[n+1],e[i],e[i+1]);if(r)return[r,n,i];t[n+1].x>e[i+1].x?n++:i++}return[]}(t,i);if(o)t.splice(u+1,1/0,o),e.splice(u+1,1/0,h(e[u],e[u+1],t=>n(t)[0].sub(o).norm())),i.splice(0,c+1,o),r.splice(0,c+1,h(r[c],r[c+1],t=>l(t).sub(o).norm()));else{let[s,o,u,c]=function(t,e){let n=0,i=0,r=[1/0];for(;n<t.length-1&&i<e.length-1;){if(t[n+1].x>e[i].x){n++;continue}if(t[n].x<e[i+1].x){i++;continue}if(t[n].x<e[i].x){let l=a(t[n],e[i],e[i+1]);l<r[0]&&(r=[l,n,i,0])}else{let l=a(e[i],t[n],t[n+1]);l<r[0]&&(r=[l,n,i,1])}t[n+1].x>e[i+1].x?n++:i++}return r}(t,i);c?(t.splice(o+1,1/0,i[u]),i.splice(0,u),e.splice(o+1,1/0,h(e[o],e[o+1],t=>n(t)[0].sub(i[u]).norm())),r.splice(0,u)):(t.splice(o+1,1/0),i.splice(0,u+1,t[o]),e.splice(o+1,1/0),r.splice(0,u+1,h(r[u],r[u+1],e=>l(e).sub(t[o]).norm())))}return{cInvolute:t,involuteT:e,cFillet:i,filletT:r}}(y,k,b,M,z,v)),function(t,e,n){let{m:i,mk:r,shift:s,z:a,backlash:h,mf:o}=t,{PI:c}=Math,f=[],m=u(i*a/2+r+s,c/a/2-h,e[0].angle());f.push(m);let d=l.extractPoints(e,30).filter((t,e,n)=>e<2||e>n.length-3||e%2==1);f.push(new l(e.option,...d));let g=l.extractPoints(n,30).filter((t,e,n)=>e<2||e>n.length-3||e%2==1);if(f.push(new l(n.option,...g)),t.inner){let t=u(e.at(-1).norm(),e.at(-1).angle(),-c/a/2-h);f.push(t)}else if(n.length>0){let t=u(i*a/2-o+s,n[n.length-1].angle(),-c/a/2-h);f.push(t)}f=f.map(t=>t.apply(t=>t.rotate(h-c/a/2)));let x=[];x.push(e[0].rotate(h-c/a/2).polar()),x.push(e.at(-1).rotate(h-c/a/2).polar()),n.length>0&&x.push(n.at(-1).rotate(h-c/a/2).polar());let b=f.reduce((t,e)=>t.slice(0,-1).concat(e.map(t=>t.polar())),[]),v={curve:[...b=b.map(t=>[t[0],-t[1]]).reverse().concat(b)],connections:[...x=x.map(t=>[t[0],-t[1]]).reverse().concat(x)]};for(let t=1;t<a;t++)v.curve=v.curve.concat(b.map(e=>[e[0],e[1]-2*t*c/a])),v.connections=v.connections.concat(x.map(e=>[e[0],e[1]-2*t*c/a]));return v}(t,y,M)}function u(t,e,n,s=r(0,0),a=.02,h=1e-4){let{abs:o,ceil:c,max:f}=Math,m=new l;if(t*o(n-e)>h){let r=f(2,c(o(n-e)/a));for(let l=0;l<=r;l++){let a=e+(n-e)*l/r;m.push(s.add(i.polar(t,a)))}}return m}let c=null,f=null,m=null;(i=>{let r;let l={width:600,height:600,ox:0,oy:0};i.setup=()=>{let{width:s,height:a}=l;l.ox=s/2,l.oy=a/2,i.createCanvas(s,a).style("position","relative"),r=function(i){let r=n(i,"ツールを非表示",27.5,0),l={m:e(i,"モジュール",0,{min:10,max:200,value:40,step:1}),alpha:e(i,"圧力角",1,{min:10,max:32,value:20,step:1}),z:e(i,"歯数A",2,{min:4,max:200,value:19,step:1}),shift:e(i,"転位A",3,{min:-.5,max:2,value:0,step:.05}),z2:e(i,"歯数B",4,{min:4,max:200,value:6,step:1}),shift2:e(i,"転位B",5,{min:-.5,max:2,value:0,step:.05}),fillet:e(i,"フィレット",6,{min:0,max:.4,value:.4,step:.01}),backlash:e(i,"バッ
クラッシュ",7,{min:0,max:2,value:0,step:.01}),velocity:e(i,"速度",8,{min:-1,max:10,value:1,step:.1}),theta:e(i,"回転角",9,{min:-180,max:180,value:0,step:.05}),df:n(i,"歯底円",10.5,0,!1),db:n(i,"基礎円",10.5,1,!1),dp:n(i,"基準円",10.5,2,!0),dk:n(i,"歯先円",10.5,3,!1),play:n(i,"自動更新",11.5,0,!0),connection:n(i,"接続点",11.5,1,!1),inner:n(i,"内歯車",11.5,2,!1),stop:!1};return t.forEach*1e,n)=>{e.style("opacity","0.2"),e.mouseOver*2)=>t.forEach(t=>t.style("opacity","1"(#notefoot_2)),e.mouseOut*3)=>t.forEach(t=>t.style("opacity","0.2"(#notefoot_3))}),l.theta.mousePressed*4)=>{l.stop=!0}),l.theta.mouseReleased*5)=>{l.stop=!1}),r.elt.onchange=()=>{t.forEach*6t,e)=>{e<2||(r.checked()?t.hide():t.show((#notefoot_6)})},{get m(){return Number(l.m.value((#notefoot_5)},get alpha(){return Number(l.alpha.value((#notefoot_4)/180*Math.PI},get z(){return Number(l.z.value(},get shift(){return Number(l.shift.value())*this.m},get z2(){return Number(l.z2.value())},get shift2(){return Number(l.shift2.value())*this.m},get theta(){return-(Number(l.theta.value())/180)*Math.PI},set theta(value){l.theta.value(-(180*value)/Math.PI),l.theta.elt.oninput()},get fillet(){return Number(l.fillet.value())*this.m},get mk(){return+this.m},get mf(){return 1.25*this.m},get backlash(){return Number(l.backlash.value())/100*2*Math.PI/this.z},get play(){return l.play.checked()&&!l.stop},get velocity(){return Number(l.velocity.value())/180*Math.PI},get df(){return l.df.checked()},get db(){return l.db.checked()},get dp(){return l.dp.checked()},get dk(){return l.dk.checked()},get connection(){return l.connection.checked()},get inner(){return l.inner.checked()}}}(i)},i.draw=()=>{var t,e,n;let h;let{ox:u,oy:d}=l;i.background(220);let{gear1:g,gear2:x}=(t=r,h=null!==c?Object.keys(e=c).filter(n=>t[n]!==e[n]):[],(!f||h.filter(t=>!["m2","shift2"].includes(t)).length>0)&&(f=o(t)),(!m||h.filter(t=>!["m","shift","inner"].includes(t)).length>0)&&(m=o({...t,z:t.z2,shift:t.shift2,inner:!1})),n=t,c=["m","z","alpha","shift","z2","shift2","fillet","backlash","inner"].reduce*7t,e)=>(t[e]=n[e],t),{}),{gear1:f,gear2:m});r.play&&(r.theta-r.velocity<-Math.PI?r.theta+=-r.velocity+2*Math.PI:r.theta+=-r.velocity),s(i,g,r.inner?u+r.m*r.z/2-r.shift:u-r.m*r.z/2-r.shift,d,r.inner?r.theta/r.z+Math.PI+Math.PI/r.z:-r.theta/r.z,r.connection,r.inner?r.m*(5+r.z)/2+r.shift:0),s(i,x,u+r.m*r.z2/2+r.shift2,d,r.theta/r.z2+Math.PI+Math.PI/r.z2,r.connection),a(i,r.inner?u+r.m*r.z/2-r.shift:u-r.m*r.z/2-r.shift,d,r),a(i,u+r.m*r.z2/2+r.shift2,d,{...r,z:r.z2,shift:r.shift2})};let s=(t,e,n,i,r=0,l=!1,s=0)=>{t.strokeWeight(1),t.stroke("black"),t.fill("white"),s&&(t.circle(n,i,2*s),t.fill(220,t.beginShape(),e.curve.forEach(e=>{t.vertex(n+e[0]*Math.cos(e[1]+r),i+e[0]*Math.sin(e[1]+r))}),t.endShape("close"),l&&e.connections.forEach(e=>{t.circle(n+e[0]*Math.cos(e[1]+r),i+e[0]*Math.sin(e[1]+r),2)})},a=(t,e,n,i)=>{let{df:r,db:l,dp:s,dk:a,m:h,z:o,mk:u,mf:c,alpha:f,shift:m}=i;t.strokeWeight(1),t.stroke("Blue"),t.noFill(),t.drawingContext.setLineDash([2,6]),r&&t.circle(e,n,(h*o/2-c+m)*2),l&&t.circle(e,n,h*o*Math.cos(f)),s&&t.circle(e,n,h*o),a&&t.circle(e,n,(h*o/2+u+m)*2),t.drawingContext.setLineDash([])}})(p);
内歯車について:
- インボリュート曲線部分のみで歯形としている
- フィレットは付けていない
- 内歯車の転位には対応していない
- どうやら逆向きに動かしてしまっている??? ← TODO
はすば歯車設計†
LANG:p5js_live function input(i, label, value, func) { p.createSpan(label).position(0, 26 * i + 10); myInput = p.createInput(value).position(150, 26 * i + 10); if (func) { myInput.input(func); } else { myInput.elt.disabled = true; } return myInput; } const inputs = {}; const recalc = () => { inputs.pitch.value(inputs.m.value() * Math.PI); inputs.mn.value( inputs.m.value() / Math.cos((inputs.beta.value() / 180) * Math.PI) ); inputs.pitchn.value(inputs.mn.value() * Math.PI); inputs.dp.value(inputs.mn.value() * inputs.z.value()); } p.setup = () => { p.createCanvas(300,240) inputs.m = input(1, "歯直角モジュール", 4, recalc); inputs.z = input(2, "歯数", 12, recalc); inputs.beta = input(3, "ねじれ角", 0, recalc); inputs.pitch = input(5, "歯直角ピッチ", 0); inputs.mn = input(6, "正面モジュール", 4); inputs.pitchn = input(7, "正面ピッチ", 0); inputs.dp = input(8, "基準円直径", 0); recalc(); }
ウォームギア設計†
LANG:p5js_live function input(i, label, value, func) { p.createSpan(label).position(0, 20 * i + 10); myInput = p.createInput(value).position(150, 20 * i + 10); if (func) { myInput.input(func); } else { myInput.elt.disabled = true; } return myInput; } const inputs = {}; function recalc() { inputs.beta.value(Math.asin(inputs.n.value() * inputs.m.value() / inputs.dp.value())/Math.PI*180) inputs.pitch.value(inputs.m.value() * Math.PI); inputs.mn.value( inputs.m.value() / Math.cos((inputs.beta.value() / 180) * Math.PI) ); inputs.pitchn.value( Math.PI * inputs.mn.value() ); inputs.vdp.value( inputs.dp.value()/Math.sin(inputs.beta.value()/180*Math.PI) ) } p.setup = () => { p.createCanvas(300,240) inputs.m = input(1, "歯直角モジュール", 4, recalc); inputs.dp = input(2, "基準円直径", 30, recalc); inputs.n = input(3, "条数", 1, recalc); inputs.pitch = input(5, "歯直角ピッチ", 0); inputs.beta = input(6, "ねじれ角", 0); inputs.mn = input(7, "正面モジュール", 4); inputs.pitchn = input(8, "正面ピッチ", 0); inputs.vdp = input(9, "仮想基準円直径", 0) recalc(); }
*1 e,n)=>{e.style("opacity","0.2"),e.mouseOver*2)=>t.forEach(t=>t.style("opacity","1"),e.mouseOut*3)=>t.forEach(t=>t.style("opacity","0.2")}),l.theta.mousePressed*4)=>{l.stop=!0}),l.theta.mouseReleased*5)=>{l.stop=!1}),r.elt.onchange=()=>{t.forEach*6t,e)=>{e<2||(r.checked()?t.hide():t.show((#notefoot_6)})},{get m(){return Number(l.m.value((#notefoot_5)},get alpha(){return Number(l.alpha.value(/180*Math.PI},get z(){return Number(l.z.value(
*2 )=>t.forEach(t=>t.style("opacity","1"
*3 )=>t.forEach(t=>t.style("opacity","0.2"
*4 )=>{l.stop=!0}),l.theta.mouseReleased*5)=>{l.stop=!1}),r.elt.onchange=()=>{t.forEach*6t,e)=>{e<2||(r.checked()?t.hide():t.show((#notefoot_6)})},{get m(){return Number(l.m.value(},get alpha(){return Number(l.alpha.value(
*5 )=>{l.stop=!1}),r.elt.onchange=()=>{t.forEach*6t,e)=>{e<2||(r.checked()?t.hide():t.show(})},{get m(){return Number(l.m.value(
*6 t,e)=>{e<2||(r.checked()?t.hide():t.show(
*7 t,e)=>(t[e]=n[e],t),{}),{gear1:f,gear2:m});r.play&&(r.theta-r.velocity<-Math.PI?r.theta+=-r.velocity+2*Math.PI:r.theta+=-r.velocity),s(i,g,r.inner?u+r.m*r.z/2-r.shift:u-r.m*r.z/2-r.shift,d,r.inner?r.theta/r.z+Math.PI+Math.PI/r.z:-r.theta/r.z,r.connection,r.inner?r.m*(5+r.z)/2+r.shift:0),s(i,x,u+r.m*r.z2/2+r.shift2,d,r.theta/r.z2+Math.PI+Math.PI/r.z2,r.connection),a(i,r.inner?u+r.m*r.z/2-r.shift:u-r.m*r.z/2-r.shift,d,r),a(i,u+r.m*r.z2/2+r.shift2,d,{...r,z:r.z2,shift:r.shift2})};let s=(t,e,n,i,r=0,l=!1,s=0)=>{t.strokeWeight(1),t.stroke("black"),t.fill("white"),s&&(t.circle(n,i,2*s),t.fill(220