Engrenagem de Dente Reto com SVG


Será desenhado uma engrenagem de dente reto em SVG da mesma forma que foi desenhado um engrenagem de dente reto utilizando o CANVAS do HTML5, será feito as devidas alterações decorrentes da diferença de regras entre ambas as linguagens.

Após a criação de uma evolvente e o círculo base com apenas uma elemento polyline a próxima etapa será a criação de um círculo interno com o elemento <circle>, um cículo de base e a evolvente com apenas uma <polyline>, um seguimento de reta com um <line> e a criação de um circulo de chanfro com um <circle>. A cada nova etapa o código SVG será aprimorado para a criação do desenho da engrenagem de dente reto.

O polyline cria várias linhas retas sequencialmente, um ponto após o outro, portanto tome cuidado para não emendar vários pontos pertencentes a partes diferentes. As curvas foram feitas com linhas retas muito pequenas.

O chanfro ou arco do pé do dente será formado com apenas um furo. Engrenagens "grandes" o melhor é fazer dois furos, um para cada chanfro no pé do dente. Na verdade a escolha por fazer um ou dois furos para o chanfro depende do tamanho da broca, que depende do tamanho da máquina.
Entendendo como desenhar uma engrenagem com apenas um furo no pé do dente para formar os dois chanfros do vão será bem mais fácil modificar o desenho.
O diâmetro interno ou diâmetro do pé do dente pode ser diminuido sem alterar o engrenamento. Para ocorrer o engrenamento o vão de uma engrenagem tem que se encaixar na cabeça do dente da outra engrenagem.
A engrenagem é uma peça que requer boa precisão, seu desenho deve ser detalhado e bem calculado.

O desenho sera feito com o sistema de coordenadas da tela, a primeira evolvente é obtida da segunda com a inversão do sinal das coordenadas do eixo-y do desenho, essa inversão é a mesma utilizada para gráficos simétricos ao eixo-x.

Será feito primeiro o arco de chanfro2 e sua rotação (-giro+pp), segundo a evolvente2 e sua rotação (-giro+pp), terceiro o arco de cabeça e sua rotação (-giro+pp), quarto a evolvente1, sua inversão e sua rotação (pp) e por fim, o arco de chanfro1 e sua rotação (pp). Os pontos da polyline devem ser gerados nessa sequência, no sentido horário, um ponto imediatamente após o outro porque a polyline junta o último ponto de uma sequência com o primeiro ponto da nova sequência. Cada sequência corresponde a um trecho do desenho (arco de chanfro2, evolvente2, etc).

Será empregado o termo circunferência e círculo como sinônimos, embrora circunferência seja formada por pontos equidistante de seu centro e círculo seja formado por todos os pontos delimitados pela circunferência.

Etapa 2: Desenho da evolvente, de um seguimento de reta e do Círculo de Chanfro do Pé do Dente
Continuando a matéria sobre engrenagem de dente reto com SVG, depois da criação da evolvente o próximo passo será desenhar um segmento de reta tangente a evolvente e ao círculo de chanfro. Esse segmento garantirá que o vão de uma engrenagem se encaixará na cabeça do dente da outra engrenagem.
O círculo de chanfro deve ser tangente ao círculo interno (círculo do pé do dente).
Nesta fase não está sendo considerado o dimensionamento do dente.
Na figura1 abaixo os valores de ri, r e rb foram escolhidos aleatoriamente, porém compatíveis.

ri=60
rb=100
PoP1=20
r=(80² - 60²)/(2*60)
Obs: 80 obtido de 100-20

O objetivo é apenas desenhar a primeira evolvente, um seguimento de reta tangente a evolvente e ao círculo de chanfro que é tangete ao círculo interno.
O β DA FIGURA BAIXO NÃO É O MESMO DA FÓRMULA DA EVOLVENTE.


Figura1 (furo.jpg)
r: é o raio do círculo que faz o chanfro da evovlente1, esse circulo é tangente ao eixo-x em P1.
Po: é o início da evolvente1 e evolvente2.
P2: ponto de tangência entre o círculo de chanfro com o círculo interno.

Na figura2 abaixo é feito o cálculo do raio do círculo de chanfro.

Figura2 (evolvente4.jpg)
Obs: a evolvente2 terá um círculo de chanfro simétrico ao da evolvente1 em relação ao eixo-x, cuja fórmula é a mesma, mudando apenas o seu centro.

Centralização
: a translação dos pontos está sendo feita diretamente nas coordenadas com h e k para centralizar a figura no SVG. h = heigth/2 e k = width/2.

Arquivo para teste
arquivo.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<iframe width="410" height="410" src="engr1.svg" scrolling="no" frameborder="0"/><br>
</body>
</html>

Arquivo engr1.svg
O arquivo egr1.svg pode ser feito em um editor de texto simples.
O círculo de base tem basicamente o mesmo código que nos arquivos anteriores.
h e k fazem a centralização do desenho no SVG.

A fórmula cartesiana da evolvente é:
x = rb *( cosβ + β * senβ)
y = rb * (senβ - β * cos β)

Circulo Interno: feito com com a criação de um elemento circle
O seguimento de reta (PoP1): é igual a 20, feito com com a criação de um elemento line.
Circulo de Chanfro: feito com um elemento circle, raio igual a ((80*80)-(60*60))/(2*60).

Circulo de Base: é feito com um <polyline> o atributo fill tem de ser none para ter uma linha, assim, pol.setAttributeNS(null,'fill','none'). Os índices para apreencherem a lista pts são: c = 0, 1, 2, ...,999.
Preenchimento da lista pts:
pts=coord[0].xx+","+coord[0].yy;//primeiro ponto da lista pts
for(c=1;c<1000;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+", "+coord[c].xx+","+coord[c].yy;//lista dos pontos do circulo de base
}


Evolvente: é feita com a continuação da mesma polyline, o primeiro indice da lista pts é 1000. ESSE RACIOCÍNIO É IMPORTANTE PARA TRABALHAR COM A POLYLINE. Os índices para continuarem a apreencher a lista pts são: c = 1000, 1001, 1002, ...,1999. Não pode pular nenhum índice nem sobrepô-lo a outro índice.
Continuação do preenchimento da lista pts:
for(c=1000;c<=1999;c=c+1){
pts=pts+", "+coord[c].xx+","+coord[c].yy;//lista dos pontos do circulo de base
}
pol.setAttributeNS(null,'points',[pts]);

Arquivo: engr1.svg
<?xml version="1.0" standalone="no"?> <!--cabecalho-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="400" height="400" stroke="black" stroke-width="0.5px" id="id1">

<script type="application/ecmascript"><![CDATA[

document.addEventListener("DOMContentLoaded", function(event) {//O evento DOMContentLoaded sera acionado quando todo o HTML (apenas) foi completamente carregado e analisado
var h = 200;//translacao da coordenada-x, centralizar
var k = 200;//translacao da coordenada-y, centralizar

var xmlns="http://www.w3.org/2000/svg";
var step = 2*Math.PI/1000; //passo do angulo beta igual a mil partes

function Point2D(xx,yy) {//funcao com dois argumentos iguais as respectivas variaveis
this.xx = xx;
this.yy = yy;
}

//variavel tipo objeto de lista para os desenhos
var coord = new Array();
var c;//índice contador

//circulo interno
var cir1 = document.createElementNS(xmlns, "circle");//cria um circulo
cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
cir1.setAttributeNS(null,'r', 60);//raio do centro
cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento


//circulo de chanfro
var rr=((80*80)-(60*60))/(2*60);//raio de chanfro

var cir2 = document.createElementNS(xmlns, "circle");//cria um circulo
cir2.setAttributeNS(null,'cx', h+80);//coordenada-x do centro
cir2.setAttributeNS(null,'cy', k+rr);//coordenada-y do centro
cir2.setAttributeNS(null,'r', rr);//raio do centro
cir2.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
cir2.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir2);//adicionar o circulo no documento


//seguimento PoP1
var seg = document.createElementNS(xmlns, "line");//cria um seguimento de linha
seg.setAttributeNS(null,'x1', h+100);//coordenada-x do primeiro ponto
seg.setAttributeNS(null,'y1', k);//coordenada-y do primeiro ponto
seg.setAttributeNS(null,'x2', k+80);//coordenada-x do segundo ponto
seg.setAttributeNS(null,'y2', k);//coordenada-y do segundo ponto
seg.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
seg.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(seg);//adicionar o circulo no documento

//criação da polilinha ou sequencia direta de pontos
var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha

//"circunferência de base"
for(beta=0;beta<=2*Math.PI;beta+=step){ //primeiro ponto com angulo igual a zero
var xa = h + 100*Math.cos(beta);//coordenada-x do circulo
var ya = k + 100*Math.sin(beta);//coordenada-y do circulo
coord.push(new Point2D(xa,ya));//preechnimento da lista com objetos (Point2D) indices de 0 a 1000
}

pts=coord[0].xx+","+coord[0].yy;//tipo texto, primeiro ponto

for(c=1;c<1000;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+", "+coord[c].xx+","+coord[c].yy;//lista dos pontos do circulo de base
}

//evolvente
for(beta=0;beta<=2*Math.PI;beta+=step){ //loop de preenchimento
var xd=h+100*Math.cos(beta)+100*beta*Math.sin(beta);//coordenada-x da evolvente
var yd=-1*(k+100*Math.sin(beta)-100*beta*Math.cos(beta))+400;//coordenada-y da evolvente no sistema cartesiano
coord.push(new Point2D(xd,yd));//preecnimento da lista com objetos (Point2D)
}

for(c=1000;c<=2000;c=c+1){ //loop com contador 2 igual ao numero de step (passos) 1000 a 2000
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista acumulada

}

pol.setAttributeNS(null,'points',[pts]);
document.documentElement.appendChild(pol);//adicionar a polylinha no documento

});
]]></script>
</svg>


O iframe abaixo foi utilizado para incluir o arquivo engr1.svg na presente página.
<iframe style="border-style: solid; border-width: 1px;" width="410" height="410" src="imgsvg/engr1.svg" scrolling="no"/><br>

Também pode-se testar o arquivo engr1.svg com um link como uma página HTML.
Link para engr1.svg

Obs: ao trabalhar com JavaScript e HTML a execução do código é feita de cima para baixo, essa e a característica da linguagem de marcação. Ou seja, o código não consegue usar uma variável antes da sua atribuição.
Exemplo errado:
var x = 2*y;
var y =2;
Exemplo certo:
var y=2;
var x = 2*y;

Obs: expressões de matemática em JavaScript são feitas com o uso dos parentesis (). Sequência de multiplicação ou divisão com soma ou subtração devem ser separadas por parentisis. Exemplo:
var x = (5*2) + 4;
var x = (2*(5+2)) + 1;

Etapa 3
: Desenho da Evolvente, de um Seguimento de Reta e do Arco de Chanfro do Pé do Dente
Devemos substituir o círculo de chanfro pelo arco de chanfro.

Pé do Dente
Opção1 (não será utilizada, pode pular): com o elemento <path> e o comando a (arco): não será utilizado esta opção, porém é apenas um oportunidade de aprender esse recurso.
<path d="M50,50 60 a25,25 1,0 70,70" fill="none" stroke="red" stroke-width="2"/>
M: mover sem desenhar, letra maiúscula corresponde ao comando em coordenadas absolutas.
a: desenha uma arco, letra minúscula corresponde ao comando em coordenadas relativas.
ponto inicial: xi=50 e xi=50
ângulo do arco: θ=60
sentido de rotação: large-arc-flag=1 e sweep-flag=0.
ponto final: xf=70 e xf=70 (ponto final).

Sentido horário: lf=1 e sf=1 ou lf=0 e sf=1 (1,1 ou 0,1).
Sentido anti-horário: lf=1 e sf=0 ou lf=0 e sf=0.(1,0 ou 0,0).

A figura abaixo mostra que para a criação de um arco em SVG precisamos indicar o ponto inicial e final do arco e selecionar os parâmetros lf e sf que indicam o sentido de rotação para os pontos inicial e final.

Observe que o ponto inicial e o final estão de acordo com o sentido de rotação..

Opção 2: um arco é uma parte de uma circunferência, portanto é só utilizar a função (fórmula) da circunferência em coordenadas cartesianas com ângulo inicial e ângulo final.

Explicação: o ponto P da figura abaixo terá duas transformações com rotações e translações iguais, porém, com ordens diferentes:


A referência para qualquer sistema de coordenadas é por padrão a origem do sistema de coordenadas (coordenada-x=0 e coordenada-y=0).
A simples translação de pontos é feita com a soma ou subtração de tal translação diretamente nas respectivas coordenadas que queremos transladar.
Rotacionar e transladar é diferente de transladar e rotacionar.
Os centros do arco2 e do arco de cabeça participaram de suas rotações. O centro de um círculo nada mais é que a translação do círculo da origem do sistema de coordenadas.
A TRANSLAÇÃO PARA CENTRALIZAÇÃO DO DESENHO NÃO É SOMADA AS RESPECTIVAS COORDENADAS ANTES DA ROTAÇÃO COMO ACONTECEU COM O CENTRO DOS ARCOS, porque essa foi a técnica escolhida, primeiro o arco com o seu centro fora da origem rotacionou em torno da origem e depois foi transladado para o centro do desenho.
Entendimento: todos os desenhos explicativos são feitos através da geometria apenas, porém, a translação é uma agrandeza vetorial. O centro do desenho (h,k) foi utilizado como referência, ou melhor, um deslocamento da origem do sistema de coordenadas, portanto não compões as coordenadas.

Exemplo:
   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 = h +(xe*Math.cos(pp) - ye*Math.sin(pp)); //translacao mais a rotacao                 
   var yeg = k+(xe*Math.sin(pp) + ye*Math.cos(pp)); //translacao mais a rotacao

Cálculo do deslocamento x do arco do pé do dente:
O β da figura abaixo não é o da evolvente, é outro.
Devemos garantir que dois arcos de um mesmo vão entre os dentes sejam tangentes as respectivas envolventes e também tangente a circunferência interna. O desenho abaxo mostra a tangência de um círculo do pé do dente e uma evolvente.
O β DA FIGURA BAIXO NÃO É O MESMO DA FÓRMULA DA EVOLVENTE.

Figura3 (evolvente5.jpg)
rie
é calculado na figura14 da etapa4

Centralização: a translação dos pontos está sendo feita diretamente nas coordenadas com h e k para centralizar a figura no SVG. h = heigth/2 e k = width/2.

Portanto:
Centro do arco: (h+r1, k+r);
Raio do arco: r = ((80*80)-(60*60))/(2*60)
Ângulo de início: 270º = (3.π/2 rd) - α;
Ângulo final: 3.π/2 + α;
tgα = r1/r=> atan(r1/r) = αrad;

Código em JavaScript:
rr=0;//contador de pontos do arco
var r=((80*80)-(60*60))/(2*60);
for(beta=(3*Math.PI/2)-Math.atan(80/r);beta<=(3*Math.PI/2);beta+=step){
rr=rr+1;
var xa = h+80 + r*Math.cos(beta);//coordenada-x do arco
var ya = k-r + r*Math.sin(beta);//coordenada-y do arco
coord.push(new Point2D(xa,ya));//preechnimento da lista com objetos (Point2D) indices de 0 a rr-1
}

pts=coord[0].xx+","+coord[0].yy;//tipo texto, primeiro ponto

for(c=1;c<rr;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+", "+coord[c].xx+","+coord[c].yy;//lista dos pontos do circulo de base
}

O seguimento PoP1 sera feito automaticamente pela polyline que une o arco de chanfro com a evolvente.
A polylina é uma sequência de pontos um após o outro, não permite pular a sequência, o último ponto de uma sequência se une a sequência seguinte.

A variável c serve de contador de pontos (índice do array cood[]) e controlador do loop for. O primeiro índice de uma array é sempre 0 (zero). Toda a sequência de pontos do polyline é feita pelo índice c, essa sequência é contínua c = 0, c=1, c=2, c=3, ..., c=1000, c=1001, c=1002,...

A sequência dos demais pontos seguem o mesmo raciocínio e estão comentados no código abaixo.

Arquivo: engr2.svg

<?xml version="1.0" standalone="no"?> <!--cabecalho-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="400" height="400" stroke="black" stroke-width="0.5px" id="id1">

<script type="application/ecmascript"><![CDATA[

document.addEventListener("DOMContentLoaded", function(event) {//O evento DOMContentLoaded sera acionado quando todo o HTML (apenas) foi completamente carregado e analisado
var h = 200;//translacao da coordenada-x, centralizar
var k = 200;//translacao da coordenada-y, centralizar

var xmlns="http://www.w3.org/2000/svg";
var step = 2*Math.PI/1000; //passo do angulo beta igual a mil partes

function Point2D(xx,yy) {//funcao com dois argumentos iguais as respectivas variaveis
this.xx = xx;
this.yy = yy;
}

//variavel tipo objeto de lista para os desenhos
var coord = new Array();
var c;//índice contador

//circulo interno
var cir1 = document.createElementNS(xmlns, "circle");//cria um circulo
cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
cir1.setAttributeNS(null,'r', 60);//raio do centro
cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento


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


//criação da polilinha ou sequencia direta de pontos
var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha


//arco do pe do dente
rr=0;//contador de pontos do arco
var r=((80*80)-(60*60))/(2*60);
for(beta=(3*Math.PI/2)-Math.atan(80/r);beta<=(3*Math.PI/2);beta+=step){
rr=rr+1;
var xa = h+80 + r*Math.cos(beta);//coordenada-x do circulo
var ya = k+r + r*Math.sin(beta);//coordenada-y do circulo
coord.push(new Point2D(xa,ya));//preechnimento da lista com objetos (Point2D) indices de 0 a rr-1
}

pts=coord[0].xx+","+coord[0].yy;//tipo texto, primeiro ponto

for(c=1;c<rr;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do circulo de base
}

//"circunferência de base"
for(beta=0;beta<=2*Math.PI;beta+=step){ //primeiro ponto com angulo igual a zero
var xa = h + 100*Math.cos(beta);//coordenada-x do circulo
var ya = k + 100*Math.sin(beta);//coordenada-y do circulo
coord.push(new Point2D(xa,ya));//preechnimento da lista com objetos (Point2D) indices de rr a rr+1000
}

for(c=rr;c<=rr+1000;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do circulo de base
}


//evolvente
for(beta=0;beta<=2*Math.PI;beta+=step){ //loop de preenchimento
var xd=h+100*Math.cos(beta)+100*beta*Math.sin(beta);//coordenada-x da evolvente
var yd=-1*(k+100*Math.sin(beta)-100*beta*Math.cos(beta))+400;//coordenada-y da evolvente no sistema cartesiano
coord.push(new Point2D(xd,yd));//preecnimento da lista com objetos (Point2D)
}

for(c=rr+1001;c<=rr+2001;c=c+1){ //loop com contador 2 igual ao numero de step (passos) rr+1001 a rr+2001
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista acumulada

}

pol.setAttributeNS(null,'points',[pts]);
document.documentElement.appendChild(pol);//adicionar a polylinha no documento
});
]]></script>
</svg>


<iframe style="border-style: solid; border-width: 1px;" width="410" height="410" src="imgsvg/engr2.svg" scrolling="no"/><br>

Também pode-se testar o arquivo egr2.svg com um link como uma página HTML.
Link para engr2.svg

Etapa4
Até aqui o objetivo foi aprender como desenhar com o SVG e com o JavaScript sem se preocupar com as dimensões.
Para fazer o desenho é necessário o dimensionamento dos dentes de forma técnica para que possa ocorrer o engrenamento entre duas engrenagens. A seguir será apresentado um mínimo de informação para continuação da matéria.
Nesta etapa será dimensionado o desenho da etapa anterior.

4.1. Escala e Unidade de Medida
A escala é uma razão entre a dimensão de "desenho" e a dimensão real, exemplo: escala 2 : 1 quer dizer que o tamanho do desenho é duas vezes maior que o tamaho real (escala = tamanho do desenho : tamanho real).

4.2. Unidade de Medida de Comprimento
São as unidades de medida de apenas uma dimensão (largura ou altura) comumente empregadas na física ou matemática, tais como, centímetro, polegada, etc. O comprimento corresponde as coordenadas no eixo-x e no eixo-y.
No caso dos monitores a tela é onde são plotados as imagens. A tela possui duas dimensões, uma no eixo-x e outra no eixo-y.
O pixel é a unidade lógica de medida do monitor.
Resolução gráfica do monitor: é a dimensão da tela, largura e altura (em pixes) por unidade de comprimento. A maioria dos monitores tem 96 pixels per inch (96ppi), ou seja, 96 pixels por polegadas para a tela.
Para a impresão a resolução é medida em dots per inch (DPI), pontos por polegadas.
1 in (uma polegada) tem 2,54cm que corresponde a 96px na tela;
1 cm (um centímetro) tem 96px/2.54 na tela (37.7952755906px);
1 mm (um milímetro) tem 96px/25.4 na tela (3.77952755906px);
q - 1/4 do milímetro;
pc - pica: 12 points ou 1/6in;
pt - point: 1/72in;
px - pixel: 1/96in;

Obs:
Quando trabalhar com pixels é interessante adotar a resolução da tela como 96ppi (1mm = 3.779px) e arredondá-la para 1mm = 4px. Assim, por exemplo, 100mm terá 400px. O desenho técnico utiliza as unidades tradicionais milímetro (mm), centímetro (cm) e metro (m).

A tabela abaixo lista as unidades que podem ser usadas com o elemento raiz <svg>:
Unidades
Descrição
em Tamanho da fonte padrão, na tipografia é o espaço ocupado pela letra "m", é a base para a determinação de laguras em uma fonte. Unidade igual ao tamanho da fonte corrente.
ex Geralmente a altura da letra x minúscula (x-height).
px Pixel, a unidade padrão, quando a unidade não é informada assume esta unidade.
pt pontos (1/72 de uma polegada)
pc picas (1/6 de uma polegada)
cm Centímetros
mm Milímetros
in
polegadas

Conversor de Medidas
1 cm = 10 mm 1 mm = 0,1 cm
1 cm = 28,34 pixels 1 mm = 2,83 pixels
1 cm = 0,39 pol 1 mm = 0,04 pol
1 pixel = 0,04 cm 1 pol = 2,54 cm
1 pixel = 0,35 mm 1 pol = 25,4 mm
1 pixel = 0,01 pol 1 pol = 71,99 pixels

4.5. Unidades para ângulos
deg para grau: um círculo tem 360deg;
grad para grado: um círculo tem 400grad;
rad para radiano: um círculo tem 2š¯›‘rad;
turn para volta: um círculo tem 1turn;

Obs: tempo (s, ms, h, d, etc.), percentagem (%) e freqüência (Hz, kHz).

4.6. Engrenagem de Dentes Retos
O intuito deste trabalho é apresentar as principais propriedades da roda dentada ou também chamada engrenagem com a finalidade didática.
A engrenagem é tão útil a civilização quanto a própria roda, ou melhor, a engrenagem é uma roda para transmissão de movimentos quase sempre entre dois eixos.

O desenho de engrenagem não necessita do desenho do seu dente, contudo, este trabalho objetiva justamente dominar essa técnica a fim de que o desenho fique mais próximo da realidade através do seu dimensionamento real.

Nos desenhos anteriores o dente não foi dimensionado porque o objetivo era aprender como desenhá-lo. Para prosseguir com o desenho da engrenagem será utilizado suas fórmulas que são facilmente encontradas na literatura a respeito.

Engrenagens Cilíndricas Retas: Possuem dentes paralelos ao eixo de rotação da engrenagem. Transmitem rotação entre eixos paralelos.


Figura4 (engr.jpg)

4.7. Diâmetro de Base
O diâmetro de base é a principal medida para a construção da engrenagem porque a envolvente é gerada apartir dela. O módulo, o número de dentes e o diâmetro primitivo tem como referência o diâmetro de base e o ângulo de pressão. O dimensionamento dos diâmetros são feitos de fora para dentro, o primeiro é o diâmetro primitivo que deverá ser um valor inteiro para não atrapalhar o engrenamento, o segundo é o diâmetro de base e por último o diâmetro do pé do dente.

O diâmetro da circunferência de base é obtido através do ângulo de pressão, que pode assumir os valores de 20º, 25º e 14,5º. O primeiro valor é utilizado na grande maioria das vezes, a ponto de já ser considerado um valor padrão. O ângulo de 25º ainda é utilizado em engrenagens fabricadas na América do Norte.
cosφ = rb/rp => rb = rp.cosφ
ou
Como 2.rb=db e 2.rp=dp
cosφ = 2.rb/2.rp => db = dp.cosφ

4.8. Ângulo de ação ou de pressão
(φ)
É o ângulo que define a direção da força que a engrenagem motora exerce sobre a engrenagem movida. A figura abaixo mostra que o pinhão (coroa 1) exerce uma força na coroa 2, formando um ângulo (φ) com a tangente comum às circunferências primitivas (reta s chama linha de pressão). O ponto C é o ponto de contato entre as duas evolventes durante o engrenamento.

Figura5 (img5.jpg)

C: é o ponto traçador, é o ponto de contato entre as duas evolventes, percorre o trajeto entre T1 e T2. Tais evolventes são geradas simultaneamente pelo ponto traçador.
T2C e CT1: raio de curvatura da evolvente da coroa2 e coroa1 respectivamente.
s: é a linha geradora, contem os pontos de tangencias T1 e T2, essa linha não muda de posição, pois é sempre tangente aos círculos de base. Uma vez que ela é sempre normal à evolvente no ponto de contato, o requerimento de movimento uniforme é satisfeito.
P: ponto de tangência entre os círculos primitivos.
φ: ângulo de ação ou de pressão.

Engrenagens que se acoplam devem ter o mesmo módulo (ou “diametral pitch”) a fim de que os espaços entre os dentes sejam compatíveis. É fácil notar que, se as engrenagens não tiverem o mesmo passo circular, o primeiro dente entra em contato, mas o segundo já não mais se acoplará ao dente correspondente. Como o passo, por definição, é diretamente proporcional ao módulo, as engrenagens devem ter módulos iguais. O módulo pode ser entendido como uma medida indireta do tamanho do dente.


Figura6 (img7.jpg)

4.7. Módulos

Em todas engrenagens existe uma relação constante relacionando o número de dentes (Z) e o diâmetro primitivo (dp). No sistema métrico esta relação é chamada de módulo m (em milímetro) e no sistema inglês de passo diametral (número de dentes por polegada).
Módulos normalizados:
0,25
0,50
0,75
1
1,25
1,5
1,75
2
2,25
2,5
2,75
3
3,25
3,5
3,75
4
4
4,5
5
5,5
6
6,5
7









7
8
9
10
11
12
13
14
15
16







O módulo é a base do dimensionamento de engrenagens no sistema internacional. Duas engrenagens acopladas possuem o mesmo módulo. O módulo deve ser expresso em milímetros.
Lembre-se que módulo é uma simplificação da fórmula do passo circular (comprimento), ou seja dp1.π/z1 = dp2.π/z2 => dp1/z1 = dp2/z2 => m1 = m2

m = dp/z (constante): garante que o vão de uma engrenagem se acoplará na cabeça do dente da outra.
m: módulo.
dp: diâmetro primitivo.
z: nº de dentes.

Os módulos são normalizados para permitir o maior intercâmbio de ferramentas de fabricação. Isso não significa que os módulos tenham que ser os recomendados, mas que é mais fácil encontrar ferramentas para confeccionar engrenagens com os seguintes módulos (em mm): 0,2 a 1,0 com incrementos de 0,1 mm; 1,0 a 4,0 com incrementos de 0,25; 4,0 a 5,0 com incrementos de 0,5 mm.

Condição da Engrenagem
Os cálculos são feitos apartir do diâmetro primitivo afim de garantir que o arco do vão e o arco do dente sejam iguais a metade do passo. O passo depende do diâmetro primitivo e do número de dentes. O número de dentes deve ser um número inteiro, pois não tem cabimento uma fração de dente.

Ao escolher um diâmetro primitivo não é qualquer módulo que servirá. Existe um módulo máximo quando as duas evolventes se cruzam na cabeça do dente e um módulo mínimo quando quando o raio interno é igual ao raio base (ri=rb) ou quando duas evolvente se interceptam no vão do dente. Para verificar essas possibilidades há necessidades de calcular a evolvente máxima θmax que se cruzam na cabeça do dente e a evolvente que se cruzam no pé do dente.

Esse assunto será tratado nas etapas 5 e 6 quando a engrenagem será criada com a entrada do módulo e do diâmetro primitivo, além de que o cálculo das evolventes para tais circunstâncias depende de outros cálculos que ainda não foram abordados.
O objetivo nesse primeiro momento é cria uma engrenagem para assimilar suas propriedades principais e depois analisar todas as suas possibilidades de construção.

4.9. RAZÃO DE CONTATO (figura 6 acima)
Situação em que o arco de ação seja exatamente igual ao passo circular, isto é:
qt = p
Isto significa que um dente e seu espaço irão ocupar o arco completo AB. Em outras palavras, quando um dente está justamente começando o contato em T1 , o dente anterior está, ao mesmo tempo, terminando o seu contato em T2.

Considere uma situação em que o arco de ação seja maior que o passo circular, isto é:
qt = 1,2p
Isto significa que quando um par de dentes está acabando de entrar em contato em T1, um outro par, ainda em contato, não terá ainda alcançado T2.
Por um curto período de tempo haverá dois dentes em contato, um na vizinhança de A e outro na de B.

Define-se razão de contato mc como:
mc = qt/p

Número que indica o número médio de pares de dentes em contato.
Em geral, usa-se, no mínimo, mc = 1,2 para evitar ruído e impacto.
mc = LT/p.cosφ

CONTINUIDADE DO ENGRENAMENTO
A continuidade do engrenamento diz respeito à quantidade de pares de dentes que está engrenada em simultâneo durante funcionamento de uma engrenagem. Assim, para que o engrenamento de duas rodas aconteça em boas condições, do ponto de vista da continuidade do engrenamento, é necessário que pelo menos um par de dentes esteja engrenado durante a transmissão do movimento (um dente de cada engrenagem). Por outras palavras, pode dizer-se que existe continuidade do engrenamento quando um par de dentes termina o seu engrenamento só após o par de dentes seguinte ter já iniciado o contacto. A situação limite, em que há apenas e só um par de dentes em contato, está representada na figura abaixo.


Figura8 (img8.jpg)

A engenagem será feita na etapa 6, considera-se apenas dois pontos de contato. Tais pontos são provenientes da engrenagem motora para a engrenagem movida. Os dois ponto de contato da engrenagem movida para a engrenagem motora não geram movimentos.

Engrenamento em que apenas há contato num par de dentes (um dente de cada engrenagem), o qual garante, teoricamente, a continuidade do engrenamento.
É sabido que no caso de engrenagens paralelas de dentes gerados em evolvente de círculo, a linha de ação ou linha de engrenamento é um segmento de reta, tal como se ilustra na figura8 acima. No âmbito do presente texto admite-se que o pinhão (engrenagem menor) ou carreto é a roda motora, enquanto a coroa (engrenagem maior) é a roda movida.
Deve ainda relembrar-se aqui que a linha de engrenamento é sempre tangente às circunferências
de base das duas rodas, passa pelo ponto de contato entre os círculos primitivos e faz um ângulo (ângulo de pressão) com a linha tangente às circunferências primitivas.

É evidente que cada dente de uma roda dentada está engrenado apenas uma vez em cada rotação
completa da roda. Este aspeto é fundamental no estabelecimento do número mínimo de dentes que uma roda dentada deve ter.
A linha de ação ou linha de engrenamento é, por definição, a linha que une as sucessivas posições
do ponto de contato de uma engrenagem.

Ordem lógica das medidas de uma engrenagem
1º) Começa pelo diâmentro primitivo, módulo e número de dentes afim de garantir um número inteiro de dentes e um arco no vão e no dente iguais.
2º) Cálculo do diâmetro de base (não precisa ser inteiro);
3º) Cálculo do passo e demais medidas;

4.11. Passo circular
É definido como a razão entre o perímetro da circunferência primitiva e o número de dentes.

Perímetro da circunferência: 2.π.rp ou dp.π

O passo é um arco de circunferência:
p = π.dp/z
Como m = dp/z (constante) => z= dp/m
p = π.dp/(dp/m)
p = π.m (arco de circunferência)

Ângulo do passo:
â= 2.π/z (em radianos)


O passo é diretamente proporcional ao modulo ou diretamente proporcional ao diâmetro primitivo e inversamente proporcional ao número de dentes.

p = e + s
s: espessura do dente no primitivo.
e: vão
Folga no vão: g = e - s
Folga na cabeça do dente: j

Mais a frente será calculado o arco no circulo de base, esse arco é chamado de giro e servirá para rotacionar a segunda evolvente do primeiro dente.

p = dp.π/z = db.cosσ.π/z

O passo depende do diâmentro primitivo e do número de dentes.
O passo depende do diâmetro de base, do número de dentes e do ângulo de pressão.

Vão dos dentes:
é a distância tomada em arco sobre o círculo primitivo entre dois flancos defrontantes de dentes consecutivos.

4.12. Passo Diametral

É a grandeza correspondente ao módulo no sistema inglês. É o número de dentes por polegada.

4.13. Altura da Cabeça do Dente ou Saliência
É a distância radial entre a circunferência primitiva e a circunferência da cabeça.
ha = m

4.14. Altura do pé ou Profundidade
É a distância radial entre a circunferência primitiva e a circunferência do pé.
hf = 1,25.m.

4.15. Altura total do dente

É a soma da altura do pé com a altura da cabeça, ou seja, ht=ha+ hf .
ha = m
hf = 1,25.m
hT = 2,25.m

O diâmetro interno di pode ser modificado, aumentado com a diminuição de hf, ou diminuido com o aumento de hf. Porém, o dimensionamento do dente é feito para suportar certa força já previamente estipulada no projeto.

4.16. Largura do Dente
A recomendação para a largura do dente é que seja no mínimo 9 vezes o módulo e no máximo 14 vezes. Para o raio de concordância no pé do dente a recomendação é que seja de um terço do módulo.
Obs: concordância é a relação de tangência (ou continuidade) entre duas ou mais entidades geométricas.

4.17. Diâmetros Principais
Diâmetro primitivo: dp = m.z
Diâmetro de base: db = dp.cosφ
Diâmetro interno ou diâmetro de pé do dente:di = dp - 2.hf
Diâmetro externo ou diâmetro da cabeça do dente: dc = dp+2.hc

4.18. Tabela
Numero de dentes: z = dp/m (nº inteiro)
Módulo: m = dp/z = p/π
Passo: p= dp.π/z = m.π (comprimento de arco)
Ângulo do passo: p = 2.π/z (radianos)
Espessura do dente no primitivo: s = p/2
Altura total do dente: hT = 2,25.m Altura da cabeça do dente: hc = m
Vão entre os dentes no primitivo: e = p/2 Altura do pé do dente: hf = 1,25.m
Folga da cabeça: j = 0,2.m Ângulo de pressão: φ = 20º

Comentário
O mais importante para a construção da engrenagem de dente reto é o círculo de base que gerará a evolvente porque é essa curva que possui a principal propriedade de uma engrenagem (os dentes giram um sobre o outro sem escorregar, sem gerar atrito, no acoplamento).
Porém, para que uma engrenagem possa acoplar em outra é necessário que ambas tenham o MESMO PASSO. Ou seja dp1.π/z1 = dp2.π/z2 => dp1/z1 = dp2/z2 => m1 = m2
Módulos iguais quer dizer passos circulares (comprimentos) iguais.
Começa-se a criação da engrenagem pela determinação de seu diâmetro primitivo e pelo número de dentes que deve ser sempre inteiro. Consequentemente ter-se-á assim um passo que dividirá o circulo primitivo em partes iguais.
O primeiro dente da engrenagem é criado com arco no primitivo igual a passo/2 e vão no primitivo igual a passo/2. Assim fica garantido o engrenamento entre duas engrenagens com o mesmo passo (ou mesmo módulo que é uma simplificação da fórmula do passo).

4.19. Desenho
Para facilitar o desenho foi escolhido o módulo igual a 5mm e número de dentes igual a 20.
Dados: m =5 e z = 20.
z = dp/m
20 = dp/5 => dp = 100mm

cos20º = db/100 => db = 0,939692620785908x100
db = 93,9692620785908

ha = m => ha = 5mm (20px)
hf = 1,25.m => hf = 6,25mm (25px)
hT = 2,25.m => hT = 11,25mm (45px)
df = dp - 2.hf => df = 97,5mm (390px)
dc = dp+2.ha => da = 110mm (440px)
p = 360º/z => p = 18º (0,3141592653 rad)
p = d.π/z => p = 31,41592653mm
s = p/2 = 9°

Cálculo da Evolvente até a Cabeça do Dente
rc = (dc/2) = 55
rb = (db/2) = 46,984625
hT: altura da cabeça do dente = 11,25

Pelo triângulo retângulo OTP temos:
cosψ = rb/rc => acos(rb/rc) = ψ
θ = ev(ψ) = tgψ - ψ
Portanto a evolvente deve rotacionar ψ + θ para ser formada.

θ + ψ = tgψ

Obs: O ângulo θ é a evolvente do ângulo ψ.

Em JavaScript:
Math.acos(ψ) = rb/rc => ψ = Math.acos(rb/rc) = Math.acos(46,984625/55) = 0.546659
θ + ψ = Math.tan(0.546659) = 0.6085181
θ + ψ = Math.tan( Math.acos(rb/rc))

θ + ψ = 0.6085181 rd (ângulo de rotação para formar a evolvente até a cabeça do dente)

Figura9 (evolvente7.jpg)

A fórmula da evolvente é:
x = rb *( cosβ + β * senβ)
y = rb * (senβ - β * cos β)
Obs: quaisquer fórmulas são sempre as mesmas tanto para o sistema de coordenadas da tela quanto para o sistema cartesiano, pois o quadrante do sistema de coordenadas é sempre o positivo para as fórmulas.

Calculo do ângulo 2*β
Será feito apenas um furo para formar os dois chanfros do vão entre os dente. Devemos calcular o valor do ângulo β e o raio do furo. Depois é só criar um seguimento de reta tangente a evolvente e ao chanfro.
O β DA FIGURA BAIXO NÃO É O MESMO DA FÓRMULA DA EVOLVENTE.

Figura10 (furo.jpg)

A principal técnica utilizada é achar o ângulo 2*β que tangencia as duas evolvente no vão.
Através do ângulo 2*β podemos traçar um único círculo que tangencia o início das duas evolventes entre o vão.
Contudo para achar o comprimento x antes tem que fazer um círculo tangencial as duas evolventes do círculo exatamente no começo da evolvente. Esse círculo possui raio igual a re, é dito errado porque não tangencia o círculo do pé do dente (ou círculo interno), conforme figura abaixo.
O β DA FIGURA BAIXO NÃO É O MESMO DA FÓRMULA DA EVOLVENTE.


Figura11( evolvente12.jpg)
O PASSO p (ângulo) NO CIRCULO PRIMITIVO É IGUAL AO PASSO p (ângulo) NO CIRCULO DE BASE.

giro é o ângulo do arco de base.
giro = p/2 + 2θ2
θ2: é a evolvente até o primitivo.
β: é utilizado para achar o ângulo do arco de chanfro
2β = (p/2 - 2θ2) => β = (p/2 - 2θ2)/2
ou
β = (p - giro)/2 (confira no desenho acima)

Em JavaScript:
var ψ2 = Math.acos(rb/rp);
θ2 = Math.tan(ψ2 ) - ψ2 ;
var β = (p/2 - 2*θ2)/2;

Cálculo do comprimento P1Po, re e rie
A figura abaixo mostra o cálculo de rie e re para P1Po = 0, porém vale para P1Po > 0.
rie: é o raio errado do círculo do pé do dente, é errado porque pode ser maior, menor ou igual ao raio ri (verdadeiro).
re: é o raio do círculo de chanfro errado, é errado porque é tangente ao círculo do pé do dente errado.
O β DA FIGURA BAIXO NÃO É O MESMO DA FÓRMULA DA EVOLVENTE.


Figura12 (evolvente5a.jpg)

Existem três hipóteses para o comprimento de x:

O raio interno (ri) pode ser igual a di/2 = (dp - 2.hf)/2 ou menor. Se for maior que essa fórmula haverá diminuição da folga entre a cabeça de um dente com o vão da outra entrenagem no engrenamento.
O β DA FIGURA BAIXO NÃO É O MESMO DA FÓRMULA DA EVOLVENTE.


Figura13 (evolvente5.jpg)

Se for diminuido o raio interno para fazer um só furo para conseguir dois chanfros isso não atrapalha no engrenamento.
Existem três hipóteses para o tamanho de x:
x = 0, neste caso rie = ri
x > 0, neste caso rie > ri. Quando isso ocorrer devemos deslocar o centro do chanfro em x para a esquerda para que fique tangente ao círculo interno certo.
x < 0, neste caso rie < ri. Quando isso ocorrer basta fazer ri = rie e x =0. Porque ri menor que di/2 não atrapalha o engrenamento. X deve ser igualado a zero para não atrapalhar os arcos. r deve ser igualado a re porque os arcos usam a variável r e não re.


Figura 14

Conforme figura acima:
tgβ = re/rb => re = rb.tgβ
senβ = re/(rie + re) => rie = re.(1-senβ)/senβ
senβ = r/(ri+r) => r = ri.senβ/(1- senβ)
cosβ = x/ (rie + re - ri -r) => x = cosβ.(rie +re - ri - r)

Código engr3.svg em JavaScript
Foram criado as variáveis abaixo para o dimensionamento da engrenagem, foi considerado a resolução da tela de 96 pixels por polegada (1pol = 2,54cm = 25,5mm), com isso 1 mm = 1*(96/25.4)
96pixels --- 25,4mm
? --- 1mm => 1mm=0,26458333...pixel, ARREDONDA para 1mm=0,25pixel. A menor unidade de medida na tela é 1 pixel, que correponde a 4mm arredondado.

//1mm sera considerado igual a 4pixels
var h = 60*4;//translacao da coordenada-x centralizar em milimetro
var k = 60*4;//translacao da coordenada-y, centralizar em milimetro

var m=5*4;
var dp=100*4;
var z=dp/m;
var db = dp*Math.cos(20*Math.PI/180);
var p=(2*Math.PI)/z;
var hc = m;
var hf = 1.25*m;
var ht = hf+hc;
var di = dp-2*hf;
var dc = (dp+2*hc);

var rb = db/2;
var rc = dc/2;
var rp = dp/2;
var ri = di/2;

Conforme já estudado:
var ψ2 = Math.acos(rb/rp);
var θ2 = Math.tan(ψ2) - ψ2;
var giro = (p/2) + (2*θ2);

var ψ = Math.acos(rb/rc);
var θ = Math.tan(ψ) - ψ;

var β = (p/2 - 2*θ2)/2;
var re=rb*Math.tan(β);
var 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;
}

Circulo interno
var cir1 = document.createElementNS(xmlns, "circle");//cria um circulo
cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
cir1.setAttributeNS(null,'r', ri);//raio do centro
cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento

Seguimento PoP1
Será feito automaticamente pela polyline que une o último ponto do arco de chanfro com o primeiro ponto da evolvente.


Arco do pé do dente
rr é a variável que guarda os valores dos índices dos pontos correspondentes ao arco do pé do dente, tais índices serão os mesmos para os pontos da polyline a ser criada.
A variável pts é um array com todos os pontos do arco do pé do dente, do círculo de base e da evolvente que serão inseridos no mesmo um após o outro nessa sequencia. Tais pontos serão os pontos da polyline a ser criada. Por isso é importante que os índices esteje corretos, o primeiro índice de um array é 0 (zero).

rr=0;//contador de ciclo do loop for igual ao indice do array
for(beta=(3*Math.PI/2)-Math.atan((rb-x)/r);beta<=(3*Math.PI/2);beta+=step){
rr=rr+1;
var xa = h+rb-x + r*Math.cos(beta);//coordenada-x do circulo
var ya = k+r + r*Math.sin(beta);//coordenada-y do circulo
coord.push(new Point2D(xa,ya));//preechnimento da lista com objetos (Point2D) indices de 0 a 1000
}

pts=coord[0].xx+","+coord[0].yy;//tipo texto, primeiro ponto

for(c=1;c<rr;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do arco do pe do dente
}

Circunferência de base
for(beta=0;beta<=2*Math.PI;beta+=step){ //primeiro ponto com angulo igual a zero
var xa = h + rb*Math.cos(beta);//coordenada-x do circulo
var ya = k + rb*Math.sin(beta);//coordenada-y do circulo
coord.push(new Point2D(xa,ya));//preechimento da lista com objetos (Point2D) indices de 0 a 999
}

for(c=rr;c<=rr+1000;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do circulo de base
}

Evolvente
rr2 é um contador de loop que contará também o numero de pontos da evolvente.
A próxima sequencia de pontos do array pts começa com índice rr+1001 e termina com índice igual a rr+1001+rr2-1=rr+1000+rr2. Entendeu? como o próximo índice é rr+1001, faltam mais rr2-1 índices para serem incluídos.

rr2=0;//contador de ciclo do loop for igual ao indice do array
for(beta=0;beta<=Math.tan(Math.acos(rb/rc));beta+=step){ //loop de preenchimento
rr2=rr2+1;
var xd=h+rb*Math.cos(beta)+rb*beta*Math.sin(beta);//coordenada-x da evolvente
var yd=-1*(k+rb*Math.sin(beta)-rb*beta*Math.cos(beta))+2*h;//coordenada-y da evolvente no sistema cartesiano
coord.push(new Point2D(xd,yd));//preecnimento da lista com objetos (Point2D)
}

for(c=rr+1001;c<rr+1001+rr2;c=c+1){ //loop com contador 2 igual ao numero de step (passos) 1001 a 2001
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista acumulada

}

Criação da polilinha ou sequencia direta de pontos
var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha
pol.setAttributeNS(null,'points',[pts]);
document.documentElement.appendChild(pol);//adicionar a polylinha no documento

Criação da polilinha ou sequencia direta de pontos
var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha
pol.setAttributeNS(null,'points',[pts]);
document.documentElement.appendChild(pol);//adicionar a polylinha no documento

arquivo engre3.svg:
Sequência para a polyline: primeiro circunferência de base, segundo arco de chanfro no pé do dente e em terceiro a evolvente. Essa sequência deve ser seguida porque a polyline é uma sequência de pontos um após o outro. O seguimento de reta será eito automaticamente quando a polyline imendar o arco de chanfro com a evolvente.
<?xml version="1.0" standalone="no"?> <!--cabecalho-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="120mm" height="120mm" stroke="black" stroke-width="0.5px" id="id1">

<script type="application/ecmascript"><![CDATA[


document.addEventListener("DOMContentLoaded", function(event) {//O evento DOMContentLoaded sera acionado quando todo o HTML (apenas) foi completamente carregado e analisado
//1mm sera considerado igual a 4pixels
var h = 100*4;//translacao da coordenada-x centralizar em milimetro
var k = 100*4;//translacao da coordenada-y, centralizar em milimetro

var m=5*4;
var dp=100*4;
var z=dp/m;
var db = dp*Math.cos(20*Math.PI/180);
var p=(2*Math.PI)/z;
var hc = m;
var hf = 1.25*m;
var ht = hf+hc;
var di = dp-2*hf;
var dc = (dp+2*hc);

var rb = db/2;
var rc = dc/2;
var rp = dp/2;
var ri = di/2;

var step = 2*Math.PI/1000;

var xmlns="http://www.w3.org/2000/svg";
var step = 2*Math.PI/1000; //passo do angulo beta igual a mil partes

function Point2D(xx,yy) {//funcao com dois argumentos iguais as respectivas variaveis
this.xx = xx;
this.yy = yy;
}

//variavel tipo objeto de lista para os desenhos
var coord = new Array();
var c;//índice contador

//circulo interno
var cir1 = document.createElementNS(xmlns, "circle");//cria um circulo
cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
cir1.setAttributeNS(null,'r', ri);//raio do centro
cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento


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


var ψ2 = Math.acos(rb/rp);
var θ2 = Math.tan(ψ2) - ψ2;
var giro = (p/2) + (2*θ2);

var ψ = Math.acos(rb/rc);
var θ = Math.tan(ψ) - ψ;

var β = (p/2 - 2*θ2)/2;
var re=rb*Math.tan(β);
var 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;
}

//arco do pe do dente
rr=0;//contador de ciclo do loop for igual ao indice do array
for(beta=(3*Math.PI/2)-Math.atan((rb-x)/r);beta<=(3*Math.PI/2);beta+=step){
rr=rr+1;
var xa = h+rb-x + r*Math.cos(beta);//coordenada-x do arco
var ya = k+r + r*Math.sin(beta);//coordenada-y do arco
coord.push(new Point2D(xa,ya));//preechnimento da lista com objetos (Point2D) indices de 0 a 999
}

pts=coord[0].xx+","+coord[0].yy;//tipo texto, primeiro ponto

for(c=1;c<rr;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do arco do pe do dente
}

//"circunferência de base"
for(beta=0;beta<=2*Math.PI;beta+=step){ //primeiro ponto com angulo igual a zero
var xa = h + rb*Math.cos(beta);//coordenada-x do circulo
var ya = k + rb*Math.sin(beta);//coordenada-y do circulo
coord.push(new Point2D(xa,ya));//preechnimento da lista com objetos (Point2D) indices de 0 a 1000
}

for(c=rr;c<=rr+1000;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do circulo de base
}


//evolvente
rr2=0; //contador de ciclo do loop for igual ao indice do array
for(beta=0;beta<=Math.tan(Math.acos(rb/rc));beta+=step){ //loop de preenchimento
rr2=rr2+1;
var xd=h+rb*Math.cos(beta)+rb*beta*Math.sin(beta);//coordenada-x da evolvente
var yd=-1*(k+rb*Math.sin(beta)-rb*beta*Math.cos(beta))+2*h;//coordenada-y da evolvente no sistema cartesiano
coord.push(new Point2D(xd,yd));//preecnimento da lista com objetos (Point2D)
}

for(c=rr+1001;c<rr+1001+rr2;c=c+1){ //loop com contador 2 igual ao numero de step (passos) 1001 a 2001
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista acumulada

}

//criação da polilinha ou sequencia direta de pontos
var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha
pol.setAttributeNS(null,'points',[pts]);
document.documentElement.appendChild(pol);//adicionar a polylinha no documento
});
]]></script>
</svg>


<iframe style="border-style: solid; border-width: 1px;" width="500" height="500" src="imgsvg/engr3.svg" scrolling="no"/><br>

Também pode-se testar o arquivo egr3.svg com um link como uma página HTML.
Link para engr3.svg


Etapa5
É importantíssimo padronizar as fórmulas e definir o sistema de coordenadas a ser usado. A melhor padronização é a que for mais intuitiva, mais lógica e por consequência a mais compreenssível. Com a padronização é possível criar a polyline que é uma sequência de pontos um após o outro.

O sistema de coordenadas adotado para o desenho da engrenagem é o da tela (para facilitar trabalhar com texto).


- A fórmula para a rotação de pontos é sempre a mesma para qualquer sistema de coordenadas, o que muda são os sinais dos ângulos (ângulo positivo a rotação é no sentido positivo do eixo-y e ângulo negativo a rotação é no sentido negativo do eixo-y), como o ângulo é o giro > 0 temos:
x' = x.cos(-giro) - y.sen(-giro)
y' = x.sen(-giro) + y.cos(-giro)
Com -giro a rotação será no sentido do eixo-y negativo para o sistema de coordenadas da tela, ou seja, sentido anti-horário.
Esta fórmula é válida para a rotação do ponto P(x,y) para qualquer quadrante, pois a fórmula do seno e cosseno não mudam. Deve-se levar em consideração o sinal do ângulo (+) no sentido do eixo-y positivo e (-) no sentido do eixo-y negativo, tanto para o sistema da tela como o sistema cartesiano.
Obs: cos60º = cos-60º, sen60º = -sen-60º.

Cálculo da Rotação das Coordenadas
Será calculado o ângulo de giro ou rotação das Coordenadas para formar o dente. Essa rotação tem como referência o círculo base.


Figura16 (evolvente8.jpg)

O chanfro2 e aa evolvente2 deverão girar um ângulo igual ao arco PoE (-giro), porém como a rotação positiva no sentido anti-horário, peceba que o cálculo para o ângulo inicial e final no chanfro tem como referência o centro do círculo de chanfro e não a origem do sistema de coordenadas.

Cálculo do Arco PoE
Arco PoE = ArcoPoC + ArcoCD + ArcoDE
ArcoPoC = evolvente no ponto A
ArcoCD = Arco no primitivo = p/2
p = 360º/z => p = 18º (0,3141592653 rad)
p = 2*Math.PI/20 = Math.PI/10

ArcoCD = p/2 = 0,157079
ArcoCD = Math.PI/20

ArcoDE = ArcoPoC = θ2 = ev(ψ2) = tgψ2 - ψ2


var ψ2 = Math.acos(rb/rp);
var θ2 = Math.tan(ψ2) - ψ2;
var giro = (p/2) + (2*θ2);

var ψ = Math.acos(rb/rc);
var θ = Math.tan(ψ) - ψ;

var β =(p/2 - 2*θ2)/2;

- Será rotacionado os pontos em -giro, sentido anti-horário (tela).
- O seguimento de reta x é feito automaticamente pela polyline.
- A sequência para a criação da polyline será conforme figura abaixo, os pontos serão sequenciais de cima para baixo um após o outro:
1º) Arco de chanfro 2 e sua rotação em -giro;
2º) Evolvente 2 e sua rotação em -giro;
3º) Arco de cabeça e sua rotação em -giro;
4º) Evolvente 1;
5) Arco de chanfro 1.

Arco de chanfro 2 com Rotação de Pontos
A rotação deverá ser igual ao ângulo -giro já calculado, como estamos desenhando no sistema de coordenadas da tela, ao rotacionar com ângulo negativo os pontos se deslocarão no sentido do eixo-y negativo (anti-horário).
Os ângulos iniciais e finais estão conforme figura acima, é só interpretar a figura.
var ψ = Math.acos(rb/rc);
var θ = Math.tan(ψ) - ψ;
<span>
θ + ψ = Math.tan(Math.acos(rb/rc)) este é o ângulo que forma a evolvente.
Math.atan((rb-x)/r): este é o ângulo que forma o arco de pé do dente.
tgα = (rb-x)/r α = Math.atan((rb-x)/r): este é o ângulo do pé do dente
Ângulo inicial do arco: (Math.PI/2+Math.atan((rb-x)/r)
Ângulo final do arco: (Math.PI)/2
Centro:(rb-x,-r)
Translação (centralização): (h,k)
O β DA FIGURA BAIXO NÃO É O MESMO DA FÓRMULA DA EVOLVENTE.

Código JavaScript
rr1=0;//contador de ciclo do loop for igual ao indice do array
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 arco
var ya = -r+r*Math.sin(beta);//coordenada-y do arco
var xag = h +(xa*Math.cos(-giro) - ya*Math.sin(-giro)); //translacao mais a rotacao
var yag = k+(xa*Math.sin(-giro) + ya*Math.cos(-giro)); //translacao mais a rotacao

coord.push(new Point2D(xag,yag));//preechnimento da lista com objetos (Point2D) indices de 0 a rr1-1
}

pts=coord[0].xx+","+coord[0].yy;//tipo texto, primeiro ponto

for(c=1;c<rr1;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do arco do pe do dente
}

Obs:
- As coordenadas do centro do arco 2 fazem parte das coordenadas desse arco e portanto precisam ser rotacionadas também.
- As coordenadas de centralização (h e k) não fazem parte da rotação, apenas da translação.


Evolvente 2 com Rotação de Pontos
A rotação deverá ser igual ao ângulo -giro já calculado, como estamos desenhando no sistema de coordenadas da tela, ao rotacionar com ângulo negativo os pontos se deslocarão no sentido do eixo-y negativo (anti-horário).
ψ: é o ângulo de inclinação da evolvente.
var ψ = Math.acos(rb/rc);
var θ = Math.tan(ψ) - ψ (evolvente)
β = θ + ψ = Math.tan(Math.acos(rb/rc)): este é o ângulo que o raio de curvatura deve girar para formar a evolvente.
Formula da evolvente:
x = rb *( cosβ + β * senβ)
y = rb * (senβ - β * cos β)

Código em JavaScript
rr2=0; //contador de ciclo do loop
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 = h +(xb*Math.cos(-giro) - yb*Math.sin(-giro)); //translacao mais a rotacao
var ybg = k+(xb*Math.sin(-giro) + yb*Math.cos(-giro)); //translacao mais a rotacao
coord.push(new Point2D(xbg,ybg));//preechimento da lista com objetos (Point2D)
}

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

}

Arco de Cabeça
raio: é o raio de cabeça (rc).
Ângulo inicial : é igual a θ (função evolvente).
var ψ = Math.acos(rb/rc);
θ = Math.tan(ψ) - ψ;
Ângulo final: é igual a a2.

a3 = giro
a2 = a3 - θ
a2 = giro- θ (arco de cabeça)

A variável θ será usada para cálculo do arco de cabeça.

A figura abaixo possui os ângulos a1, a2, a3 e a4 sobre a circunferência de base.
Com base na figura 9 a1 = θ
a4 refere-se a divisão de 360º pelo número de dentes = 18º (passo).


Figura20 (evolvente10.jpg)

Código em JavaScript
a2 = giro - θ;//angulo do arco de cabeca
rr3=0;//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 = h +(xc*Math.cos(-giro) - yc*Math.sin(-giro)); //translacao mais a rotacao
var ycg = k+(xc*Math.sin(-giro) + yc*Math.cos(-giro)); //translacao mais a rotacao

coord.push(new Point2D(xcg,ycg));//preechimento da lista com indices de rr1+rr2 a rr1+rr2+rr3-1
}

for(c=rr1+rr2;c<rr1+rr2+rr3;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do arco do pe do dente
}

Evolvente 1
Não é necessário a rotação apenas a inversão dos sinais das coordenadas-y para inverter a curva simetricamente ao eixo-x, assim a curva fica para cima.

ψ: é o ângulo de inclinação da evolvente.
var ψ = Math.acos(rb/rc);
var θ = Math.tan(ψ) - ψ (evolvente)
β = θ + ψ= Math.tan(ψ): este é o ângulo que o raio de curvatura deve girar para formar a evolvente.

Formula da evolvente com a curvatura para cima no sistema de coodenadas da tela:
x = rb *( cosβ + β * senβ)
y = -rb * (senβ - β * cos β)
A coordenada-y é multiplicado por -1.

Código em JavaScript
rr4=0; //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=h+rb*Math.cos(beta)+rb*beta*Math.sin(beta);//coordenada-x da evolvente1
var yd=k+-rb*Math.sin(beta)+rb*beta*Math.cos(beta);//coordenada-y invertida da evolvente1 no sistema da tela
coord.push(new Point2D(xd,yd));//preechimento da lista com objetos (Point2D) indices de rr1+rr2+rr3 a rr1+rr2+rr3+rr4-1

}
for(c=rr1+rr2+rr3;c<rr1+rr2+rr3+rr4;c=c+1){ //loop para preenchimento da lista
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista acumulada

}


Arco de chanfro 1
Não precisa de rotação

Os ângulos iniciais e finais estão conforme figura abaixo, é só interpretar acima.
ângulo inicial do arco: 3*Math.PI/2
ângulo final do arco: (3*Math.PI/2 - Math.atan((rb-x)/r))
Centro:(rb-x,r)
Translação (centralização): (h,k)

Código JavaScript
rr5=0;//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 = h + rb-x+r*Math.cos(beta);//coordenada-x do arco1
var ye = k + r+r*Math.sin(beta);//coordenada-y do arco1

coord.push(new Point2D(xe,ye));//preechnimento da lista com objetos (Point2D) indices de rr1+rr2+rr3+rr4 a rr1+rr2+rr3+rr4+rr5-1
}

for(c=rr1+rr2+rr3+rr4;c<rr1+rr2+rr3+rr4+rr5;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do arco do pe do dente
}


Criação da Polilinha ou Sequência Direta de Pontos
var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha
pol.setAttributeNS(null,'points',[pts]);
document.documentElement.appendChild(pol);//adicionar a polylinha no documento

engr4.svg
Esse arquivo
<?xml version="1.0" standalone="no"?> <!--cabecalho-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="480px" height="480px" stroke="black" stroke-width="0.5px" id="id1">

<script type="application/ecmascript"><![CDATA[


document.addEventListener("DOMContentLoaded", function(event) {//O evento DOMContentLoaded sera acionado quando todo o HTML (apenas) foi completamente carregado e analisado
//1mm sera considerado igual a 4pixels
var h = 240;//translacao da coordenada-x centralizar em milimetro
var k = 240;//translacao da coordenada-y, centralizar em milimetro

var m=10*4; //1mm igual a 4px
var dp=100*4;
var z=dp/m;
var db = dp*Math.cos(20*Math.PI/180);
var p=(2*Math.PI)/z;
var hc = m;
var hf = 1.25*m;
var ht = hf+hc;
var di = dp-2*hf;
var dc = (dp+2*hc);

var rb = db/2;
var rc = dc/2;
var rp = dp/2;
var ri = di/2;

var step = 2*Math.PI/1000;//passo para angulo

var xmlns="http://www.w3.org/2000/svg";
var step = 2*Math.PI/1000; //passo do angulo beta igual a mil partes

function Point2D(xx,yy) {//funcao com dois argumentos iguais as respectivas variaveis
this.xx = xx;
this.yy = yy;
}

//variavel tipo objeto de lista para os desenhos
var coord = new Array();
var c;//índice contador

//circulo interno
var cir1 = document.createElementNS(xmlns, "circle");//cria um circulo
cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
cir1.setAttributeNS(null,'r', ri);//raio do centro
cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento


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


var ψ2 = Math.acos(rb/rp);
var θ2 = Math.tan(ψ2) - ψ2;
var giro = (p/2) + (2*θ2);

var ψ = Math.acos(rb/rc);
var θ = Math.tan(ψ) - ψ;//evolvente

var β = (p/2 - 2*θ2)/2;
var re=rb*Math.tan(β);
var 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;
}

//arco2 do pe do dente rotacionado
rr1=0;//contador de ciclo do loop for igual ao indice do array
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 arco
var ya = -r+r*Math.sin(beta);//coordenada-y do arco
var xag = h +(xa*Math.cos(-giro) - ya*Math.sin(-giro)); //translacao mais a rotacao
var yag = k+(xa*Math.sin(-giro) + ya*Math.cos(-giro)); //translacao mais a rotacao

coord.push(new Point2D(xag,yag));//preechnimento da lista com objetos (Point2D) indices de 0 a rr1-1
}

pts=coord[0].xx+","+coord[0].yy;//tipo texto, primeiro ponto

for(c=1;c<rr1;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do arco2 do pe do dente
}

//evolvente2 e rotacao
rr2=0; //contador de ciclo do loop
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 = h +(xb*Math.cos(-giro) - yb*Math.sin(-giro)); //translacao mais a rotacao
var ybg = k+(xb*Math.sin(-giro) + yb*Math.cos(-giro)); //translacao mais a rotacao
coord.push(new Point2D(xbg,ybg));//preechimento da lista com objetos (Point2D)
}

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

}

// arco de cabeca

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

rr3=0;//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 = h +(xc*Math.cos(-giro) - yc*Math.sin(-giro)); //translacao mais a rotacao
var ycg = k+(xc*Math.sin(-giro) + yc*Math.cos(-giro)); //translacao mais a rotacao

coord.push(new Point2D(xcg,ycg));//preechimento da lista com indices de rr1+rr2 a rr1+rr2+rr3-1
}

for(c=rr1+rr2;c<rr1+rr2+rr3;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do arco do pe do dente
}


//evolvente1 tem que inverter a coordenadaY
rr4=0; //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=h+rb*Math.cos(beta)+rb*beta*Math.sin(beta);//coordenada-x da evolvente1
var yd=k+-rb*Math.sin(beta)+rb*beta*Math.cos(beta);//coordenada-y invertida da evolvente1 no sistema da tela
coord.push(new Point2D(xd,yd));//preechimento da lista com objetos (Point2D) indices de rr1+rr2+rr3 a rr1+rr2+rr3+rr4-1

}
for(c=rr1+rr2+rr3;c<rr1+rr2+rr3+rr4;c=c+1){ //loop para preenchimento da lista
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista acumulada

}

//chanfro1 ou arco1
rr5=0;//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 = h + rb-x+r*Math.cos(beta);//coordenada-x do arco1
var ye = k + r+r*Math.sin(beta);//coordenada-y do arco1

coord.push(new Point2D(xe,ye));//preechnimento da lista com objetos (Point2D) indices de rr1+rr2+rr3+rr4 a rr1+rr2+rr3+rr4+rr5-1
}

for(c=rr1+rr2+rr3+rr4;c<rr1+rr2+rr3+rr4+rr5;c=c+1){ //loop com contador c igual ao numero de step (passos)
pts=pts+","+coord[c].xx+","+coord[c].yy;//lista dos pontos do arco do pe do dente
}


//criação da polilinha ou sequencia direta de pontos
var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha
pol.setAttributeNS(null,'points',[pts]);
document.documentElement.appendChild(pol);//adicionar a polylinha no documento
});
]]></script>
</svg>


<iframe style="border-style: solid; border-width: 1px;" width="500" height="500" src="imgsvg/engr4.svg" scrolling="no"/><br>

Também pode-se testar o arquivo egr4.svg com um link como uma página HTML.
Link para engr4.svg


Etapa6
Na etapa5 foi criado apenas um dente, para gerar os dentes restantes será necessário acrescentar um laço de repetição para a criação dos demais dentes. Após criar o primeiro dente o segundo dente deve começar onde terminou o primeiro dente, para isso ocorrer  devemos acrescentar no giro de criação do dente o ângulo de passo (pp=pp+p), perceba que a variável pp é igual a zero para o primeiro dente. A cada novo ciclo de criação do dente é dado um novo passo.
A lista pts=[] receberá todos os pontos da engrenagem, a variável c é o índice dessa lista que deverá ser único e em sequencia, pois um ponto da polyline deve ser imediatamente seguido pelo próximo ponto, a polyline cria o desenho ligando os pontos de forma sequencial.
A variável c além de índice da lista pts é também contador dos loops for de criação dos arcos e evolventes, portanto deve ficar fora da função vai(), ou seja, é uma variável global.

cc=0: É importantíssimo,  guarda o último valor do ciclo de criação de um dente (rr5) e passa a variável c que reinicia um novo ciclo de criação do próximo dente.
pp=0: É impotantissimo, é o ângulo de rotação para formar os demais dentes depois do primeiro, a primeira rotação é zero (0) as demais é p acumuladamente a cada ciclo.

Cada ciclo de repetição cria um novo dente
rri, rr2, rr3, rr4 e rr5 são contadores de ciclos para os arcos e evolventes.
O primeiro ponto do arco2 tem índice 0 (zero) e último com indice menor que rr1.
O primeiro ponto da evolvente2 tem indice igual a rr1 e último ponto com indice menor que rr2.
O primeiro ponto do arco de cabeça tem índice igual a rr2 e último ponto com indice menor que rr3.
O primeiro ponto da evolvente1 tem índiceigual a rr3 e último ponto com indice menor que rr4.
O primeiro ponto do arco1 (pé do dente) tem indice igual a rr4 e último ponto com índice menor rr5.

No final do primeiro ciclo de preencimento da lista pts com todos os pontos do primeiro dente, rr1 e cc serão igualados a rr5 e iniciará um novo ciclo correspondente ao próximo dente, seguirá assim até o final do ciclo.

Função para criação dos pontos e preenchimento da lista pts
Todos os pontos serão rotacionados em pp inicializado com zero e no final de cada ciclo de criação do dente é incrementado em p (ângulo de passo).

...
var c;//índice dos pontos e contador do loop for, fica de fora da função vai
var cc=0;//importantíssimo,  guarda o último valor do ciclo de criação de um dente (rr5) e passa passa a variável c que reinicia um novo ciclo de criação de um dente

pts=[];//lista de pontos, fica fora da função vai assim é acessível globalmente  
function vai(){
  var coord = new Array();
  pp=0;
  rr1=0;
function Point2D(xx,yy) {
  this.xx = xx+h;
  this.yy = yy+k;
 

   
for(i=0;i<z;i=i+1){

//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;//contador de ciclo
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 menos 1
}
 
for(c=cc;c<rr1;c=c+1){ //loop com contador c igual ao numero de step para cada ciclo rr1 é igual a c mais 1
     pts.push(coord[c].xx);
     pts.push(coord[c].yy);
}

...
cc=rr5;
rr1=rr5;//importantissimo a cada ciclo de repeticao o contador acumula-se e começa a fazer um novo 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 dos demais dentes

...

Indice c para um ciclo de criação de um dente:
cc ≤ c < rr1 para o arco2
rr1 ≤ c < rr2 para a evolvente2
rr2 ≤ c < rr3 para o arco de cabeça
rr3 ≤ c < rr4 para a evolvente1
rr5 ≤ c < rr5 para a arco1

Indices para o reinício do próximo ciclo de criação do próximo dente:
cc=rr5
rr1=rr5
pp=pp+p


Criação da polilinha ou sequencia direta de pontos
var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
pol.setAttributeNS(null,'fill','none');//importante para o polyline ser uma linha
pol.setAttributeNS(null,'points',pts);
document.documentElement.appendChild(pol);//adicionar a polylinha no documento

Código: engr5.svg (está todo comentado)
<?xml version="1.0" standalone="no"?> <!--cabecalho-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="480px" height="480px" stroke="black" stroke-width="0.5px" id="id1">
  
<script type="application/ecmascript"><![CDATA[

document.addEventListener("DOMContentLoaded", function(event) {//O evento DOMContentLoaded sera acionado quando todo o HTML (apenas) for completamente carregado e analisado
//1mm sera considerado igual a 4pixels
var pts=[];//lista com todos os pontos do polyline 
var h = 240;//translacao da coordenada-x para centralizar no svg
var k = 240;//translacao da coordenada-y para centralizar no svg

var m=4*4; //1mm igual a 4px
var dp=100*4;//diâmetro primitivo de 100 milimettros
var z=dp/m;
var db = dp*Math.cos(20*Math.PI/180);
var p=(2*Math.PI)/z;//passo em radianos
var hc = m; //altura de cabeca do dente
var hf = 1.25*m;//altura do pé do odente
var ht = hf+hc;//altura toral do dente
var di = dp-2*hf;//diametro interno
var dc = (dp+2*hc);//diaametro de cabeca

var rb = db/2;//raio de base
var rc = dc/2;//raio de cabeca
var rp = dp/2;//raio do primitivo
var ri = di/2;//raio interno

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

var xmlns="http://www.w3.org/2000/svg";


//circulo interno
var cir1 = document.createElementNS(xmlns, "circle");
    cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
    cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
    cir1.setAttributeNS(null,'r', ri-50);//raio do circulo interno igual a ri-50 escolhido aleatoriamente
    cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
    cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento


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


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

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

var β = (p/2 - 2*θ2)/2;//é utilizado para achar o ângulo do arco de chanfro
var re=rb*Math.tan(β);
var 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 c;//índice dos pontos e contador do loop for, fica de fora da função vai
var cc=0;//importantíssimo,  guarda o último valor do ciclo de criação de um dente (rr5) e passa passa a variável c que reinicia um novo ciclo de criação de um dente

pts=[];//lista de pontos, fica fora da função vai assim é acessível globalmente  
function vai(){ //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
//as variáveis dentro da função serão inicializadas a cada nova execução da função
  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 lista pts, para cada ciclo rr1 é cumulativo


function Point2D(xx,yy) {//funcao com dois argumentos iguais as respectivas variaveis
//todos os pontos serão rotacionados e centralizados
  this.xx = xx+h;
  this.yy = yy+k;
 

   
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 menos 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);
     pts.push(coord[c].yy);
}

//evolvente2 e rotacao
rr2=rr1; //contador de ciclo do loop é o próximo indice depois de rr1 menos 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
     pts.push(coord[c].xx);
     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 cabeca
   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 menos 1
     pts.push(coord[c].xx);
     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 evolvente1 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);
     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
}
 
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 menos 1
     pts.push(coord[c].yy);
}
cc=rr5;
rr1=rr5;//importantissimo a cada ciclo de repeticao o contador acumula-se e começa a fazer um novo 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 dos demais dentes


//criação da polilinha ou sequencia direta de pontos

  var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol.setAttributeNS(null,'points',pts);
    pol.setAttributeNS(null,'id','id2');
    document.documentElement.appendChild(pol);//adicionar a polylinha no documento  

}//fecha função vai

vai();//primeira execução da função

});
 ]]></script>
 </svg>



<iframe style="border-style: solid; border-width: 1px;" width="500" height="500" src="imgsvg/engr5.svg" scrolling="no"/><br>

Também pode-se testar o arquivo engr5.svg com um link como uma página HTML.
Link para engr5.svg

Etapa7
Agora vamos animar o desenho com sucessivas rotações.
Centro de giro é (h,k) use 240 e 240 direto.
Crie um id para a polyline: pol.setAttributeNS(null,'id','id2');

Acrescente o código abaixo no arquivo engr5.svg após o desenho da polyline:
 var transforme = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");
     transforme.setAttributeNS(null,'attributeType', 'XML');
     transforme.setAttributeNS(null,'attributeName', 'transform');
     transforme.setAttributeNS(null,'type', 'rotate');
     transforme.setAttributeNS(null,'from', '0 240 240');//ângulo inicial e coordenadas de centro
     transforme.setAttributeNS(null,'to','360 240 240');//ângulo final e coordenadas de centro
     transforme.setAttributeNS(null,'dur', '10s');//duração
     transforme.setAttributeNS(null,'repeatCount', 'indefinite');//repetição
     document.getElementById('id2').appendChild(transforme);//insere na polyline

Código: engr6.svg (está todo comentado)
<?xml version="1.0" standalone="no"?> <!--cabecalho-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="480px" height="480px" stroke="black" stroke-width="0.5px" id="id1">
  
<script type="application/ecmascript"><![CDATA[

document.addEventListener("DOMContentLoaded", function(event) {//O evento DOMContentLoaded sera acionado quando todo o HTML (apenas) for completamente carregado e analisado
//1mm sera considerado igual a 4pixels
var pts=[];//lista com todos os pontos do polyline 
var h = 240;//translacao da coordenada-x para centralizar no svg
var k = 240;//translacao da coordenada-y para centralizar no svg

var m=4*4; //1mm igual a 4px
var dp=100*4;//diâmetro primitivo de 100 milimettros
var z=dp/m;
var db = dp*Math.cos(20*Math.PI/180);
var p=(2*Math.PI)/z;//passo em radianos
var hc = m; //altura de cabeca do dente
var hf = 1.25*m;//altura do pé do odente
var ht = hf+hc;//altura toral do dente
var di = dp-2*hf;//diametro interno
var dc = (dp+2*hc);//diaametro de cabeca

var rb = db/2;//raio de base
var rc = dc/2;//raio de cabeca
var rp = dp/2;//raio do primitivo
var ri = di/2;//raio interno

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

var xmlns="http://www.w3.org/2000/svg";


//circulo interno
var cir1 = document.createElementNS(xmlns, "circle");
    cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
    cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
    cir1.setAttributeNS(null,'r', ri-50);//raio do circulo interno igual a ri-50 escolhido aleatoriamente
    cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
    cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento


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


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

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

var β = (p/2 - 2*θ2)/2;//é utilizado para achar o ângulo do arco de chanfro
var re=rb*Math.tan(β);
var 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 c;//índice dos pontos e contador do loop for, fica de fora da função vai
var cc=0;//importantíssimo,  guarda o último valor do ciclo de criação de um dente (rr5) e passa passa a variável c que reinicia um novo ciclo de criação de um dente

pts=[];//lista de pontos, fica fora da função vai assim é acessível globalmente  
function vai(){ //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
//as variáveis dentro da função serão inicializadas a cada nova execução da função
  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 lista pts, para cada ciclo rr1 é cumulativo


function Point2D(xx,yy) {//funcao com dois argumentos iguais as respectivas variaveis
//todos os pontos serão rotacionados e centralizados
  this.xx = xx+h;
  this.yy = yy+k;
 

   
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 menos 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);
     pts.push(coord[c].yy);
}

//evolvente2 e rotacao
rr2=rr1; //contador de ciclo do loop é o próximo indice depois de rr1 menos 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
     pts.push(coord[c].xx);
     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 cabeca
   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 menos 1
     pts.push(coord[c].xx);
     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 evolvente1 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);
     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
}
 
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 menos 1
     pts.push(coord[c].yy);
}
cc=rr5;
rr1=rr5;//importantissimo a cada ciclo de repeticao o contador acumula-se e começa a fazer um novo 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 dos demais dentes

}//fecha função vai

vai();//primeira execução da função
//criação da polilinha ou sequencia direta de pontos
var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol.setAttributeNS(null,'points',pts);
    pol.setAttributeNS(null,'id','id2');
    document.documentElement.appendChild(pol);//adicionar a polylinha no documento
   
   
 var transforme = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");
     transforme.setAttributeNS(null,'attributeType', 'XML');
     transforme.setAttributeNS(null,'attributeName', 'transform');
     transforme.setAttributeNS(null,'type', 'rotate');
     transforme.setAttributeNS(null,'from', '0 240 240');//ângulo inicial e coordenadas de centro
     transforme.setAttributeNS(null,'to','360 240 240');//ângulo final e coordenadas de centro
     transforme.setAttributeNS(null,'dur', '10s');//duração
     transforme.setAttributeNS(null,'repeatCount', 'indefinite');//repetição
     document.getElementById('id2').appendChild(transforme);//insere na polyline


});
 ]]></script>
 </svg>


<iframe style="border-style: solid; border-width: 1px;" width="500" height="500" src="imgsvg/engr6.svg" scrolling="no"/><br>

Também pode-se testar o arquivo engr6.svg com um link como uma página HTML.
Link para engr6.svg


Discussão do Problema
A figura abaixo mostra uma possibilidade:

Figura22 (chanfro.jpg)

Etapa8
Na etapa7 a rotação da engrenagem foi através do atributo transforme, com isso quem está rotacionando é o elemento polyline (um quadrado), isso pode ser observado no GoogleChrome > Mais ferramentas > Ferramentas do desenvolvedor > Aba elements (clique no elemento polyline).
O interessante para simular a realidade de experimentos é girar todos os pontos do polyline individualmente e assim poder compará-los com outros pontos de outra engrenagem.
Alterações do código da Etapa7:
- O código engr6.svg executava a função vai() apenas uma vez, no código abaixo, engr6a.svg a função vai() será executada a cada 5000 milissegundos, para construir novamente a engrenagem precisamos inicializar novamente cada variável a cada execução da função vai(), portanto serão incluídas dentro dessa função as variáveis rr1 e pp e a lista pts. A função Points2D() pode ficar dentro da função ou acima dela.
Cada engrenagem que rotacionar terá uma lista de pontos, pts=[], por isso ela fica dentro da função vai, ou seja, localmente. Se ficasse fora teríamos apenas uma lista pts com todas as engrenagens que giram, neste caso teremos que acertar os índices dos pontos porque o primeiro índice é zero para cada lista e se utilizar apenas uma lista há um só índice zero.

- A rotação e centralização do pontos da engrenagem serão feitos através da aplicação da fórmula de rotação de pontos diretamente nas variáveis this.xx e this.yy da função Point2D(xx,yy), essas variáveis receberão as rotações dos parâmentros que derem entrada na chamada da função Point2D(?,?). Todos os pontos serão rotacionados e centralizados.
A funcao abaixo possui dois argumentos iguais as respectivas variaveis.

function Point2D(xx,yy) {
  this.xx = h+xx*Math.cos(g) - yy*Math.sin(g);
  this.yy = k+xx*Math.sin(g) + yy*Math.cos(g);
}
 
Obs:
this.xx e this.yy: variáveis da função com escopo igual a da função.
xx e yy: argumentos da função.
parâmetros: são valores de entrada na chamada da função.
h e k: centralização de todos os pontos. Não precisará mais fazer qualquer outra centralização.
 
- Repetição infinita (cuidado para não travar o navegador) da chamada da função vai() a cada 10000 milissegundos. A cada execução da função vai() a variável g é incrementada em 10, assim a rotação dos pontos serão acrescidos desse valor.

setInterval(function(){
vai();
g=g+10; //a cada execução da função o ângulo de giro global é incrementado em 10
}, 5000);//repetição infinita a cada intervalo de 5000 milissegundos
});

Código: engr6a.svg
<?xml version="1.0" standalone="no"?> <!--cabecalho-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="480px" height="480px" stroke="black" stroke-width="0.5px" id="id1">
  
<script type="application/ecmascript"><![CDATA[

document.addEventListener("DOMContentLoaded", function(event) {//O evento DOMContentLoaded sera acionado quando todo o HTML (apenas) for completamente carregado e analisado
//1mm sera considerado igual a 4pixels
var pts=[];//lista com todos os pontos do polyline 
var h = 240;//translacao da coordenada-x para centralizar no svg
var k = 240;//translacao da coordenada-y para centralizar no svg


var m=4*4; //1mm igual a 4px
var dp=100*4;//diâmetro primitivo de 100 milimettros
var z=dp/m;
var db = dp*Math.cos(20*Math.PI/180);
var p=(2*Math.PI)/z;//passo em radianos
var hc = m; //altura de cabeca do dente
var hf = 1.25*m;//altura do pé do odente
var ht = hf+hc;//altura toral do dente
var di = dp-2*hf;//diametro interno
var dc = (dp+2*hc);//diaametro de cabeca

var rb = db/2;//raio de base
var rc = dc/2;//raio de cabeca
var rp = dp/2;//raio do primitivo
var ri = di/2;//raio interno

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

var xmlns="http://www.w3.org/2000/svg";


//circulo interno
var cir1 = document.createElementNS(xmlns, "circle");
    cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
    cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
    cir1.setAttributeNS(null,'r', ri-50);//raio do circulo interno igual a ri-50 escolhido aleatoriamente
    cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
    cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento


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


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

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

var β = (p/2 - 2*θ2)/2;//é utilizado para achar o ângulo do arco de chanfro
var re=rb*Math.tan(β);
var 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;
}

g=0;  //variávvel global, ângulo de giro para todos os pontos

var c;//índice dos pontos e contador do loop for, fica de fora da função vai
var cc=0;//importantíssimo,  guarda o último valor do ciclo de criação de um dente (rr5) e passa passa a variável c que reinicia um novo ciclo de criação de um dente

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(g) - yy*Math.sin(g);
  this.yy = k+xx*Math.sin(g) + yy*Math.cos(g);

 
function vai(){ //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
//as variáveis dentro da função serão inicializadas a cada nova execução da função
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 lista pts, para cada ciclo rr1 é cumulativo
pts=[];//cada engrenagem terá uma lista de pontos, por isso ela fica dentro da função vai, ou seja, localmente. Se ficasse fora teríamos apenas uma lista pts para todas as engrenagens que giram
 
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 menos 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);
     pts.push(coord[c].yy);
}

//evolvente2 e rotacao
rr2=rr1; //contador de ciclo do loop é o próximo indice depois de rr1 menos 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
     pts.push(coord[c].xx);
     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 menos 1
     pts.push(coord[c].xx);
     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 evolvente1 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);
     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
}
 
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 menos 1
     pts.push(coord[c].yy);
}
cc=rr5;
rr1=rr5;//importantissimo a cada ciclo de repeticao o contador acumula-se e começa a fazer um novo 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 dos demais dentes 

//criação da polilinha ou sequencia direta de pontos

var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol.setAttributeNS(null,'points',pts);
    pol.setAttributeNS(null,'id','id2');
    document.documentElement.appendChild(pol);//adicionar a polylinha no documento

}//fecha função vai

setInterval(function(){
vai();
g=g+10; //a cada execução da função o ângulo de giro global é incrementado em 10
}, 5000);//repetição infinita a cada intervalo de 5000 milissegundos
});

 ]]></script>
 </svg>


<iframe style="border-style: solid; border-width: 1px;" width="500" height="500" src="imgsvg/engr6a.svg" scrolling="no"/><br>

Também pode-se testar o arquivo engr6a.svg com um link como uma página HTML.
Link para engr6a.svg

Etapa9
Após conseguirmos girar individualmente os pontos da polyline precisamos apagar a polyline anterior a cada execução da função vai(), isso é feito com o método setInterval().

Alteração do código engr6a.svg:
- Precisa executar a função pela primeira vez para inicializar as variáveis e construir a engrenagem sem nenhuma rotação:
vai();//primeira execução da função

- Remover a polyline da primeira execução, incrementar o ângulo de rotação (g=g+1) e chamar novamente a variável vai():
vai();
setInterval(function(){
var polilinha = document.getElementById('id2'); //remoção da polyline
var pai = polilinha.parentNode;
pai.removeChild(polilinha);
g=g+0.01;//incremento do ângulo de giro global
vai();//nova execução da função
}, 100);//repetição infinita a cada intervalo de 100 milissegundos

Código: engr6b.svg (está todo comentado)
<?xml version="1.0" standalone="no"?> <!--cabecalho-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="480px" height="480px" stroke="black" stroke-width="0.5px" id="id1">
  
<script type="application/ecmascript"><![CDATA[

document.addEventListener("DOMContentLoaded", function(event) {//O evento DOMContentLoaded sera acionado quando todo o HTML (apenas) for completamente carregado e analisado
//1mm sera considerado igual a 4pixels
var pts=[];//lista com todos os pontos do polyline 
var h = 240;//translacao da coordenada-x para centralizar no svg
var k = 240;//translacao da coordenada-y para centralizar no svg


var m=4*4; //1mm igual a 4px
var dp=100*4;//diâmetro primitivo de 100 milimettros
var z=dp/m;
var db = dp*Math.cos(20*Math.PI/180);
var p=(2*Math.PI)/z;//passo em radianos
var hc = m; //altura de cabeca do dente
var hf = 1.25*m;//altura do pé do odente
var ht = hf+hc;//altura toral do dente
var di = dp-2*hf;//diametro interno
var dc = (dp+2*hc);//diaametro de cabeca

var rb = db/2;//raio de base
var rc = dc/2;//raio de cabeca
var rp = dp/2;//raio do primitivo
var ri = di/2;//raio interno

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

var xmlns="http://www.w3.org/2000/svg";


//circulo interno
var cir1 = document.createElementNS(xmlns, "circle");
    cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
    cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
    cir1.setAttributeNS(null,'r', ri-50);//raio do circulo interno igual a ri-50 escolhido aleatoriamente
    cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
    cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento


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


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

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

var β = (p/2 - 2*θ2)/2;//é utilizado para achar o ângulo do arco de chanfro
var re=rb*Math.tan(β);
var 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;
}

g=0;  //variávvel global, ângulo de giro para todos os pontos

var c;//índice dos pontos e contador do loop for, fica de fora da função vai

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(g) - yy*Math.sin(g);
  this.yy = k+xx*Math.sin(g) + yy*Math.cos(g);

 
function vai(){ //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
//as variáveis dentro da função serão inicializadas a cada nova execução da função
var cc=0;//importantíssimo,  guarda o último valor do ciclo de criação de um dente (rr5) e passa passa a variável c que reinicia um novo ciclo de criação de um dente
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 lista pts, para cada ciclo rr1 é cumulativo
pts=[];//cada engrenagem terá uma lista de pontos, por isso ela fica dentro da função vai, ou seja, localmente. Se ficasse fora teríamos apenas uma lista pts para todas as engrenagens que giram
 
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 menos 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);
     pts.push(coord[c].yy);
}

//evolvente2 e rotacao
rr2=rr1; //contador de ciclo do loop é o próximo indice depois de rr1 menos 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
     pts.push(coord[c].xx);
     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 menos 1
     pts.push(coord[c].xx);
     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 evolvente1 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);
     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
}
 
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 menos 1
     pts.push(coord[c].yy);
}
cc=rr5;
rr1=rr5;//importantissimo a cada ciclo de repeticao o contador acumula-se e começa a fazer um novo 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 dos demais dentes 

//criação da polilinha ou sequencia direta de pontos

var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol.setAttributeNS(null,'points',pts);
    pol.setAttributeNS(null,'id','id2');
    document.documentElement.appendChild(pol);//adicionar a polylinha no documento

}//fecha função vai

vai();//primeira execução da função
setInterval(function(){
var polilinha = document.getElementById('id2'); //remoção da polyline
var pai = polilinha.parentNode;
pai.removeChild(polilinha);
g=g+0.01;//incremento do ângulo de giro global
vai();//nova execução da função
}, 100);//repetição infinita a cada intervalo de 100 milissegundos
});
 ]]></script>
 </svg>




<iframe style="border-style: solid; border-width: 1px;" width="500" height="500" src="imgsvg/engr6b.svg" scrolling="no"/><br>

Também pode-se testar o arquivo engr6b.svg com um link como uma página HTML.
Link para engr6b.svg


Etapa10
Esta rotação é feita diretamente no atributo da polyline após sua criação, a vantagem é que há apenas a criação de uma polyline, ou seja, não precisa removê-la a cada nova rotação.

Alteração do código engr5.svg:
A rotação é sempre feita tendo a origem do sistema de coordenadas como centro. Após a rotação é feita a translação para centralização do polyline no SVG.

Esta translação abaixo refere-se a centralização dos pontos da polyline no SVG, porém ainda de forma estática (sem rotação):
for(i=0;i<=pts.length-2;i=i+2){// translação para o centro do svg
pts[i]=pts[i]+h;
pts[i+1]=pts[i+1]+k;
}

Simples criação da polyline:
  var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol.setAttributeNS(null,'id','id2');
    pol.setAttributeNS(null,'points',pts);
    document.documentElement.appendChild(pol);//adicionar a polylinha no documento 

Rotação direta da polyline:
setInterval(function(){ 
pts2=[];
gg2=0.05;//rotação constante, não precisa de incremento

for(i=0;i<=pts.length-2;i=i+2){ //translação para a origem do sistema de coordenadas do svg
pts[i]=pts[i]-h;                       //essa translação é obrigatória para que a rotação seja em torno de si mesmo
pts[i+1]=pts[i+1]-k;
}

for(i=0;i<=pts.length-2;i=i+2){
var    x=pts[i]*Math.cos(gg2) - pts[i+1]* Math.sin(gg2); //rotação dos pontos
pts2.push(x);
var   y=pts[i]* Math.sin(gg2) + pts[i+1]* Math.cos(gg2);
pts2.push(y);
}
pts=pts2;

for(i=0;i<=pts.length-2;i=i+2){//translação para o centro do svg
pts[i]=pts[i]+h;
pts[i+1]=pts[i+1]+k;
}

pol.setAttributeNS(null,'points',pts);
},200);

Código: engr6c.svg (está todo comentado)
<?xml version="1.0" standalone="no"?> <!--cabecalho-->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" width="480px" height="480px" stroke="black" stroke-width="0.5px" id="id1">
  
<script type="application/ecmascript"><![CDATA[

document.addEventListener("DOMContentLoaded", function(event) {//O evento DOMContentLoaded sera acionado quando todo o HTML (apenas) for completamente carregado e analisado
//1mm sera considerado igual a 4pixels
var h = 240;//translacao da coordenada-x para centralizar no svg
var k = 240;//translacao da coordenada-y para centralizar no svg

var m=4*4; //1mm igual a 4px
var dp=100*4;//diâmetro primitivo de 100 milimettros
var z=dp/m;
var db = dp*Math.cos(20*Math.PI/180);
var p=(2*Math.PI)/z;//passo em radianos
var hc = m; //altura de cabeca do dente
var hf = 1.25*m;//altura do pé do odente
var ht = hf+hc;//altura toral do dente
var di = dp-2*hf;//diametro interno
var dc = (dp+2*hc);//diaametro de cabeca

var rb = db/2;//raio de base
var rc = dc/2;//raio de cabeca
var rp = dp/2;//raio do primitivo
var ri = di/2;//raio interno

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

var xmlns="http://www.w3.org/2000/svg";


//circulo interno
var cir1 = document.createElementNS(xmlns, "circle");
    cir1.setAttributeNS(null,'cx', h);//coordenada-x do centro
    cir1.setAttributeNS(null,'cy', k);//coordenada-y do centro
    cir1.setAttributeNS(null,'r', ri-50);//raio do circulo interno igual a ri-50 escolhido aleatoriamente
    cir1.setAttributeNS(null,'fill','none');//importante para ser uma circunferencia
    cir1.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
document.documentElement.appendChild(cir1);//adicionar o circulo no documento


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


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

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

var β = (p/2 - 2*θ2)/2;//é utilizado para achar o ângulo do arco de chanfro
var re=rb*Math.tan(β);
var 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 c;//índice dos pontos e contador do loop for, fica de fora da função vai
var cc=0;//importantíssimo,  guarda o último valor do ciclo de criação de um dente (rr5) e passa passa a variável c que reinicia um novo ciclo de criação de um dente

pts=[];//lista de pontos, fica fora da função vai assim é acessível globalmente  
function vai(){ //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
//as variáveis dentro da função serão inicializadas a cada nova execução da função
  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 lista pts, para cada ciclo rr1 é cumulativo


function Point2D(xx,yy) {//funcao com dois argumentos iguais as respectivas variaveis
//todos os pontos serão rotacionados e centralizados
  this.xx = xx;
  this.yy = yy;
 

   
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 menos 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);
     pts.push(coord[c].yy);
}

//evolvente2 e rotacao
rr2=rr1; //contador de ciclo do loop é o próximo indice depois de rr1 menos 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
     pts.push(coord[c].xx);
     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 menos 1
     pts.push(coord[c].xx);
     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 evolvente1 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);
     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
}
 
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 menos 1
     pts.push(coord[c].yy);
}
cc=rr5;
rr1=rr5;//importantissimo a cada ciclo de repeticao o contador acumula-se e começa a fazer um novo 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 dos demais dentes


for(i=0;i<=pts.length-2;i=i+2){// translação para o centro do svg
pts[i]=pts[i]+h;
pts[i+1]=pts[i+1]+k;
}

  var pol = document.createElementNS(xmlns, "polyline");//cria uma polilinha
    pol.setAttributeNS(null,'stroke-width', '1px');//formata a espessura da linha
    pol.setAttributeNS(null,'fill','none');//importante para o polyline ser umalinha       
    pol.setAttributeNS(null,'id','id2');
    pol.setAttributeNS(null,'points',pts);
    document.documentElement.appendChild(pol);//adicionar a polylinha no documento 

setInterval(function(){ 
pts2=[];
gg2=0.05;

for(i=0;i<=pts.length-2;i=i+2){ //translação para a origem do sistema de coordenadas do svg
pts[i]=pts[i]-h;                       //essa translação é obrigatória para que a rotação seja em torno de si mesmo
pts[i+1]=pts[i+1]-k;
}

for(i=0;i<=pts.length-2;i=i+2){
var    x=pts[i]*Math.cos(gg2) - pts[i+1]* Math.sin(gg2); //rotação dos pontos
    pts2.push(x);
 var   y=pts[i]* Math.sin(gg2) + pts[i+1]* Math.cos(gg2);
    pts2.push(y);
}
pts=pts2;

for(i=0;i<=pts.length-2;i=i+2){//translação para o centro do svg
pts[i]=pts[i]+h;
pts[i+1]=pts[i+1]+k;
}

pol.setAttributeNS(null,'points',pts);
},200);

}//fecha função vai 

vai();
});
 ]]></script>
 </svg>




<iframe style="border-style: solid; border-width: 1px;" width="500" height="500" src="imgsvg/engr6c.svg" scrolling="no"/><br>

Também pode-se testar o arquivo engr6c.svg com um link como uma página HTML.
Link para engr6c.svg

Com esse último arquivo é possível acessar cada ponto da imagem desenhada e programá-lo conforme nossa necessidade. Assim é possível continuar o desenvolvimento do código em direção a simulações reais de movimentos, choques, etc.