Différences entre les versions de « Roues dentées »

De wiki jackbot
Aller à la navigation Aller à la recherche
m
m
 
Ligne 4 : Ligne 4 :
Pour bien comprendre comment fonctionnent les engrenages il peut être bon de manipuler différents système, c'est ce que propose ce [https://ciechanow.ski/gears/ site], il contient également beaucoup d'informations utiles concernant les rapports, le couple etc ...
Pour bien comprendre comment fonctionnent les engrenages il peut être bon de manipuler différents système, c'est ce que propose ce [https://ciechanow.ski/gears/ 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/  https://ciechanow.ski/gears/], mais me concentrer sur la partie modélisation afin de pouvoir générer des modèles imprimable en 3D.
Dans la suite de ce wiki, je ne vais pas revenir sur les notions abordés sur le site [https://ciechanow.ski/gears/  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 [http://www.cartertools.com/involute.html site].


<h1>Paramètres</h1>
<h1>Paramètres</h1>

Version actuelle datée du 12 juin 2021 à 08:59

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. On obtiendra une vis en faisant tourner ce profil autour de l'axe des abscisses et en amenant le point sur le point . À partir de là il existe plusieurs façons de faire, cependant en regardant de plus près comment est conçue une vis métrique :

ISO metric thread.png

Cette illustration à été trouvé sur Wikipedia.

On constate qu'avec quelques relations du théorème de Thalès on pourra aisément connaitre les valeurs de et de . Ce sont donc ces valeurs qu'on utilisera en tant que paramètre de notre module. Voici le prototype de notre module :

module vis(diam_int = 4, diam_ext = 6, DA = 0.25, BC = 0.25, pas = 1, haut = 31, precision = 5, diam_buse = 0.4)

La suite n'a rien de sorcier, mais il est vrai que concevoir un polyhèdre n'est jamais de tout repos, surtout un aussi complèxe.

d1 = diam_int - diam_buse;
d2 = diam_ext - diam_buse;

//ajout de 2 tour pour avoir une coupe propre lors de la création de la vis
nbr_tours = ceil(haut/pas) + 2;
angle = nbr_tours * 360;

Ces lignes nous servent simplement à déterminer le nombre de tours ainsi que l'angle total de rotation.

//par symétrie AB = CD
AB = pas/2 - BC/2 - DA/2;

Ici non plus pas de réelles difficultés, il faut juste faire attention au fait que ce qui nous intéresse est la distance sur l'axe des abscisses, donc la valeur correspond au des points et . C'est maintenant que ça va se compliquer car on va passer à la génération des ensembles de points de la vis

A = [ for(i=[0 : precision : angle]) [ d1*cos(i)/2, d1*sin(i)/2, i*pas/360 - pas ] ] ;
B = [ for(i=[0 : precision : angle]) [ d2*cos(i)/2, d2*sin(i)/2, i*pas/360 - pas + AB ] ];
C = [ for(i=[0 : precision : angle]) [ d2*cos(i)/2, d2*sin(i)/2, i*pas/360 - pas + AB + BC] ];
D = [ for(i=[0 : precision : angle]) [ d1*cos(i)/2, d1*sin(i)/2, i*pas/360 - pas + AB + BC + AB] ];

La variable A représente l'ensemble des points A, A1, A2 etc ... Tous les points par lesquels va passer le point A lors de la rotation. On peut facilement comprendre qu'on fait tourner le point A grace à la présence de et de dans ses coordonnées x et y respectivement. Quant à sa coordonnée z :

i*pas/360 - pas

On comprends facilement que pour chaque tour, sa position sur l'axe z sera incrémenté d'un pas. On obtient donc bien une trajectoire hélicoïdale pour ce point. Il en est de même avec les autres points qui sont simplement décalé sur l'axe z.

points = concat(A, B, C, D, [[0, 0, 0]], [[0, 0, nbr_tours * pas]]);

Cette ligne dans le script d'OpenSCAD permet uniquement de rassembler tous les points dans une seule variable, en y ajoutant au passage les points centraux des faces inférieure et supérieure. Pour des raisons pratique il vaut mieux calculer tous les index qui seront nécessaires par la suite :

longueur = len(A);
index_A = 0;
index_B = longueur;
index_C = index_B + longueur;
index_D = index_C + longueur;
index_O = index_D + longueur;
index_Oh = index_O + 1;

Une fois qu'on a tout ça on peut déterminer tous les petits triangles qui serviront de facettes à cette vis :

faces_inferieurs1 = [ for(i=[0:longueur - 2]) [ index_A + i, index_B + i, index_A + 1 + i ] ];
faces_inferieurs2 = [ for(i=[0:longueur - 2]) [ index_B + i, index_B + 1 + i, index_A + 1 + i ] ];
faces_exterieurs1 = [ for(i=[0:longueur - 2]) [ index_B + 1+ i, index_B + i, index_C + i ] ];
faces_exterieurs2 = [ for(i=[0:longueur - 2]) [ index_C + i, index_C + 1 + i, index_B + 1 + i ] ];
faces_superieurs1 = [ for(i=[0:longueur - 2]) [ index_C + 1 + i, index_C + i, index_D + i ] ];
faces_superieurs2 = [ for(i=[0:longueur - 2]) [ index_D + i, index_D + 1 + i, index_C + 1 + i ] ];
faces_interieurs1 = [ for(i=[0:longueur - 2 - 360/precision]) [ index_D + i, index_A + 360/precision + i, index_D + 1 + i ] ];
faces_interieurs2 = [ for(i=[0:longueur - 2 - 360/precision]) [ index_A + 360/precision + i, index_A + 360/precision + 1 + i,  index_D + 1 + i ] ];
faces_disque_inferieur = [ for(i=[0 : 360/precision - 1]) [ index_A + i, index_A + 1 + i,  index_O ] ];
faces_disque_superieur = [ for(i=[0 : 360/precision - 1]) [ index_D + len(D) - 360/precision + i, index_D + len(D) - 360/precision - 1 + i,  index_Oh ] ];
face_fermeture_basse = [ [index_O, index_A + 360/precision, index_D, index_C, index_B, index_A] ];
face_fermeture_haute = [ [index_Oh, index_D + len(D) - 360/precision - 1, index_A + len(A) - 1, index_B + len(B) - 1, index_C + len(C) - 1, index_D + len(D) - 1] ];

En réalité ce n'est pas compliqué, si on regarde la première ligne il s'agit en fait d'un triangle formé par un point A, le point B du même indice ainsi que le point A suivant. Ce n'est pas compliqué, mais assez indigeste ...

faces = concat( faces_inferieurs1, faces_inferieurs2,
		faces_exterieurs1, faces_exterieurs2,
		faces_superieurs1, faces_superieurs2,
		faces_interieurs1, faces_interieurs2,
		faces_disque_inferieur,	faces_disque_superieur,
		face_fermeture_basse, face_fermeture_haute
		);

Comme on a concaténé les points dans une seule variable plus tôt, on fait de même avec les faces. En respectant bien l'ordre dans tout le script on peut au final faire quelque chose de très simple :

polyhedron(points, faces);

Qui va nous générer une vis, mais pour avoir des extrémité planes il faut les couper :

difference()
{
	polyhedron(points, faces);
	
	translate([0, 0, -pas])
	{cylinder(d = 2*d2, h = pas);}
	translate([0, 0, haut])
	{cylinder(d = 2*d2, h = 3*pas);}
}

Récapitulatif

module vis(diam_int = 4, diam_ext = 6, DA = 0.25, BC = 0.25, pas = 1, haut = 31, precision = 5, diam_buse = 0.4)
{
	/*Lors de l'impression le centre de la buse se placera au bon endroit
	ce qui signifie qu'une erreur de la moitié du diamètre de la buse apparaitra à l'extérieur.
	*/
	d1 = diam_int - diam_buse;
	d2 = diam_ext - diam_buse;
	
	//ajout de 2 tour pour avoir une coupe propre lors de la création de la vis
	nbr_tours = ceil(haut/pas) + 2;
	angle = nbr_tours * 360;

	//par symétrie AB = CD
	AB = pas/2 - BC/2 - DA/2;
	
	A = [ for(i=[0 : precision : angle]) [ d1*cos(i)/2, d1*sin(i)/2, i*pas/360 - pas ] ] ;
	B = [ for(i=[0 : precision : angle]) [ d2*cos(i)/2, d2*sin(i)/2, i*pas/360 - pas + AB ] ];
	C = [ for(i=[0 : precision : angle]) [ d2*cos(i)/2, d2*sin(i)/2, i*pas/360 - pas + AB + BC] ];
	D = [ for(i=[0 : precision : angle]) [ d1*cos(i)/2, d1*sin(i)/2, i*pas/360 - pas + AB + BC + AB] ];

	points = concat(A, B, C, D, [[0, 0, 0]], [[0, 0, nbr_tours * pas]]);
	
	longueur = len(A);
	index_A = 0;
	index_B = longueur;
	index_C = index_B + longueur;
	index_D = index_C + longueur;
	index_O = index_D + longueur;
	index_Oh = index_O + 1;
	
	faces_inferieurs1 = [ for(i=[0:longueur - 2]) [ index_A + i, index_B + i, index_A + 1 + i ] ];
	faces_inferieurs2 = [ for(i=[0:longueur - 2]) [ index_B + i, index_B + 1 + i, index_A + 1 + i ] ];
	faces_exterieurs1 = [ for(i=[0:longueur - 2]) [ index_B + 1+ i, index_B + i, index_C + i ] ];
	faces_exterieurs2 = [ for(i=[0:longueur - 2]) [ index_C + i, index_C + 1 + i, index_B + 1 + i ] ];
	faces_superieurs1 = [ for(i=[0:longueur - 2]) [ index_C + 1 + i, index_C + i, index_D + i ] ];
	faces_superieurs2 = [ for(i=[0:longueur - 2]) [ index_D + i, index_D + 1 + i, index_C + 1 + i ] ];
	faces_interieurs1 = [ for(i=[0:longueur - 2 - 360/precision]) [ index_D + i, index_A + 360/precision + i, index_D + 1 + i ] ];
	faces_interieurs2 = [ for(i=[0:longueur - 2 - 360/precision]) [ index_A + 360/precision + i, index_A + 360/precision + 1 + i,  index_D + 1 + i ] ];
		
	/*!!!!! ATTENTION !!!!!
	pour éviter l'erreur : Object may not be a valid 2-manifold and may need repair!
	il faut que les points utilisés pour les disques aient été utilisés dans les autres faces.
	*/
	faces_disque_inferieur = [ for(i=[0 : 360/precision - 1]) [ index_A + i, index_A + 1 + i,  index_O ] ];
	faces_disque_superieur = [ for(i=[0 : 360/precision - 1]) [ index_D + len(D) - 360/precision + i, index_D + len(D) - 360/precision - 1 + i,  index_Oh ] ];
	face_fermeture_basse = [ [index_O, index_A + 360/precision, index_D, index_C, index_B, index_A] ];
	face_fermeture_haute = [ [index_Oh, index_D + len(D) - 360/precision - 1, index_A + len(A) - 1, index_B + len(B) - 1, index_C + len(C) - 1, index_D + len(D) - 1] ];
	faces = concat( faces_inferieurs1, faces_inferieurs2,
					faces_exterieurs1, faces_exterieurs2,
					faces_superieurs1, faces_superieurs2,
					faces_interieurs1, faces_interieurs2,
					faces_disque_inferieur,	faces_disque_superieur,
					face_fermeture_basse, face_fermeture_haute
					);

	difference()
	{
		polyhedron(points, faces);
		
		translate([0, 0, -pas])
		{cylinder(d = 2*d2, h = pas);}
		translate([0, 0, haut])
		{cylinder(d = 2*d2, h = 3*pas);}
	}
}

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.

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 + Vis sans fin

Pour générer une roue qui sera associée à une vis sans fin il faut bien faire attention que c'est le module apparent de la roue qui doit correspondre au module de la vis ! Si on note :

  • le module de la vis
  • l'angle de pression de la vis
  • le module de la roue
  • l'angle de pression de la roue
  • l'angle d'hélice

Alors il faut respecter :

et