Roues dentées

De wiki jackbot
Aller à la navigation Aller à la recherche

Les roues dentées sont des systèmes mécaniques, elles sont utilisées dans des engrenages afin de créer des transmissions de puissance. Les différentes illustrations ont été réalisées avec le logiciel OpenSCAD et geogebra

Pour bien comprendre comment fonctionnent les engrenages il peut être bon de manipuler différents système, c'est ce que propose ce site, il contient également beaucoup d'informations utiles concernant les rapports, le couple etc ...

Dans la suite de ce wiki, je ne vais pas revenir sur les notions abordés sur le site https://ciechanow.ski/gears/, mais me concentrer sur la partie modélisation afin de pouvoir générer des modèles imprimable en 3D. Une façon alternative de modéliser se trouve sur ce site.

Paramètres

On va lister ici les paramètres qui vont permettre de définir une roue dentée. Il faut distinguer deux types de paramètres, les paramètres de bases, sans qui on ne peut rien faire et les paramètres que l'on va déduire des paramètres de bases.

Paramètres de base

Le module

Noté , il s'agit du paramètre centrale des transmissions mécaniques. Il représente la taille des dents. De ce fait on comprend assez facilement qu'il est nécessaire que les différents éléments qui vont devoir s'engrainer doivent avoir le même module.

L'angle de pression

Noté cet angle correspond à la partie bleue sur cette crémaillère

Cremaillere angle alpha.png

Le nombre de dents

Noté , je ne pense pas qu'il soit nécessaire de s'étendre sur ce paramètre.

Paramètres déduis

Une fois en possession de , et , nous pouvons définir entièrement une crémaillère ou une roue dentée. Cependant afin de modéliser ces éléments, il va nous falloir quelques informations supplémentaires.

Le pas

Sur une crémaillère, le pas est la distance pour laquelle le motif se répète, on peut faire le parallèle avec les phénomène oscillant et ce qui est appelé longueur d'onde. On le note et il correspond à :

avec le module et la constante mathématique (3.1415...)

La hauteur de la dent

La hauteur, noté , d'une dent est en réalité composé de deux paramètres

  • la saillie noté
  • le creux noté

avec le module

Dans le cas où le module est inférieur à 1.25 on a :

Dans le cas contraire on a :

La hauteur totale de la dent étant définie par :

Le diamètre de la roue

Comme précédemment on va faire la distinction entre différents diamètres :

  • le diamètre de tête noté
  • le diamètre primitif noté
  • le diamètre de pied noté
  • le diamètre de base noté

Le diamètre primitif correspond à :

Il est à noter que sur le cercle primitif, la largeur d'une dent est d'un demi-pas. C'est également ce cercle qui est utilisé pour les calculs de rapport de transmission, car sur ce cercle les différents éléments possèdent la même vitesse linéaire.

Vu que l'on travaille sur des diamètres, pour trouver le diamètre de tête il est nécessaire d'ajouter deux fois la saillie de la dent.

Pour des raisons identiques on a pour le diamètre de pied :

le diamètre de base sert à générer la développante de cercle qui servira de profil pour les dents.

Récapitulatif

  • , le module, qui caractérise la largeur de la dent et ainsi la couple maximal transmissible
  • , l'ange de pression, qui joue sur l'inclinaison des dents
  • , le nombre de dents
  • , le pas définissant la distance de répétition
  • , la saillie de la dent. Partie qui sera au-dessus du cercle primitif
  • , le creux de la dent. Partie qui sera en-dessous du cercle primitif
    • si alors
    • si alors
  • , la hauteur de la dent
  • , le diamètre primitif de la roue
    • Sur le cercle de diamètre d (cercle primitif), la largeur d'une dent est de
    • Sur le cercle primitif, les éléments possèdent la même vitesse linéaire
  • , le diamètre de tête de la roue
  • , le diamètre de pied de la roue
  • , permet la génération de la développante de cercle d'équation :


La crémaillère

Maintenant que nous avons listé tous les paramètres, nous allons commencer avec l'exemple le plus simple : la crémaillère, une simple rangée de dents. Les connaissances de bases de la trigonométrie suffisent à calculer tous les points nécessaires à la modélisation d'une crémaillère.

Cremaillere.png

Sachant que sur le trait vert (), la dent à une largeur de , on peut déduire que la base de la dent a une largeur de :

Dans Openscad on peut donc écire :

function creux(m = 1) = m <= 1.25 ? 1.4*m : 1.25*m;

module dent_cremaillere_2D(m = 1, alpha = 20)
{
    //hauteurs
    hf = creux(m);
    ha = m;
    h = hf + ha;
    
    //pas
    p = m*PI;

    largeur_base = 2*hf*tan(alpha) + p/2;
    polygon([ [0, 0], [h*tan(alpha), h], [largeur_base - h*tan(alpha), h], [largeur_base, 0] ]);
}

Avec ce module on peut modéliser UNE dent de crémaillère. Pour modéliser une crémaillère entière, on va simplement appeler ce module autant de fois qu'on veut de dents.

module cremaillere_2D(z = 10, m = 1, alpha = 20, largeur = 10)
{
    //hauteurs
	hf = creux(m);
    
    //pas
    p = m*PI;
    
    union()
    {
        //corps de la crémaillère
        translate([0, -largeur, 0])
        {square([p* (z - 1) + p/2 + 2*hf*tan(alpha), largeur]);}
        
        //dents de la crémaillère
        for(i=[0:z-1])
		{
            translate([p*i, 0, 0])
            {dent_cremaillere_2D(m, alpha);}
        }
    }
}

Pour l'instant la modélisation est en 2D, pour obtenir un modèle 3D il suffit d'utiliser la fonction linear_extrude d'OpenSCAD.

module cremaillere_3D(z = 10, m = 1, alpha = 20, largeur = 10, epaisseur = 3)
{
    linear_extrude(epaisseur)
    {cremaillere_2D(z, m, alpha, largeur);}
}

Roue dentée

Profil d'une dent

Le profil d'une dent doit posséder une courbure bien particulière. Pour éviter les efforts sur l'axe de rotation, il faut que les normales restent tangentes à un cercle fixe. Une courbe possédant cette caractéristique est la développante de cercle, plus d'information ici. L'équation d'une telle courbe est :

Dans OpenSCAD on peut écrire les fonctions suivantes :

function developpante_x(r = 1, t = 0) = r*(cos(t)+rad(t)*sin(t));
function developpante_y(r = 1, t = 0) = r*(sin(t)-rad(t)*cos(t));

Intersection avec la développante de cercle

Maintenant que nous pouvons tracer une développante de cercle, il faut trouver quelle est la portion de cette courbe que l'on va utiliser pour générer la dent. Bien entendu on commencera à générer la dent pour , mais quelle est la valeur maximale de  ?

Première limite

La première limite très intuitive est que la dent ne doit pas dépasser le cercle de tête. Il faut donc dans un premier temps trouver la valeur de pour laquelle la développante de cercle intersecte le cercle de tête .

Intersection developpante.png

Le point appartenant à la développante ses coordonnées sont , or est le rayon du cercle de tête. En appliquant le théorème de Pythagore on obtient :

On peut maintenant écrire les différentes fonctions dans notre fichier OpenSCAD en n'oubliant pas que ce logiciel fonctionne avec des angles en degré, il ne faut donc pas oublier les fonctions de conversion :

//Fonctions de conversion
function rad(angle = 0) = PI * angle / 180;
function degre(angle = 0) = angle * 180 / PI;

function intersect_rad(r=1, R=2) = sqrt( (R*R)/(r*r) - 1);
function intersect(r=1, R=2) = degre(intersect_rad(r, R));

On peut donc calculer la limite de la dent avec :

Ida = intersect(db, da);

Deuxième limite

Un peu moins évident, dans certains cas il arrive que le point d'intersection calculé précédemment dépasse l'axe de symétrie de la dent. Cependant pour pouvoir établir cette deuxième limite il va nous falloir d'abord calculer l'angle formé par la base de la dent.

Angle à la base de la dent

On peut donc maintenant dessiner un bord d'une dent, pour dessiner la dent complète il faut connaître la largeur à la base de la dent. Pour y arriver il faut faire comme pour la crémaillère sauf que dans ce cas c'est avec des angles qu'il faudra travailler.

Angle base dent.png

Nous cherchons l'angle : Le point est le point d'intersection du cercle primitif avec la développante de cercle. La longueur de l'arc de cercle . Or si on considère l'angle en radian on peu écrire :

Pour l'angle , il faut en premier lieu calculer les coordonnées du point , chose que l'on peut obtenir facilement en utilisant la fonction écrite à l'étape précédente :

Id = intersect(db, d);

Idx = developpante_x(db/2,Id);
Idy = developpante_y(db/2,Id);

Avec un peu de trigonométrie on déduit que :

Et donc dans OpenSCAD :

angle = atan2(Idy, Idx);
angle_base = degre(p/d) + 2*angle;

Deuxième limite

Nous pouvons maintenant revenir sur notre deuxième limite. Mais avant de commencer faisons un petit schéma pour voir où nous en sommes :

Dent.png

Sur ce schéma cela devient évident, inutile de continuer la développante de cercle jusqu'au cercle de tête. Pour calculer l'intersection entre une développante de cercle et un cercle c'était relativement facile, théorème de Pythagore, quelques notions de trigonométrie et ça passe. Ici pour calculer l'intersection d'une droite avec la développante de cercle il va falloir ajouter quelques segments et ruser un peu.

Intersection symetrie.png

Le triangle en rouge va nous permettre de résoudre le problème. Faisons la liste de ses propriétés intéressantes :

  1. Le segment est le rayon du cercle de base
  2. La droite est tangente au cercle de base
  3. La longueur du segment est proportionnelle au paramètre de la développante de cercle :
  4. L'angle (en radian) est le paramètre de la développante de cercle
  5. L'angle est la moitié de l'angle de base de la dent

Commençons à faire quelque déductions de tout ceci :

  • d'après 2. et sont perpendiculaire et donc le triangle est rectangle en
  • Vu que le triangle est rectangle on peut écrire :
  • L'angle que nous devons trouver est : car

Mais là, petit problème je ne sais pas trouver la solution de cette équation. Cependant, tout n'est pas perdu, car on peut ajouter une condition dans la boucle for dans OpenSCAD.

if( i < angle_base/2 + acos( sqrt( 1/(1 + rad(i) * rad(i)))) )

Construction de la dent

Le but de l'opération est de créer un polygone dont les cotés sont définies par la développante de cercle ainsi que les paramètres trouvés aux étapes précédentes. Pour ce faire nous utilisons une boucle for

A = [ for(i=[0: ceil(Ida)])
if( i < angle_base/2 + acos( sqrt( 1/(1 + rad(i) * rad(i)))) )
[developpante_x(db/2,i), developpante_y(db/2,i)] ];

La variable A contient une série de points définie par la développante de cercle, selon les cas ça sera soit jusqu'au cercle de tête, soit jusqu'à l'axe de symétrie. Pour obtenir les points de l'autre coté, il faut dans un premier temps créer une matrice de rotation et parcourir les points dans l'autre sens :

Matrice_de_rotation = [ [cos(angle_base), -sin(angle_base)], [sin(angle_base), cos(angle_base)] ];

B = [ for(i=[floor(-Ida):0])
if( i > -angle_base/2 - acos( sqrt( 1/(1 + rad(i) * rad(i)))) ) 
Matrice_de_rotation*[developpante_x(db/2,i), developpante_y(db/2,i)] ];

La matrice de rotation va nous permettre de tourner toute la courbe et ainsi obtenir la largeur de la dent voulue. Le polygone complet s'obtient en concaténant les deux ensembles de points.

C = concat(A, B);

Si on teste tout ça on peut s'apercevoir d'un problème :

Mauvaise roue dentee.png

Les dents ne touchent pas la roue. Cela arrive quand il y a trop peu de dents, essayer de combler ce vide n'est pas la meilleure solution. Car en essayant de rectifier la roue, il pourra arriver que les dents de la roue rectifiée se fassent "attaquer" par les dents de l'autre éléments au niveau de leur base. Pouvant générer alors une usure prématuré ou une rupture. Pour palier à ce problème on peut jouer sur plusieurs paramètres :

  • le nombre de dents
  • l'angle de pression
  • faire un déport de denture.

Pour faire simple, un déport de denture est un décalage de la dent jusqu'à ce quelle touche le cercle de pied. Pour y arriver on va devoir modifier la saillie, le creux ainsi que la largeur de la dent sur le cercle primitif. Cependant cette modification ne change en rien le cercle primitif ou l'entraxe.

//hauteurs
hf = creux(m) - deport;
ha = m + deport;

//largeur de la dent sur le cercle primitif
l = p/2 + 2*deport*sin(alpha);

ATTENTION !! Ce paramètre doit être utilisé avec précaution car le diamètre du cercle primitif, ainsi que l'entraxe ne changeront pas, de ce fait un déport trop grand peut occasionner un mauvais fonctionnement. En pratique on le limite à :

Récapitulatif

function developpante_x(r = 1, t = 0) = r*(cos(t)+rad(t)*sin(t));
function developpante_y(r = 1, t = 0) = r*(sin(t)-rad(t)*cos(t));

//Fonctions de conversion
function rad(angle = 0) = PI * angle / 180;
function degre(angle = 0) = angle * 180 / PI;

function intersect_rad(r=1, R=2) = sqrt( (R*R)/(r*r) - 1);
function intersect(r=1, R=2) = degre(intersect_rad(r, R));

module roue_dentee_2D(z = 40, m = 1, alpha = 20, deport = 0)
{    
    //hauteurs
    hf = creux(m) - deport;
    ha = m + deport;
    
    //pas
    p = m*PI;
    
    //calcul des diamètres
    d = m * z;
    db = d * cos(alpha);
    df = d - 2*hf;
    da = d + 2*ha;
    
    //calcul de l'angle entre 2 dents
    angle_dent = 360 / z;
    
    //largeur de la dent sur le cercle primitif
    l = p/2 + 2*deport*sin(alpha);
    
    //angle de la dent sur le cercle primitif
    la = degre(2*l/d);
    
    //paramètre d'intersection de la developpante avec le cercle primitif
    //Id = intersect(db/2, d/2); équivalent à :
    Id = intersect(db, d);
    Idx = developpante_x(db/2,Id);
    Idy = developpante_y(db/2,Id);
    
    //angle entre la base de la dent et l'intersection avec le cercle primitif
    angle = atan2(Idy, Idx);
    //angle de la dent à sa base
    angle_base = la + 2*angle;
    
    //paramètre d'intersection de la developpante avec le cercle de tête
    //Ida = intersect(db/2, da/2); équivalent à :
    Ida = intersect(db, da);

    //GENERATION DE LA DENT
    
    A = [ for(i=[0: ceil(Ida)])
           if( i < angle_base/2 + acos( sqrt( 1/(1 + rad(i) * rad(i)))) )
           [developpante_x(db/2,i), developpante_y(db/2,i)] ];
    
    Matrice_de_rotation = [ [cos(angle_base), -sin(angle_base)], [sin(angle_base), cos(angle_base)] ];
    
    //Pour continuer le polygone il faut parcourir les valeurs dans l'autre sens
    B = [ for(i=[floor(-Ida):0])
          if( i > -angle_base/2 - acos( sqrt( 1/(1 + rad(i) * rad(i)))) ) 
          Matrice_de_rotation*[developpante_x(db/2,i), developpante_y(db/2,i)] ];
                        
    C = concat(A, B);

    union()
    {
        //pied de la dent
        circle(d=df);

        for(j = [0:1:z-1])
        {
            rotate([0, 0, j*angle_dent])
            {polygon(C);}
        }
    }
}

De même que pour la crémaillère on obtient ici un modèle en deux dimension, pour passer à la 3D il suffit d'extruder ce modèle :

module roue_dentee_3D(z = 50, m = 1, alpha = 20, epaisseur = 2, deport = 0)
{
    linear_extrude(epaisseur)
    {roue_dentee_2D(z,m,alpha, deport);}
}

Roue dentée hélicoïdale

Maintenant que nous savons modéliser une roue dentée droite, on va chercher à comprendre ce qu'il faut changer pour obtenir ceci :

Pour comprendre il faut regarder cette magnifique illustration que j'ai trouvé à cette adresse.

Engren15.jpg

On a donc deux façon de regarder le profil d'une dent

  • soit dans le plan perpendiculaire à l'axe de rotation
  • soit dans le plan perpendiculaire aux dents

Pour pouvoir réutiliser le travail effectué avant, il faut donc qu'on s'intéresse aux grandeurs apparentes. Et plus précisément au module et à l'angle de pression. On obtiendra ceci :

ma = m/cos(beta);
alpha_a = atan2(tan(alpha),cos(beta));

Dans openscad la fonction linear_extrude possède un paramètre twist. Cependant vous allez comprendre qu'il ne correspond pas à l'angle . Il va donc falloir faire quelques petits calculs de conversion.

Ici vous pouvez voir deux carrés extrudés, dans les deux cas, le paramètre twist vaut 90°, mais dans le premier cas on extrude sur 10mm alors que dans le second sur 20mm. Le paramètre twist représente en fait la différence d'orientation entre le début et la fin de l'extrusion. Les angles formés par les sommets des carrés ne sont pas les mêmes. On va donc devoir chercher quelle est la valeur de twist pour obtenir l'angle

Calcul twist.png

Je tiens à préciser que cette illustration n'est pas juste, car est en réalité un arc de cercle. Cependant elle permet de voir de quoi on parle. Si on travail en radian alors on a l'égalité Si on déroulait cette roue dentée alors on aurait : et donc . On obtient donc :

et donc :

Dans OpenSCAD ça donne :

module roue_dentee_helicoidale(z = 50, m = 1, alpha = 20, beta = 45, epaisseur = 20, deport = 0)
{
	ma = m/cos(beta);
    alpha_a = atan2(tan(alpha),cos(beta));
    angle = degre(epaisseur*tan(beta)/(ma*z/2));

	linear_extrude(height = epaisseur, twist = angle, slices = epaisseur/2)
	{roue_dentee_2D(z, ma, alpha_a, deport);}
}

Pour que ce genre de roue puisse s'engrainer il faut obligatoirement qu'elles possèdent le même module réel ainsi que la même valeur absolue de l'angle , donc soit ou alors .

Roue en chevron

Si vous avez réussi à suivre jusque là, alors petite pause avec les roues en chevrons. Il s'agit juste de deux roues hélicoïdales posées l'une sur l'autre.

module roue_dentee_chevron(z = 40, m = 1, alpha = 20, beta = 30, epaisseur = 10, deport = 0)
{
    //ici les calculs des paramètres apparents ne servent qu'à aligner correctement les deux roues
    ma = m/cos(beta);
    angle = degre(epaisseur*tan(beta)/(ma*z/2));
	
    roue_dentee_helicoidale(z, m, alpha, beta, epaisseur/2, deport);
    
    translate([0, 0, epaisseur/2])
    {
        rotate([0, 0, -angle/2])
        {roue_dentee_helicoidale(z, m, alpha, -beta, epaisseur/2, deport);}
    }
}

Engrenage roue plus vis sans fin

Si vous n'avez pas encore fait de pause, c'est peut-être le moment parce qu'on va attaquer un gros morceau ! Les systèmes de roue et vis sans fin permettent un rapport de réduction important ainsi qu'un "verrouillage" car suivant l'angle d'hélice la roue ne pourra pas faire tourner la vis. Cependant la modélisation d'un tel système requiert un peu plus de calcul et le respect de certaines contraintes.

  • l'angle , il est nécessaire que
  • le pas axial de la vis doit être égal au pas apparent de la roue
  • pour améliorer l'engrainement entre la roue et la vis on peut avoir recourt à une roue globoïde

Vis sans fin

Si on décide de modéliser une vis sans fin, autant créer un module générique, qui nous permettra également de générer par exemple des vis métriques.

Coupe vis.png

Sur cette illustration on voit la coupe d'une vis, dans le plan XZ. On obtiendra une vis en faisant tourner ce profil autour de l'axe Z et en amenant le point sur le point . Mais avant de s'attaquer à la génération de la vis, posons les notations afin que ça soit bien clair dans la suite.

  • ...
  • est la distance selon l'axe Z entre les points et
  • est la distance selon l'axe Z entre les points et
  • est la distance selon l'axe Z entre les points et

La coupe d'une dent possède une symétrie, il sera donc facile de retrouver certaines distances, on utilisera donc la largeur de tête et la largeur de la saillie en guise de paramètre pour notre module :

module vis(diam_int = 4, diam_ext = 6, largeur_saillie = 1, largeur_tete = 0.8, pas = 3, haut = 10, precision = 5, diam_buse = 0.4)

Sur le principe, rien de sorcier. Cependant, autant faire les choses bien ! C'est à dire, ne générer que les points nécessaire et uniquement ceux là et c'est bien ça qui compliquera la modélisation. Car une autre façon de faire, plus simple, serait de faire tourner tous ces points sur une distance plus grande que celle voulue, puis de couper la vis pour obtenir la bonne longueur. Mais dans ce cas il y aura des points et des opérations supplémentaires, c'est à dire un rendu plus long car plus de calcul. Il faut donc bien réfléchir en amont, sur la position de départ de chaque point, combien de tours effecturont-ils, ainsi que d'autres petits détails.


Ordre d'apparition des points

En regardant l'illustration plus haut, on se doute bien que si on commence par le point , il n'y aura aucun autre point en dessous pour fermer la vis et donc la première dent commencera de manière abrupte. Il est donc nécessaire de commencer par le dernier point de la dent, c'est à dire . Pour générer ces points on utilisera une boucle for du type :

for(i=[angle_debut : precision : angle_fin]) [ rayon*cos(i), rayon*sin(i), i*pas/360]

Avec i l'angle, en degré, dans le plan XY et precision le pas angulaire.

Imaginons qu'on commence avec le point et qu'on pose que pour . Le point aura donc pour coordonnées :

On remarque que le point aura des coordonnées sur l'axe Z négative, or pour obtenir une coupe propre il faut le contraindre dans un premier temps à jusqu'à ce que . On peut facilement trouver cet angle sachant que :

Donc l'angle pour lequel on a est :

Pour tout angle supérieur on aura :

On posera donc :

C_lim_basse = 360*Zcd/pas;

C'est pour cet angle là que les points commenceront à émerger. Mais pour des raisons pratiques on fera en sorte que l'angle de départ de ces points soit un multiple du paramètre precision. On posera donc :

B_debut = ceil(C_lim_basse/precision)*precision;

Pour des raisons identiques aux précédentes les points devront être contraint à jusqu'à l'angle :

B_lim_basse = 360*Zbd/pas;

Il en va de même pour les points

A_debut = ceil(B_lim_basse/precision)*precision;
A_lim_basse = 360*Zad/pas;

Mais là on se rend compte qu'aucun point ne se trouvera sous ces points et que la vis ne pourra pas être fermée correctement. Il faut donc revenir sur la définition établie du point et le faire commencer afin qu'il se trouve sous ce point ce qui nous donne :

D_debut = floor(A_lim_basse/precision)*precision + precision - 360;

Et on lui impose d'être contraint à jusqu'à pour être raccord avec ce qu'on a écrit au début.

D_lim_basse = 0;

En résumé on a :

C_debut = precision;												//Le point C commence sur le pas d'après, cependant il doit émerger progressivement
C_lim_basse = 360*Zcd/pas;											//jusqu'a ce que Zc > 0
B_debut = ceil(C_lim_basse/precision)*precision;					//à ce moment le point B peut commencer à apparaitre, mais contraint à Zb = 0
B_lim_basse = 360*Zbd/pas;											//jusqu'à ce que Zb > 0
A_debut = ceil(B_lim_basse/precision)*precision;					//à ce moment le point A peut commencer à apparaitre, mais contraint à Za = 0
A_lim_basse = 360*Zad/pas;											//jusqu'à ce que Za > 0
D_debut = floor(A_lim_basse/precision)*precision + precision - 360;	//Le point D[0] doit être juste sous le point A tel que Za > 0
D_lim_basse = 0;													//On aura Zd > 0 pour un angle de 0°

Nous savons donc maintenant pour quel valeur de chaque point commencera et jusqu'à quel valeur ils devront être contraint à

Disparition des points

On retrouve un problème similaire en haut de la vis, car les arrêter dès qu'ils atteignent fera que pour certains point il ne sera pas possible de trouver un point pour fermer la vis correctement. Il est donc nécessaire d'appliquer le même raisonnement afin de faire continuer les points mais en les contraignant à

Les points seront les premiers à atteindre le sommet de la vis, et pour être plus précis ils l'atteindront quand :

On notera donc :

D_lim_haute = 360*haut/pas;

À partir de cet angle ils seront contraint à , mais devront continuer jusqu'à ce que les points atteignent eux aussi , ce qui arrivera pour l'angle :

On notera donc :

D_fin = 360*(haut + Zcd)/pas;

Angle qui comme on l'a dit, correspont à , la limite haute des points est donc toute trouvée :

C_lim_haute = D_fin;

On continue le même raisonnement et on obtient :

C_fin = 360*(haut + Zbd)/pas;
B_lim_haute = C_fin;
B_fin = 360*(haut + Zad)/pas;
A_fin = D_lim_haute + 360;
A_lim_haute = B_fin;

Pour résumer :

D_lim_haute = 360*haut/pas;															//Jusqu'à ce que D atteigne le haut de la vis, puis disparaisse progressivement
D_fin = 360*(haut + Zcd)/pas;														//disparition du point D, on ajoute précision pour ajouter un dernier point
C_lim_haute = D_fin;																//à ce moment le point C doit rester en haut de la vis
C_fin = 360*(haut + Zbd)/pas;														//pour disparaitre à ce moment là
B_lim_haute = C_fin;																//pareil pour le point B qui doit maintenant rester en haut de la vis
B_fin = 360*(haut + Zad)/pas;														//et disparaitre
A_fin = D_lim_haute + 360;															//en même temps que le point A
A_lim_haute = B_fin;																//pour des raisons de cohérence on donne aussi une limite haute à A

Génération des points

Si vous avez bien saisis où commencent et finissent les points, ainsi que les raisons qui déterminent ces positions, il vous sera aisé de comprendre que pour générer les points on utilise :

A = [ for(i=[A_debut : precision : A_fin])
		i < A_lim_basse ?															//Est-ce que Za est inférieur à 0 ?
			[	( diam_1 - (i*pas/360 - Zad)*(diam_2 - diam_1)/(Zab))*cos(i)/2,		//Cas où Za est inférieur à 0
				( diam_1 - (i*pas/360 - Zad)*(diam_2 - diam_1)/(Zab))*sin(i)/2,
				0] :
		i > A_lim_haute ?															//Est-ce que Za est supérieur à haut ?
			[ diam_1*cos(i)/2, diam_1*sin(i)/2, haut] :								//Cas où Za > haut
			[ diam_1*cos(i)/2, diam_1*sin(i)/2, (i*pas/360 - Zad)]					//Cas où 0 < Za < haut
	];

La seule question que vous devriez vous poser est à quoi correspond cette partie là :

( diam_1 - (i*pas/360 - Zad)*(diam_2 - diam_1)/(Zab))

Une petite illustration permettra de mieux comprendre

Vis sans fin point A.png

Le point rouge à gauche est le point , on constate qu'il doit être placé sur un cercle de diamètre correspondant au diamètre extérieur de la vis, cependant le point rouge à droite est le point qui lui se trouve sur un cercle de diamètre correspondant au diamètre intérieur de la vis. La partie de l'algorithme en question sert donc à corriger le diamètre des points jusqu'à ce qu'ils émergent et atteignent le diamètre intérieur de la vis.

Les autres points sont générés de manière identique :

B = [ for(i=[B_debut : precision : B_fin])
		i < B_lim_basse ?															//Est-ce que Zb est inférieur à 0 ?
			[ diam_2*cos(i)/2, diam_2*sin(i)/2, 0 ] :								//Cas où Zb est inférieur à 0
		i > B_lim_haute ?															//Cas où Zb est supérieur à 0, est-ce que Zb est supérieur à haut ?
			[( diam_1 + (haut - i*pas/360 + Zad)*(diam_2 - diam_1)/(Zab))*cos(i)/2,	//Cas où Zb est supérieur à haut
			( diam_1 + (haut - i*pas/360 + Zad)*(diam_2 - diam_1)/(Zab))*sin(i)/2,
			haut] :
			[ diam_2*cos(i)/2, diam_2*sin(i)/2, (i*pas/360 - Zbd)]					//Cas où 0 < Zb < haut
	];

C = [ for(i=[C_debut : precision : C_fin])
	i < C_lim_basse ?																//Est-ce que Zc est inférieur à 0 ?
		[( diam_1 + (i*pas/360)*(diam_2 - diam_1)/(Zcd))*cos(i)/2,					//Cas où Zc est inférieur à 0
		 ( diam_1 + (i*pas/360)*(diam_2 - diam_1)/(Zcd))*sin(i)/2,
			0] :
		i > C_lim_haute ?															//Cas où ZC est supérieur à 0, est-ce que Zc est supérieur à haut ?
			[ diam_2*cos(i)/2, diam_2*sin(i)/2, haut] :								//Cas où Zc est supérieur à haut
			[ diam_2*cos(i)/2, diam_2*sin(i)/2, (i*pas/360 - Zcd)]					//Cas où 0 < Zc < haut
	];

D = [ for(i=[D_debut : precision : D_fin])
	i< D_lim_basse ?
		[ diam_1*cos(i)/2, diam_1*sin(i)/2, 0] :
	i > D_lim_haute ?																//Est-ce que Zd est supérieur à la hauteur ?
		[( diam_1 + (i*pas/360 - haut)*(diam_2 - diam_1)/(Zcd))*cos(i)/2,			//Cas où Zd est supérieur à haut
		 ( diam_1 + (i*pas/360 - haut)*(diam_2 - diam_1)/(Zcd))*sin(i)/2,
			haut] :
		[ diam_1*cos(i)/2, diam_1*sin(i)/2, i*pas/360]								//Cas où Zd est inférieur à haut
	];

Association des points pour créer les faces

Si vous avez trouvé ce que j'ai écris jusque là imbuvable, dites vous que ce n'est pas fini ...

Maintenant que nous disposons de tous les points nécessaire à la modélisation de la vis, commençons par tous les regrouper :

points = concat(A, B, C, D, [[0, 0, 0]], [[0, 0, haut]]);

Puis pour des raisons pratique on va créer des index :

A_index = 0;
B_index = len(A);
C_index = B_index + len(B);
D_index = C_index + len(C);
O_index = D_index + len(D);
Oh_index = O_index + 1;

Pour créer les faces correspondantes au cylindre intérieur de la vis, il faudra associer les points et . Une petite illustration est la bienvenue :

Vis sans fin point bas.png

Les points rouges sont les points à partir de A_lim_basse, le point vert est le point . Dans un premier temps on va calculer l'index pour lequel les points se trouvent au dessus des points . Si vous avez bien suivis, vous savez que ça a quelque chose à voir avec le paramètre A_lim_basse.

AD_delta = floor(abs(A_lim_basse - A_debut)/precision);

Puis comme sur l'image on va associer les points et , ce qui va nous donner :

for(i=[0:(D_lim_haute - D_debut)/precision]) [ A_index + AD_delta + i, A_index + AD_delta + i + 1, D_index + i ]

Puis dans la même logique il faudra associer les points et , ce qui nous donnera :

for(i=[0:(D_lim_haute - D_debut)/precision]) [ D_index + i, A_index + AD_delta + i + 1, D_index + i + 1 ]

Les faces internes de la vis seront donc générées par :

AD_delta = floor(abs(A_lim_basse - A_debut)/precision);
faces_interieurs = [
	for(i=[0:(D_lim_haute - D_debut)/precision]) [ A_index + AD_delta + i, A_index + AD_delta + i + 1, D_index + i ],
	for(i=[0:(D_lim_haute - D_debut)/precision]) [ D_index + i, A_index + AD_delta + i + 1, D_index + i + 1 ]
					];

Avec la même logique on peut construire les autres faces de la vis :

delta_AB = floor((B_lim_basse - B_debut)/precision);
faces_inferieurs = [
	for(i=[0:(A_lim_haute - A_debut)/precision]) [ B_index + delta_AB + i, B_index + delta_AB + i + 1, A_index + i ],
	for(i=[0:(A_lim_haute - A_debut)/precision]) [ B_index + delta_AB + i + 1, A_index + i + 1, A_index + i ],
					];

delta_BC = floor((C_lim_basse - C_debut)/precision);
faces_exterieurs = [
	for(i=[0:(B_lim_haute - B_debut)/precision]) [ B_index + 1 + i, B_index + i, C_index + i + 1 + delta_BC],
	for(i=[0:(B_lim_haute - B_debut)/precision]) [ C_index + i + delta_BC, C_index + delta_BC + 1 + i, B_index + i ]
					];

delta_CD = floor((D_lim_basse - D_debut)/precision);
faces_superieurs = [
	for(i=[0:(C_lim_haute - C_debut)/precision]) [ D_index + delta_CD + i, D_index + delta_CD + i + 1, C_index + i ],
	for(i=[0:(C_lim_haute - C_debut)/precision]) [ D_index + delta_CD + i + 1, C_index + i + 1, C_index + i ],
					];

Il ne reste plus qu'à fermer la vis en bas et en haut. La logique est la même que précédemment, sauf qu'il faut rajouter quelques faces de jonctions afin de fermer convenablement les faces inférieur et supérieur.

faces_disque_inferieur = [
	for(i=[0:(A_lim_basse - A_debut)/precision - 1]) [A_index + i, A_index + i + 1, O_index],
	[B_index + (B_lim_basse - B_debut)/precision,A_index, O_index],
	for(i=[0:(B_lim_basse - B_debut)/precision - 1]) [B_index + i, B_index + i + 1, O_index],
	[C_index + (C_lim_basse - C_debut)/precision,B_index, O_index],
	for(i=[0:(C_lim_basse - C_debut)/precision - 1]) [C_index + i, C_index + i + 1, O_index],
	[D_index + (D_lim_basse - D_debut)/precision,C_index, O_index],
	for(i=[0:(D_lim_basse - D_debut)/precision - 1]) [D_index + i, D_index + i + 1, O_index],
	[A_index + (A_lim_basse - A_debut)/precision,D_index, O_index]
						];
	
faces_disque_superieur = [
	for(i=[floor((A_lim_haute - A_debut)/precision + 1): len(A) - 2]) [A_index + i + 1, A_index + i, Oh_index],
	[A_index + (A_lim_haute - A_debut)/precision + 1, B_index + len(B) - 1, Oh_index],
	for(i=[floor((B_lim_haute - B_debut)/precision + 1): len(B) - 2]) [B_index + i + 1, B_index + i, Oh_index],
	[B_index + (B_lim_haute - B_debut)/precision + 1, C_index + len(C) - 1, Oh_index],
	for(i=[floor((C_lim_haute - C_debut)/precision + 1): len(C) - 2]) [C_index + i + 1, C_index + i, Oh_index],
	[C_index + (C_lim_haute - C_debut)/precision + 1, D_index + len(D) - 1, Oh_index],
	for(i=[floor((D_lim_haute - D_debut)/precision + 1): len(D) - 2]) [D_index + i + 1, D_index + i, Oh_index],
	[D_index + floor((D_lim_haute - D_debut)/precision + 1), A_index + len(A) - 1, Oh_index],
						];

Finalement

Une fois tout ce travail (imbuvable je l'admet) réalisé, on dispose de tous les points et de toutes les faces nécessaires et uniquement ceux là ! On peut alors très simplement générer le polyhèdre grâce à :

faces = concat( 
				faces_inferieurs,
				faces_exterieurs,
				faces_superieurs,
				faces_interieurs,
				faces_disque_inferieur,
				faces_disque_superieur
				);

polyhedron(points, faces, convexity = 10);

Et enfin obtenir le module pour générer une vis !

Vis métrique

Nous allons faire un petit détours, car vu que maintenant nous avons notre module générique, on va en créer un autre afin de pouvoir créer des vis métriques.

ISO metric thread.png

Cette illustration à été trouvé sur Wikipedia.

module vis_metrique(d = 4, haut = 10, precision = 5, diam_buse = 0.4)
{
	//   			     0    1     2     3     4     5     6     7     8     9
	pas_metrique = [ -1.0, 0.25, 0.40, 0.50, 0.70, 0.80, 1.00, -1.0, 1.25, -1.0,
					  1.50, -1.0, 1.75, -1.0, 2.00, -1.0, 2.00, -1.0, 2.50, -1.0,
					  2.50];
	
	H = 0.866*pas_metrique[d];
	d1 = d - 1.0825*pas_metrique[d];
	if(pas_metrique[d] != -1)
	{
		vis(diam_int = d1, diam_ext = d, DA = pas_metrique[d]/4, BC = pas_metrique[d]/8, pas = pas_metrique[d], haut = haut, precision = precision, diam_buse = diam_buse);
	}
	else
	{
		echo("<font color='red'><b>mauvais diamètre pour la vis métrique</b></font>");
	}
}

Rien de spécial à dire sur ce module, il reprends le module précédent avec les paramètres correspondant aux normes des vis métriques. On peut ainsi faire :

vis_metrique(d = 6, haut = 10, precision = 5, diam_buse = 0.4);

Pour obtenir une vis M6 :

Ce genre de modèle 3D s'imprime très bien et est parfaitement fonctionnel. Il est cependant parfois nécessaire de passer une filière dessus afin d'éliminer quelques bavures. Si vous ne disposez pas de cet outil, un écrou fera également l'affaire mais il faudra alors être très délicat car un écrou n'est pas prévu pour couper contrairement à la filière. La vis ne résistera pas à un effort intense en torsion. Si l'écrou bloque, revenez en arrière et revissez-le, il faudra répéter cette opération plusieurs fois afin d'user la bavure.

Vis trapézoïdale

module vis_sans_fin(m = 1, alpha = 20, diam = 15, haut = 10, precision = 5, diam_buse = 0.4)
{
	//hauteur d'une dent
	hf = m <= 1.25 ? 1.4*m : 1.25*m;
	ha = m;
	h = hf + ha;

	p = m*PI;
	
	largeur_base = 2*hf*tan(alpha) + p/2;
	largeur_crete = largeur_base - 2*h*tan(alpha);
	
	vis(diam_int = diam, diam_ext = diam + 2*h, DA = p - largeur_base, BC = largeur_crete, pas = p, haut = haut, precision = precision, diam_buse = diam_buse);
}

Vous reconnaîtrez sans aucun doutes les paramètres utilisés pour générer la crémaillère. On ne fait donc que calculer les points d'une dent de crémaillère qui seront ensuite fournis au module vis afin de générer la vis sans fin.

Roue dentée + Vis sans fin

Ici on va se retrouver dans le même cas de figure que pour les engrenages hélicoïdaux, donc petit rappel :

Engren15.jpg

Pour associer ces deux composants, on va dans un premier temps revenir en 2D. C'est donc bien les grandeurs apparentes de la roue qui seront importante afin d'obtenir un engrènement correcte.

Coupe roue dentee vis sans fin.png

On observe sur cette image ce que donnera une coupe (perpendiculairement à l'axe de la roue) d'un engrenage roue dentée + vis sans fin. La coupe d'une vis sans fin n'est rien d'autre qu'une crémaillère. On en déduit donc que le module de la crémaillère devra donc être égale au module apparent de la roue dentée. Or pour connaître le module apparent de la roue dentée il nous faut connaître l'angle . Une façon de générer la vis sans fin est de faire tourner cette crémaillère autour d'un axe tout en faisant en sorte qu'au bout d'un tour, la dent notée 1 arrive sur la dent notée 2. En dépliant ce volume voici ce qu'on obtiendrait :

Vis sans fin deroulee.png

La dent bleue est là pour mettre en évidence le fait qu'en enroulant cette surface, chaque dent sera associée à la suivante. On comprend bien sur cette figure que l'angle de la roue dentée doit correspondre à l'inclinaison des dents sur l'image. Dans les différents documents que j'ai pu trouver, le diamètre utilisé pour calculer est le diamètre primitif

On a donc comme paramètres pour la vis :

  • le module de la vis, qui n'est autre que le module de la crémaillère 2D
  • l'angle de pression de la vis
  • l'angle d'hélice

et pour la roue :

  • le module apparent de la roue
  • le module réel de la roue
  • l'angle de pression apparent de la roue
  • l'angle d'hélice