Programa para Desenhar Duas Engrenagens de Dentes Retos Acopladas e Rotacionando


O código está comentado e há mais orientações abaixo. É uma implementação do código que criou uma engrenagem de dente reto em SVG rotacionando. Realize alguns testes conforme indicação abaixo. Refaça todo o código passo a passo para entendê-lo. Leia, estude, assimile e realize bastantes testes, só assim entenderá e conseguirá melhorar o código.

Testes: Clique no botão Desenhar. Observe o desenho. Clique no botão Recarregar Página e depois no Botão Limpar Campos. Entre com dados "compatíveis" e clique no botão Desenhar.
O SVG possui 250mm de largura por 150mm de altura (1mm=4pixel):Entrada de dados em MILIMETROS
Engrenagem Dente Reto
Motora
Movida

Módulo
Módulo: m = dp/z
Ângulo de pressão:

φ
Diâmetro primitivo dp = m.z
Diâmetro de cabeça


dcmáx=rb/cos(π/2.z)
Centro(x,y) do SVG: (125,75)
:x :x

:y :y


Número de Dentes

z = dp/m (inteiro)
Diâmetro de base


db = dp.cosφ
Diâmetro interno errado (teórico)


di = dp - 2.hf
Diâmetro interno otimizado (tangente ao chanfro)


dio=2ri
Diâmetro de cabeça


da = dp+2.ha
Passo em ângulo


p=2.π/z
Altura do pé do dente:

hf = 1,25.m
Altura comum do dente:

hc = 2.m
Altura total do dente:


ht = 2,25.m
Vão entre os dentes no primitivo:

e = p/2
Folga da cabeça:


j = 0,2.m
β: metade vão na base. Obs:(β+ α=90º)

β= (p - giro)/2
Raio do chanfro certo


r
Distância x


x

Código: está comentado
<!DOCTYPE html>
<html lang="pt_BR"><head>
<meta charset="UTF-8">
<style>
body{
font-family: Arial;
font-size: 24px;
line-height: 28px;
text-align:justify;
text-indent:0px
magin-left:4px;
magin-right:4px;
}

table{
white-space: nowrap;
font-size: 20px;
line-height: 20px;
border:1px solid black;
border-collapse:collapse;
white-space: nowrap;"
}
  </style>

</head>
<body>
<svg version="1.1" baseprofile="full" xmlns="http://www.w3.org/2000/svg" width="1000px" height="600px" stroke="black" stroke-width="0.5px" id="id1" viewbox="0 0 1000  600" style="border: 1px solid rgb(0, 0, 0);">
<script type="application/ecmascript"><![CDATA[

var svg=document.getElementById("id1");
var xmlns="http://www.w3.org/2000/svg";


function criar(dp,m,cx,cy,gg,pts,vai) {//funcao classe
//1mm sera considerado igual a 4pixels
var cc=0;//importantíssimo para o início de cada dente apartir do dente anterior
this.dp=dp;
this.m=m;
this.cx=cx;
this.cy=cy;
this.gg=gg;
this.pts=pts;


var h = 4*cx;//1milimetro está sendo igualado a 4px
var k = 4*cy;

 z=dp/m;
a = parseFloat(document.getElementById("idselect2").value);
db = dp*Math.cos(a);
p=(2*Math.PI)/z;
hc = m;
hf = 1.25*m;
ht = hf+hc;
di = dp-2*hf;
dc = (dp+2*hc);
rb = (db*4)/2;
rc = (dc*4)/2;
rp = (dp*4)/2;
ri = (di*4)/2;//fora da função avai

ψ2 = Math.acos(rb/rp);
θ2 = Math.tan(ψ2) - ψ2;//evolvente até o primitivo
giro = (p/2) + (2*θ2);//ângulo do arco de base


ψ = Math.acos(rb/rc);
θ = Math.tan(ψ) - ψ;//evolvente até  o circulo de cabeça

β = (p/2 - 2*θ2)/2;//é utilizado para achar o ângulo do arco de chanfro
re=rb*Math.tan(β);
rie = re*(1- Math.sin(β))/Math.sin(β);


if(rie>=ri){
r=(ri*Math.sin(β))/(1-Math.sin(β));
x=Math.cos(β)*(rie-ri-r+re);
}else{
ri=rie;
r=re;
x=0;
}


var step = 2*Math.PI/1000;//passo da angulo beta para a polyline formar as curvas

//seguimento PoP1 sera feito automaticamente pela polyline que une o arco de chanfro com a evolvente

 
//as variáveis dentro da função serão inicializadas a cada nova execução da função

function Point2D(xx,yy) {//funcao com dois argumentos iguais as respectivas variaveis
//todos os pontos serão rotacionados e centralizados
this.xx = h+xx*Math.cos(gg) - yy*Math.sin(gg);//gg angulo de rotacao dos pontos
this.yy = k+xx*Math.sin(gg) + yy*Math.cos(gg);
}


this.vai=function(){ //função para criação dos pontos e preenchimento da lista pts, cada nova execução da função uma nova inicialização de variáveis


  var coord = new Array();//variavel tipo objeto de lista para os pontos do desenho
  pp=0;// impotantissimo é o angulo de rotação para formar os demais dentes depois do primeiro, a primeira rotação é zero as demais é p acumuladamente a cada ciclo
  rr1=0;//importantiissimo, contador cumulativo de ciclo do loop for que preenche a llista pts, para cada ciclo rr1 é igual a rr+1 mais 1 
   
for(i=0;i<z;i=i+1){// loop de repetiçao da criação dos dentes primeiro ciclo rr é igual a zero, demais ciclos é p acumuladamente a cada ciclo

//arco2 do pe do dente rotacionado

for(beta=(Math.PI/2+Math.atan((rb-x)/r));beta>=(Math.PI)/2;beta=beta-step){
rr1=rr1+1;
   var xa =  rb-x+r*Math.cos(beta);//coordenada-x do arco2
   var ya = -r+r*Math.sin(beta);//coordenada-y do arco2
   var xag = (xa*Math.cos(-giro+pp) - ya*Math.sin(-giro+pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p                   
   var yag = (xa*Math.sin(-giro+pp) + ya*Math.cos(-giro+pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p
 
   coord.push(new Point2D(xag,yag));//preechnimento da lista com objetos (Point2D) indices de 0 a rr1-1
}
 
for(c=cc;c<rr1;c=c+1){ //loop com contador c igual ao numero de step (passos) para cada ciclo rr1 é igual a c mais 1
     pts.push(coord[c].xx);//lista dos pontos do arco2 do pe do dente
     pts.push(coord[c].yy);
}

//evolvente2 e rotacao
rr2=rr1; //contador de ciclo do loop é o próximo indice depois de rr1-1
for(beta=0;beta<=Math.tan(Math.acos(rb/rc));beta+=step){ //loop de preenchimento
    rr2=rr2+1;
     var xb=rb*Math.cos(beta)+rb*beta*Math.sin(beta);//coordenada-x da evolvente
     var yb=rb*Math.sin(beta)-rb*beta*Math.cos(beta);//coordenada-y da evolvente no sistema da tela
     var xbg = (xb*Math.cos(-giro+pp) - yb*Math.sin(-giro+pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p               
     var ybg = (xb*Math.sin(-giro+pp) + yb*Math.cos(-giro+pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p
     coord.push(new Point2D(xbg,ybg));//preechimento da lista com objetos (Point2D)
}

for(c=rr1;c<rr2;c=c+1){ //loop para preenchimento da lista com indice de rr1 a rr2-1
       pts.push(coord[c].xx);//lista acumulada
       pts.push(coord[c].yy);  
}

// arco de cabeca

a2 = giro - θ;//angulo do arco de cabeca

rr3=rr2;//contador de ciclo do loop
for(beta=θ;beta<=a2;beta=beta+step/10){
rr3=rr3+1;
   var xc =  rc*Math.cos(beta);//coordenada-x do arco de cabrca
   var yc =  rc*Math.sin(beta);//coordenada-y do arco de cabeca
   var xcg = (xc*Math.cos(-giro+pp) - yc*Math.sin(-giro+pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p                  
   var ycg = (xc*Math.sin(-giro+pp) + yc*Math.cos(-giro+pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p
 
   coord.push(new Point2D(xcg,ycg));//preechimento da lista
}
 
for(c=rr2;c<rr3;c=c+1){ //loop com contador c igual ao numero de step (passos), indices de rr2 a rr3-1
     pts.push(coord[c].xx);//lista dos pontos do arco do pe do dente
     pts.push(coord[c].yy);
}


//evolvente1 tem que inverter a coordenadaY
rr4=rr3; //contador de ciclo do loop
for(beta=Math.tan(Math.acos(rb/rc));beta>=0;beta-=step){ //loop de preenchimento
    rr4=rr4+1;
     var xd=rb*Math.cos(beta)+rb*beta*Math.sin(beta);//coordenada-x da evolvente1
     var yd=-rb*Math.sin(beta)+rb*beta*Math.cos(beta);//coordenada-y invertida da evolvente2 no sistema da tela
     var xdg = (xd*Math.cos(pp) - yd*Math.sin(pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p                  
     var ydg = (xd*Math.sin(pp) + yd*Math.cos(pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p
    
     coord.push(new Point2D(xdg,ydg));//preechimento da lista com objetos (Point2D)

}
for(c=rr3;c<rr4;c=c+1){ //loop para preenchimento da lista, indices de rr3 a rr4-1
     pts.push(coord[c].xx);//lista acumulada
     pts.push(coord[c].yy);
}

//chanfro1 ou arco1
rr5=rr4;//contador de ciclo do loop for igual ao indice do array
for(beta=3*Math.PI/2;beta>=(3*Math.PI/2 - Math.atan((rb-x)/r));beta=beta-step){
rr5=rr5+1;
   var xe = rb-x+r*Math.cos(beta);//coordenada-x do arco1
   var ye = r+r*Math.sin(beta);//coordenada-y do arco1
   var xeg = (xe*Math.cos(pp) - ye*Math.sin(pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p                  
   var yeg = (xe*Math.sin(pp) + ye*Math.cos(pp)); //rotacao em zero graus para o primero ciclo, os demais cliclos a rootação é igual a p
 
   coord.push(new Point2D(xeg,yeg));//preechnimento da lista com objetos (Point2D) indices de rr1+rr2+rr3+rr4 a rr1+rr2+rr3+rr4+rr5-1
}
 
for(c=rr4;c<rr5;c=c+1){ //loop com contador c igual ao numero de step (passos)
     pts.push(coord[c].xx);//lista dos pontos do arco do pe do dente,indices de rr4 a rr5-1
     pts.push(coord[c].yy);
}
cc=rr5;//importantíssimo para criação do inicio de cada dente apartir do ultimo
rr1=rr5;//importantissimo a cada ciclo de repeticao o contador acumula-se e começa a fazer umnovo dente
pp=pp+p;//angulo pp mais o passo, depois do primeiro dente (pp igual a zero) a rotação dos pontos é igual a p cumulativamente

}//fecha o for de criação dos dentes

}//fecha vai

}//fecha função criar


function func1(){
//engrenagem 1
var dp1 = parseFloat(document.getElementById("ddp1").value);
var m1 = parseFloat(document.getElementById("dm1").value);
var cx1 = parseFloat(document.getElementById("dx1").value); //coordenada-x do centro da engrenagem
var cy1 = parseFloat(document.getElementById("dy1").value);//coordenada-y do centro da engrenagem

z1=dp1/m1;
var p1=(2*Math.PI)/z1;
var pts1=[];

a = parseFloat(document.getElementById("idselect2").value);
db1=dp1*Math.cos(a).toFixed(4);
rb1=db1/2;
rp1=dp1/2;
var ψ2 = Math.acos(rb1/rp1);
var θ2 = Math.tan(ψ2) - ψ2;//evolvente até o primitivo
var giro = (p1/2) + (2*θ2);//ângulo do arco de base
var gg1=giro/2;


var engr1 = new criar(dp1,m1,cx1,cy1,gg1,pts1);  // criação do objeto com seus atributos 
//criação da polilinha ou sequencia direta de pontos
engr1.vai();
//criação da polilinha ou sequencia direta de pontos
    var pol1 = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol1.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol1.setAttributeNS(null,'points',pts1);
    pol1.setAttributeNS(null,'id','id2');
    svg.appendChild(pol1);//adicionar a polylinha no documento  

document.getElementById("dz1").innerHTML=z;
document.getElementById("ddb1").innerHTML=db.toFixed(4);
document.getElementById("ddi1").innerHTML=di.toFixed(4);
document.getElementById("ddio1").innerHTML=di.toFixed(4) -2*x.toFixed(4);
document.getElementById("ddc1").innerHTML=dc.toFixed(4);
document.getElementById("dp1").innerHTML=p.toFixed(4);
document.getElementById("dhf1").innerHTML=hf.toFixed(4);
document.getElementById("dhc1").innerHTML=hc.toFixed(4);
document.getElementById("dht1").innerHTML=ht.toFixed(4);
document.getElementById("de1").innerHTML=(p/2).toFixed(4);
document.getElementById("dj1").innerHTML=(0.2*engr1.m).toFixed(4);
document.getElementById("db1").innerHTML=β.toFixed(4);
document.getElementById("dr1").innerHTML=r.toFixed(4);
document.getElementById("x1").innerHTML=x.toFixed(4);

//engrenagem 2
var dp2 = parseFloat(document.getElementById("ddp2").value);
var m2 = parseFloat(document.getElementById("dm2").value);
var cx2 = parseFloat(document.getElementById("dx2").value); //coordenada-x do centro da engrenagem
var cy2 = parseFloat(document.getElementById("dy2").value);//coordenada-y do centro da engrenagem
var pts2=[];

z2=dp2/m2;
p2=(2*Math.PI)/z2;

a = parseFloat(document.getElementById("idselect2").value);
db2=dp2*Math.cos(a).toFixed(4);
rb2=db2/2;
rp2=dp2/2;
var ψ2 = Math.acos(rb2/rp2);
var θ2 = Math.tan(ψ2) - ψ2;//evolvente até o primitivo
var giro = (p2/2) + (2*θ2);//ângulo do arco de base, metade do giro faz o primeiro dente ficar simétrico ao eixoX
g2=(p2/2+Math.PI);
var gg2=(giro/2)+g2;//acoplaamento do primeiro vão da segunda engrenagem no primeiro dente da primeira engrenagem
a = parseFloat(document.getElementById("idselect2").value);
document.getElementById("dz2").innerHTML=z2;
document.getElementById("ddb2").innerHTML=db2;
var engr2 = new criar(dp2,m2,cx2,cy2,gg2,pts2);  // criação do objeto com seus atributos
engr2.vai();
//criação da polilinha ou sequencia direta de pontos
    var pol2 = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol2.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol2.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol2.setAttributeNS(null,'points',pts2);
    pol2.setAttributeNS(null,'id','id3');
    svg.appendChild(pol2);//adicionar a polylinha no documento

document.getElementById("dz2").innerHTML=z;
document.getElementById("ddb2").innerHTML=db.toFixed(4);
document.getElementById("ddi2").innerHTML=di.toFixed(4);
document.getElementById("ddio2").innerHTML=di.toFixed(4) -2*x.toFixed(4);
document.getElementById("ddc2").innerHTML=dc.toFixed(4);
document.getElementById("dp2").innerHTML=p.toFixed(4);
document.getElementById("dhf2").innerHTML=hf.toFixed(4);
document.getElementById("dhc2").innerHTML=hc.toFixed(4);
document.getElementById("dht2").innerHTML=ht.toFixed(4);
document.getElementById("de2").innerHTML=(p/2).toFixed(4);
document.getElementById("dj2").innerHTML=(0.2*engr1.m).toFixed(4);
document.getElementById("db2").innerHTML=β.toFixed(4);
document.getElementById("dr2").innerHTML=r.toFixed(4);
document.getElementById("x2").innerHTML=x.toFixed(4);

setInterval(function(){  
var polilinha1 = document.getElementById('id2'); //remoção da polyline
var pai1 = polilinha1.parentNode;
pai1.removeChild(polilinha1);   

delete  engr1; //limpar o objeto da memoria
gg1=gg1+0.04; 
pts1=[]; 

var engr1 = new criar(dp1,m1,cx1,cy1,gg1,pts1);
engr1.vai();
    var pol1 = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol1.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol1.setAttributeNS(null,'points',pts1);
    pol1.setAttributeNS(null,'id','id2');
    svg.appendChild(pol1);//adicionar a polylinha no documento 

 
var polilinha2 = document.getElementById('id3'); //remoção da polyline
var pai3 = polilinha2.parentNode;
pai3.removeChild(polilinha2); 
delete  engr2; //limpar o objeto da memoria 
pts2=[];
gg2=gg2-(0.04*(dp1/dp2));      
var engr2 = new criar(dp2,m2,cx2,cy2,gg2,pts2);
engr2.vai();
    var pol2 = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol2.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol2.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol2.setAttributeNS(null,'points',pts2);
    pol2.setAttributeNS(null,'id','id3');
    svg.appendChild(pol2);//adicionar a polylinha no documento    
    
},400);


//circulo interno qualquer
    var cir1 = document.createElementNS(xmlns, "circle");
    cir1.setAttributeNS(null,'cx', 4*cx1);//coordenada-x do centro
    cir1.setAttributeNS(null,'cy', 4*cy1);//coordenada-y do centro
    cir1.setAttributeNS(null,'r', 4*rb1-50);//raio do circulo interno igual a ri-40 escolhido aleatoriamente
    cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
    cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    cir1.setAttributeNS(null,'id','idc1');   
    svg.appendChild(cir1);//adicionar o circulo no documento
   
    var cir2 = document.createElementNS(xmlns, "circle");
    cir2.setAttributeNS(null,'cx', 4*cx2);//coordenada-x do centro
    cir2.setAttributeNS(null,'cy', 4*cy2);//coordenada-y do centro
    cir2.setAttributeNS(null,'r', 4*rb2-50);//raio do circulo interno igual a ri-40 escolhido aleatoriamente
    cir2.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
    cir2.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    cir2.setAttributeNS(null,'id','idc2');   
    svg.appendChild(cir2);//adicionar o circulo no documento   
}//fecha func1
function limpar(){
    document.getElementById("ddp1").value=' ';
    document.getElementById("dm1").value=' ';
    document.getElementById("dz1").innerHTML=' ';
    document.getElementById("ddb1").innerHTML=' ';
    document.getElementById("dx1").value=' ';
    document.getElementById("dy1").value=' ';
   
    document.getElementById("ddp2").value=' ';
    document.getElementById("dm2").value=' ';
    document.getElementById("dz2").innerHTML=' ';
    document.getElementById("ddb2").innerHTML=' ';
    document.getElementById("dx2").value=' ';
    document.getElementById("dy2").value=' ';
}

function recarregar(){
    location.reload (true);
}



 ]]></script><br>
</svg><span style="font-weight: bold;">Testes</span>: Clique no bot&atilde;o <span style="font-weight: bold;">Desenhar</span>. Observe o desenho. Clique no
bot&atilde;o <span style="font-weight: bold;">Recarregar P&aacute;gina</span> e depois no Bot&atilde;o <span style="font-weight: bold;">Limpar
Campos</span>. Entre com dados "compat&iacute;veis" e clique no bot&atilde;o
<span style="font-weight: bold;">Desenhar</span>.<br>

<table style="background-color: rgb(204, 204, 204);" border="1" cellpadding="2" cellspacing="2">

  <tbody>
    <tr>
      <td colspan="4" rowspan="1">O SVG possui 250mm de largura por
150mm de altura (1mm=4pixel):Entrada de dados em MILIMETROS</td>
    </tr>
    <tr>
      <td>Engrenagem Dente Reto<br>
      </td>
      <td>Motora<br>
      </td>
      <td>Movida<br>
      </td>
      <td><br>
      </td>
    </tr>
    <tr>
      <td>M&oacute;dulo<br>
      </td>
      <td><input id="dm1" name="dm1" maxlength="10" autocomplete="off" value="4" type="text"></td>
      <td><input id="dm2" name="dm2" maxlength="10" autocomplete="off" value="4" type="text"></td>
      <td>M&oacute;dulo: m = dp/z<br>
      </td>
    </tr>
    <tr>
      <td>&Acirc;ngulo de press&atilde;o:
      <select id="idselect2">
      <option value="0.34906585">20&ordm;</option>
      <option value="0.43633231">25&deg;</option>
      <option value="0.52359877">30&ordm;</option>
      <option value="0.6108652">35&ordm;</option>
      <option value="0.6981317">40&deg;</option>
      </select>
      </td>
      <td><br>
      </td>
      <td> <br>
      </td>
      <td><span>&phi;</span></td>
    </tr>
    <tr>
      <form></form>
      <td>Di&acirc;mettro primitivo</td>
      <td><input id="ddp1" name="ddp1" maxlength="10" autocomplete="off" value="100" type="text"></td>
      <td><input id="ddp2" name="ddp2" maxlength="10" autocomplete="off" value="60" type="text"></td>
      <td>dp = m.z</td>
    </tr>
    <tr>
      <td>Di&acirc;metro de cabe&ccedil;a<br>
      </td>
      <td><span id="dcmax1"></span> <br>
      </td>
      <td><span id="dcmax2"></span><br>
      </td>
      <td><span>dcm&aacute;x=rb/cos(&pi;/2.z)</span></td>
    </tr>
    <tr>
      <td>Centro(x,y) do SVG: (125,75)<br>
      </td>
      <td><input id="dx1" name="dx1" maxlength="10" autocomplete="off" value="50" type="text">:x</td>
      <td><input id="dx2" name="dx2" maxlength="10" autocomplete="off" value="130" type="text">:x</td>
      <td><br>
      </td>
    </tr>
    <tr>
      <td>
      </td>
      <td><input id="dy1" name="dy1" maxlength="10" autocomplete="off" value="75" type="text">:y</td>
      <td><input id="dy2" name="dy2" maxlength="10" autocomplete="off" value="75" type="text">:y</td>
      <td><br>
      </td>
    </tr>
    <tr>
      <td><br>
      </td>
      <td><input style="border: 1px solid black;" id="enter" size="100" maxlength="100" name="" value="Desenhar" onclick="func1()" type="button"></td>
      <td><input style="border: 1px solid black;" id="enter" size="100" maxlength="100" name="" value="Recarregar Pagina" onclick="recarregar()" type="button"><br>
      </td>
      <td><input style="border: 1px solid black;" id="enter" size="100" maxlength="100" name="" value="Limpar Campos" onclick="limpar()" type="button"> </td>
    </tr>
    <tr>
      <td>N&uacute;mero de Dentes</td>
      <td><span id="dz1"></span><br>
      </td>
      <td><span id="dz2"></span><br>
      </td>
      <td><span><span></span></span>z = dp/m (inteiro)<br>
      </td>
    </tr>
    <tr>
      <td>Di&acirc;metro de base<br>
      </td>
      <td><span id="ddb1"></span> <br>
      </td>
      <td><span id="ddb2"></span><br>
      </td>
      <td><span>db = dp.cos&phi;</span></td>
    </tr>
    <tr>
      <td>Di&acirc;metro interno errado (te&oacute;rico)<br>
      </td>
      <td><span id="ddi1"></span> <br>
      </td>
      <td><span id="ddi2"></span><br>
      </td>
      <td>di = dp - 2.hf</td>
    </tr>
    <tr>
      <td>Di&acirc;metro interno otimizado (tangente ao chanfro)<br>
      </td>
      <td><span id="ddio1"></span> <br>
      </td>
      <td><span id="ddio2"></span><br>
      </td>
      <td>dio=2ri<br>
      </td>
    </tr>
    <tr>
      <td>Di&acirc;mettro de cabe&ccedil;a<br>
      </td>
      <td><span id="ddc1"></span> <br>
      </td>
      <td><span id="ddc2"></span><br>
      </td>
      <td>da = dp+2.ha</td>
    </tr>
    <tr>
      <td>Passo em &acirc;ngular<br>
      </td>
      <td><span id="dp1"></span> <br>
      </td>
      <td><span id="dp2"></span><br>
      </td>
      <td><span>p=2.&pi;/z</span></td>
    </tr>
    <tr>
      <td>Altura do p&eacute; do dente:</td>
      <td><span id="dhf1"></span> <br>
      </td>
      <td><span id="dhf2"></span><br>
      </td>
      <td>hf = 1,25.m</td>
    </tr>
    <tr>
      <td>Altura comum do dente:</td>
      <td><span id="dhc1"></span> <br>
      </td>
      <td><span id="dhc2"></span><br>
      </td>
      <td>hc = 2.m</td>
    </tr>
    <tr>
      <td>Altura total do dente:<span> </span><br>
      </td>
      <td><span id="dht1"></span> <br>
      </td>
      <td><span id="dht2"></span><br>
      </td>
      <td>ht = 2,25.m</td>
    </tr>
    <tr>
      <td>V&atilde;o entre os dentes no primitivo: </td>
      <td><span id="de1"></span> <br>
      </td>
      <td><span id="de2"></span><br>
      </td>
      <td>e<sub><span> </span></sub>= p/2</td>
    </tr>
    <tr>
      <td>Folga da cabe&ccedil;a:<span> </span><br>
      </td>
      <td><span id="dj1"></span> <br>
      </td>
      <td><span id="dj2"></span><br>
      </td>
      <td>j = 0,2.m</td>
    </tr>
    <tr>
      <td>&beta;: metade v&atilde;o na base. Obs:(&beta;+
&alpha;=90&ordm;) </td>
      <td><span id="db1"></span><br>
      </td>
      <td><span id="db2"></span><br>
      </td>
      <td>&beta;= (p - giro)/2<br>
      </td>
    </tr>
    <tr>
      <td>Raio do chanfro certo<br>
      </td>
      <td><span id="dr1"></span> <br>
      </td>
      <td><span id="dr2"></span><br>
      </td>
      <td>r<br>
      </td>
    </tr>
    <tr>
      <td>Dist&acirc;ncia<span> </span><span>x</span><br>
      </td>
      <td><span id="x1"></span> <br>
      </td>
      <td><span id="x2"></span><br>
      </td>
      <td>x<br>
      </td>
    </tr>
  </tbody>
</table>
</body>
</html>

Esquema do Engrenamento
- Centralização ou Posicionamento:


A velocidade de rotação das duas engrenagem terão o mesmo tempo marcado pela função setInterval().
Tempo: 400 (milissegundos) para as duas engrenagens.
Engrenagem 1 (motora):
Variação ângular
= 0.04 a cada 400 milissegundos
Ângulo inicial: gg1, ângulo de simetria em relação ao eixo-x do primeiro dente (ângulo inicial), assim o dente criado da primera engrenagem fica na horizontal simetricamente.
Velocidade ângular: gg1=gg1+0.04
Diâmetro primitivo: dp1

Engrenagem 2 (movida):
Ângulo inicial: gg2, ângulo que alinha o primeiro dente da segunda engrenagem na horizontal (giro/2), faz uma rotação de 180º (Math.PI) mais uma rotação igual a metade do passo ângular (p2/2). Assim, o primeiro vão da segunda engrenagem fica na horizontal e acoplado no primeiro dente da primeira engrenagem. As duas engrenagens ficam prontas para iniciarem a movimentação.
Variação ângular: 0.04.(dp1/dp2) a cada 400 milissegundos
A velocidade ângular da engrenagem movida tem sentido inverso da engrenagem motora.
Se dp1> dp2 => Velocidade Ângular = gg2 - 0.04.(dp1/dp2)
Se dp1< dp2 => Velocidade Ângular = gg2 - 0.04.(dp1/dp2)

As velocidades no ponto de contato devem ser iguais, por isso o ângulo de variação para a engrenagem movida é multiplicado por dp1/dp2 se dp1>dp2 ou multiplicada por dp1/dp2 se dp2>dp1. Isso acontece porque para um mesmo intervalo de tempo o comprimento do arco variado das duas engrenagens devem ser iguais.
O fator de multiplicaçao será sempre dpMotora/dpMovida.

Erros corrigidos com muitos testes:
- A rotação das duas engrenagem estava sendo feito separadamente cada uma com o uso da função setInterval() separadamente, isso gerou problemas pois a rotação de ambas ficava desincronizadas com o passar do tempo, além de outros problemas
- Vários erros ocorreram devido a não separação do código pertencente a classe criar() e os objetos criados com o operador new (engr1 e engr2). Uma classe faz as operações, os objeto são instâncias da classe, herdam as propriedades da classe, dão entrada com parâmetros que são passados para os argumentos herdados. Objetos podem ser criados e deletados, ocupam espaço na memória. Os objetos evitam a repetição de códigos.
- Erros decorrentes do mal posicionamentos de variáveis, ou seja, erro de escopo, visibilidade ou acesso da mesma.
- A rotação dos pontos estava sendo feita com valores muito alto, por exemplo gg1=10 e gg2 =20, isso cria um salto muito grande e causa a inversão de rotação, pois os ângulos estão em radianos. Agora está sendo utilizado gg1=gg1+0.04 e gg2=gg2-(0.04*(dp1/dp2));   

Orientação:
Faça um código bem simples que sirva de estrutura para o projeto. Implemente o código com uma parte por vez, assim fica mais fácil achar o erro. Teste muito.
O erro é de programação? O erro de de geometria analítica ou cálculo? O erro é de desenho técnico?

Etapa 10
Para a simulação do engrenamento foi utilizado o código da etapa 9 com algumas alterações. Para trabalhar com duas engrenagens no mesmo código foi utilizado o conceito de objeto na linguagem JavaScript. A função que faz o papel de classe é criar(), a função vai() faz os cálculos e as operações. Os objetos engr1 e engr2 herdam as propriedade da função classe e são utilizados para a entrada de dados.
Outro conceito utilizado aplamente até aqui é o de escopo, visibilidade ou acesso da variável. Se uma variável deve ser acessada por duas funções diferente, então ela deve ficar fora das duas funções e no mesmo escopo onde ambas se encontram. Lembrando que a função é quem cria o escopo interno a ela através do par de chaves {} do seu bloco.
O desenvolvimento de código mais complexo com a linguagem JavaScript é limitado devido a falta de tipificação (número, texto, global, privada) de variáveis e execução do código que é de cima para baixo.

Será primeiro testados alguns códigos bem mais simples para depois implementar o mesmo raciocínio no código da etapa 9.

O código abaixo possui a função classe criar() com os argumentos dp, m e vai. Tais argumentos são iguais as variáveis desta função com os mesmos nomes. A propriedade this deixa o escopo da sua variável no mesmo escopo da função quando ela for chamada com a entrada de dados, tais dados serão iguais as respectivas variáveis.
A propriedade this especifica o objeto atual como sendo fonte dos valores passados a função.
Parâmetro (entrada de dados) implementado com this significa que prevalece o escopo onde a função é  chamada (atual).
O operador new cria os objetos engr1 e engr2 que herdão as propriedades da função criar().
vai é um método que realiza operações.

Código 1:
Este código possui a função criar() com os argumentos dp e m, os objetos engr1 e engr2 herdam as propriedades da classe criar(), tais objetos são criados com o operador new. A função vai() realiza cálculos internamente.

<html lang="pt_BR">
<head>
<meta charset="utf-8">
</head>
<body>
<script>
function criar ( dp, m) { // três argumentos
  this.dp = dp;  // as duas propriedade são declaradas como iguais aos argumentos
  this.m = m;
 
  function vai () {
    z=dp/m;
    c= a+b;
    }
    vai();
}

dp=50;//parâmetros de entrada
m=2;
a=2;
b=3;

var engr1 = new criar(dp,m);  // criação do objeto com seus atributos

document.writeln("Diâmetro primitivo: "+engr1.dp +"</br>");
document.writeln("Módulo: "+engr1.m+"</br>");
document.writeln("Número dentes: "+z+"</br>");
document.writeln("a + b = "+c+"</br>"+"</br>");

dp=100;//parâmetros de entrada
m=10;
a=10;
b=3;

var engr2 = new criar(dp,m);  // criação do objeto com seus atributos

document.writeln("Diâmetro primitivo: "+engr2.dp +"</br>");
document.writeln("Módulo: "+engr2.m+"</br>");
document.writeln("Número dentes: "+z+"</br>");
document.writeln("a + b = "+c+"</br>");

</script>
</body>
</html>

Resultado:
Diâmetro primitivo: 50
Módulo: 2
Número dentes: 25
a + b = 5

Diâmetro primitivo: 100
Módulo: 10
Número dentes: 10
a + b = 13

Código 2:
Este código possui vantagem em relação ao anterior, o código abaixo possui o método vai que é capaz de fazer cálculos com os parâmetros de entrada e ainda ser propriedade de objetos e assim pode ser chamado como uma função após a criação de um objeto. O código abaixo foi escolhido como base para o código que desenha as duas engrenagens.

<!DOCTYPE html>
<html lang="pt_BR">
<head>
<meta charset="utf-8">
</head>
<body>
<script>


var criar=function(dp,m,vai) { // três argumentos
this.dp = dp;  // as tres propriedade são declaradas como iguais aos argumentos
this.m = m;
this.vai = function() {
    z=dp/m;
    c=a+b;
    }
p=2*m;
}

dp=50;
m=5;
a=2;
b=3;

var engr1 = new criar(dp,m);  // criação do objeto com seus atributos
engr1.vai();
document.writeln("Dâmetro primitivo: "+engr1.dp +"</br>");
document.writeln("Módulo: "+engr1.m+"</br>");
document.writeln("Número dentes: "+z+"</br>");
document.writeln("a + b= "+c+"</br>");
document.writeln("p= "+p+"</br>");

dp=100;
m=2;
a=10;
b=3;

var engr2 = new criar(dp,m);  // criação do objeto com seus atributos
engr2.vai();
document.writeln("Diâmetro primitivo: "+engr2.dp +"</br>");
document.writeln("Módulo: "+engr2.m+"</br>");
document.writeln("Número dentes: "+z+"</br>");
document.writeln("a + b= "+c+"</br>");
document.writeln("p= "+p+"</br>");

</script>
</body>
</html>

Resultado:
Dâmetro primitivo: 50
Módulo: 5
Número dentes: 10
a + b= 5
p= 10
Diâmetro primitivo: 100
Módulo: 2
Número dentes: 50
a + b= 13
p= 4

Observe que um objeto acessa todas as variáveis da função que serve como classe para sua criação.