Estudo dos Pontos de Contato (engrenagens de dente reto)

Pontos de Contato
Iremos fazer um círculo nos pontos de contado entre duas engrenagens de dente reto para realçar esses contatos.
O raciocínio é fazer primeiro um código bem simples que acha os pontos iguais para depois utilizá-lo no código que criar as duas engrenagens acopladas.

Código Simples
A lista pts1 representa os pontos da primeira engrenagem e a lista pts2 representa os pontos da segunda engrenagem.
As duas lista possuem uma sequência de pontos com coordenadas x e y em uma sequência imediata, ou seja, (x1,y1,x2,y2,x3,y3...), por isso o contador do laço for é incrementado em 2 a cada ciclo.

Código iguais.html:
<html lang="pt_BR">
<head>
<meta charset="utf-8">
</head>
<body>
<script>
function ptiguais() {
pts1=[20,30,40,50,60,70,80,90,100,110];
pts2=[80,90,100,110,120,130,140,150,160,170];
iguais=[];
   for(i=0;i<=pts1.length-1;i=i+2){//pega cada "x" com indices 0, 2, 4,... e cada "y" com índices 1, 3, 5, ... de pts1
      for(j=0;j<=pts2.length;j=j+2){//pega cada "x" com indices 0, 2, 4,... e cada "y" com índices 1, 3, 5, ... de pts2
         if((pts1[i]==pts2[j])&&(pts1[i+1]==pts2[j+1])){//se "x" e "y" são iguais em pts1 e pts2
            iguais.push(pts1[i]);//iguais recebe "x" iguais
            iguais.push(pts1[i+1]);//iguais recebe "y" iguais
         }
      }

   }
   for(i=0;i<=4;i=i+2){//impressão na tela, só dois pontos por vez devido sobrecarga de memoria
      document.writeln("x = "+iguais[i]+"<br>");
      document.writeln("y = "+iguais[i+1]+"<br>");
   }
}
ptiguais();
</script>
</body>
</html>

Resultado:
x = 80
y = 90
x = 100
y = 110

Implementação no Código
Devemos implementar o código que cria duas engrenagens acopladas com o código abaixo que é incluido na função setInterval(), porém, antes disso devemos arrendondar os valores das coordenadas dos pontos com a função parseFloat() afim de que facilite a igualdade de tais coordenadas.

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

iguais=[];
for(i=0;i<=pts1.length-1;i=i+2){//pega a cada ciclo "x" com indices 0, 2, 4,... e "y" com índices 1, 3, 5, ... de pts1

      for(j=0;j<=pts2.length;j=j+2){//pega a cada ciclo "x" com indices 0, 2, 4,... e "y" com índices 1, 3, 5, ... de pts2
         if((pts1[i]==pts2[j])&&(pts1[i+1]==pts2[j+1])){//se "x" e "y" são iguais em pts1 e pts2
            iguais.push(pts1[i]);//iguais recebe "x" iguais
            iguais.push(pts1[i+1]);//iguais recebe "y" iguais
         }
      }

   }

   for(i=0;i<=iguais.length;i=i+2){// desenho dos pontos iguais
      if ((typeof iguais[i] !=='undefined')&&(typeof iguais[i+1] !=='undefined')) {//eliminar o erro undefined
          var cir4 = document.createElementNS(xmlns, "circle");
          cir4.setAttributeNS(null,'cx', iguais[i]);//coordenada-x do centro
          cir4.setAttributeNS(null,'cy', iguais[i+1]);//coordenada-y do centro
          cir4.setAttributeNS(null,'r',0.5);//raio do circulo interno igual a ri-40 escolhido aleatoriamente
          cir4.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
          cir4.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
          cir4.setAttributeNS(null,'id','id4');
          svg.appendChild(cir4);//adicionar o circulo no documento
          svg.appendChild(pol1);//adicionar a polylinha no documento
          svg.appendChild(pol2);//adicionar a polylinha no documento
      }
   }

IMPORTANTE: só após todos os cálculos serem feito é que os elementos (polylinhas e pontos) são inseridos no SVG. Isso é feito para tentar desenhar tudo o mais rápido possível.

O código completo se encontra logo abaixo. Devido a quantidade de cálculos o código é muito lendo. No windows é mais lento ainda.

A tabela abaixo cria duas engrenagens acopladas e destaque os pontos de contado entre os dentes.


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âmettro 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âmettro de cabeça


da = dp+2.ha
Passo em ângular


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 completo:
<!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 = parseFloat(h+xx*Math.cos(gg) - yy*Math.sin(gg)).toFixed(1);//gg angulo de rotacao dos pontos
this.yy = parseFloat(k+xx*Math.sin(gg) + yy*Math.cos(gg)).toFixed(1);
}

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);

var cir4 = document.createElementNS(xmlns, "circle");
    cir4.setAttributeNS(null,'id','id4');
    svg.appendChild(cir4);

setInterval(function(){
iguais=[];
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', '0.5px');//formata a espessura da linha
    pol1.setAttributeNS(null,'stroke', 'red');
    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', '0.5px');//formata a espessura da linha
    pol2.setAttributeNS(null,'stroke', 'blue');
    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  


   for(i=0;i<=pts1.length-1;i=i+2){//pega a cada ciclo "x" com indices 0, 2, 4,... e "y" com índices 1, 3, 5, ... de pts1
      for(j=0;j<=pts2.length;j=j+2){//pega a cada ciclo "x" com indices 0, 2, 4,... e "y" com índices 1, 3, 5, ... de pts2
         if((pts1[i]==pts2[j])&&(pts1[i+1]==pts2[j+1])){//se "x" e "y" são iguais em pts1 e pts2
            iguais.push(pts1[i]);//iguais recebe "x" iguais
            iguais.push(pts1[i+1]);//iguais recebe "y" iguais


         }
      }

   }

   for(i=0;i<=iguais.length;i=i+2){// desenho dos pontos iguais
     if ((typeof iguais[i] !=='undefined')&&(typeof iguais[i+1] !=='undefined')) {//eliminar o erro undefined
       var cir4 = document.createElementNS(xmlns, "circle");
       cir4.setAttributeNS(null,'cx', iguais[i]);//coordenada-x do centro
       cir4.setAttributeNS(null,'cy', iguais[i+1]);//coordenada-y do centro
       cir4.setAttributeNS(null,'r', 0.5);//raio do circulo interno igual a ri-40 escolhido aleatoriamente
       cir4.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
       cir4.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
       cir4.setAttributeNS(null,'id','id4');
       svg.appendChild(cir4);//adicionar o circulo no documento
       svg.appendChild(pol1);//adicionar a polylinha no documento
       svg.appendChild(pol2);//adicionar a polylinha no documento
    }
   }

},200);


//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>


Análise:
1) Cada dente pode ter no máximo dois pontos de contato com o dente da outra engrenagem. É perceptível na execução do código que há mais de dois pontos de contato em um dente acoplado, uma das razões para esse erro é que um dente com o perfil evolvental faz contato com outro dente com perfil reto. O perfil reto do dente corresponde a distância "x" entre o circulo interno e o começo da evolvente.
Uma alternativa é não usar a distância "x" e diminuir a altura do dente, porém manter a mesma distância entre os centros. Neste caso o círculo interno pode simplesmente interceptar o início da evolvente.
2) A simulação da rotação entre as duas engrenagens acopladas foi feita criando uma rotação diferente para ambas. Uma simulação mais realistica envolveria o estudo das forças atuantes no sistema e a engrenagem motora empurraria a engrenagem movida.
3) Com os códigos desenvolvidos até aqui é possível estudar e testar as propriedades da engrenagem de dente reto. Outro desafio é a construção de engrenagens em três dimensões. O ideal é fazer isso com um código puro em javascript.