Comment faire des tracés sur image - Taillage d'engrenages.

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par Cool Dji »

Un lien interessant sur les engrenages...

http://k-v1.over-blog.com/article-les-e ... 50224.html
Only PureBasic makes it possible
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par Le Soldat Inconnu »

Ça y est, j'ai réussi, c'est plutôt complexe quand même, plus que ce que j'imaginais. Ça m'a résisté 1 semaines :mrgreen:

voilà mon code pour dessiner un engrenage, Sulren, tu penses quoi du résultat ?

Il ne manque qu'une chose, la forme de l'outil créaillère que j'utilise n'est pas arrondi aux extrémités mais droit. Je galère pour trouver l'équation qui va bien. Les ellipses, c'est pas simple.

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 4.40
;
; Explication du programme :
; Dessiner un engrenage


; Le filtre permet d'émuler de l'antialiasing sur le dessin de l'engrenage, ne pas mettre au dessus de 8
Global FiltreAA = 4, Dessin_Angle.d, Dessin_Zoom.d, Dessin.i


Enumeration
  #G_Module
  #G_Z
  #G_Angle_Pression
  #G_D_primitif
  #G_D_pied
  #G_D_tete
  #G_H_dent
  #G_Pas
  #G_Zoom
  #G_Dessin
  #G_Angle
EndEnumeration

#Engrenage_ResolutionDent = 200
#Equation_Degree = 2
#Engrenage_Couleur = $FF00FFFF
#Engrenage_Diametre = $200000FF
#Engrenage2_Couleur = $FF0000FF
#Cremaillere_Couleur = $40FFFFFF
#Cremaillere_Hauteur = $400000FF
Structure Structure_Equation
  x1.d
  x2.d
  v.d[#Equation_Degree + 1]
EndStructure
Structure Structure_Rayon
  R.d
  Angle.d
EndStructure
Structure Structure_Engrenage
  Module.d
  Z.d
  D_primitif.d
  D_tete.d
  D_pied.d
  H_dent.d
  Angle_pression.d
  Pas.d
  Contour.Structure_Rayon[#Engrenage_ResolutionDent]
  Cremaillere.Structure_Equation[5]
  Outil.Structure_Equation[5]
EndStructure

Global Engrenage.Structure_Engrenage

Procedure.s AfficheValeur(Valeur.d)
  ProcedureReturn Trim(Trim(Trim(StrD(Valeur), "0"), "."), ",")
EndProcedure

Procedure Engrenage_Calcul(*Calcul.Structure_Engrenage)
  With * Calcul
    ;- Paramètres de l'engrenage
    \D_primitif = \Z * \Module
    \D_tete = \D_primitif + 2 * \Module
    \D_pied = \D_primitif - 2.5 * \Module
    \Pas = #PI * \Module
    \H_dent = 2.25 * \Module
    ;- Equation de la crémaillère
    Largeur_zone_inclinee.d = 2.25 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_tete.d = \Pas / 2 - 2 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_pied.d = \Pas / 2 - 2.5 * \Module * Sin(\Angle_pression * #PI / 180)
    
    ; Zone 1
    \Cremaillere[0]\x1 = 0
    \Cremaillere[0]\x2 = Largeur_zone_tete / 2
    \Cremaillere[0]\v[0] = \H_dent
    ; zone 2
    \Cremaillere[1]\x1 = \Cremaillere[0]\x2
    \Cremaillere[1]\x2 = \Cremaillere[1]\x1 + Largeur_zone_inclinee
    \Cremaillere[1]\v[1] = -2.25 * \Module / Largeur_zone_inclinee
    \Cremaillere[1]\v[0] = \H_dent - \Cremaillere[1]\v[1] * Largeur_zone_tete / 2
    ; zone 3
    \Cremaillere[2]\x1 = \Cremaillere[1]\x2
    \Cremaillere[2]\x2 = \Cremaillere[2]\x1 + Largeur_zone_pied
    ; \Cremaillere[2]\v[2] = 2 * \Module / Largeur_zone_inclinee / Largeur_zone_pied
    ; \Cremaillere[2]\v[1] = \Cremaillere[1]\v[1] - 2 * \Cremaillere[2]\v[2] * \Cremaillere[2]\x1
    ; \Cremaillere[2]\v[0] = 0.25 * \Module - \Cremaillere[2]\v[2] * \Cremaillere[2]\x1 * \Cremaillere[2]\x1 - \Cremaillere[2]\v[1] * \Cremaillere[2]\x1
    ; Zone 4
    \Cremaillere[3]\x1 = \Cremaillere[2]\x2
    \Cremaillere[3]\x2 = \Cremaillere[3]\x1 + Largeur_zone_inclinee
    \Cremaillere[3]\v[1] = 2.25 * \Module / Largeur_zone_inclinee
    \Cremaillere[3]\v[0] = -\Cremaillere[3]\v[1] *(Largeur_zone_tete / 2 + Largeur_zone_inclinee + Largeur_zone_pied)
    ; Zone 5
    \Cremaillere[4]\x1 = \Cremaillere[3]\x2
    \Cremaillere[4]\x2 = \Pas
    \Cremaillere[4]\v[0] = \H_dent
    
    
    Largeur_zone_inclinee.d = 2.25 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_tete.d = \Pas / 2 - 2.5 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_pied.d = \Pas / 2 - 2 * \Module * Sin(\Angle_pression * #PI / 180)
    ; Zone 1
    \Outil[0]\x1 = 0
    \Outil[0]\x2 = Largeur_zone_tete / 2
    \Outil[0]\v[0] = \H_dent + 0.25 * \Module
    ; zone 2
    \Outil[1]\x1 = \Outil[0]\x2
    \Outil[1]\x2 = \Outil[1]\x1 + Largeur_zone_inclinee
    \Outil[1]\v[1] = -2.25 * \Module / Largeur_zone_inclinee
    \Outil[1]\v[0] = \H_dent + 0.25 * \Module - \Outil[1]\v[1] * Largeur_zone_tete / 2
    ; zone 3
    \Outil[2]\x1 = \Outil[1]\x2
    \Outil[2]\x2 = \Outil[2]\x1 + Largeur_zone_pied
    \Outil[2]\v[0] = 0.25 * \Module
    ; Zone 4
    \Outil[3]\x1 = \Outil[2]\x2
    \Outil[3]\x2 = \Outil[3]\x1 + Largeur_zone_inclinee
    \Outil[3]\v[1] = 2.25 * \Module / Largeur_zone_inclinee
    \Outil[3]\v[0] = 0.25 * \Module - \Outil[3]\v[1] *(Largeur_zone_tete / 2 + Largeur_zone_inclinee + Largeur_zone_pied)
    ; Zone 5
    \Outil[4]\x1 = \Outil[3]\x2
    \Outil[4]\x2 = \Pas
    \Outil[4]\v[0] = \H_dent + 0.25 * \Module
    
    ; Reset de la taille de l'engrenage
    For x = 0 To #Engrenage_ResolutionDent - 1
      \Contour[x]\R = \D_tete / 2
      \Contour[x]\Angle = x * 2 * #PI / #Engrenage_ResolutionDent / \Z
    Next
    
    ;- Affichage des résultats
    SetGadgetText(#G_D_primitif, AfficheValeur(Engrenage\D_primitif))
    SetGadgetText(#G_D_tete, AfficheValeur(Engrenage\D_tete))
    SetGadgetText(#G_D_pied, AfficheValeur(Engrenage\D_pied))
    SetGadgetText(#G_H_dent, AfficheValeur(Engrenage\H_dent))
    SetGadgetText(#G_Pas, AfficheValeur(Engrenage\Pas))
    
  EndWith
EndProcedure

Procedure Engrenage_Diametre(*Calcul.Structure_Engrenage)
  With * Calcul
    If \Module > 0 And \Z > 0 And \Angle_pression > 0 And \D_pied > 0
      
			;- Calcul des rayons avec l'angle par défaut
      For x = 0 To #Engrenage_ResolutionDent - 1
        Angle_reel.d = x * 2 * #PI / #Engrenage_ResolutionDent / \Z
        x_reel.d = \D_primitif * Angle_reel / 2
        
        While x_reel >= \Pas And \Pas > 0
          x_reel - \Pas
        Wend
        If x_reel < 0
          x_reel = 0
        EndIf
        For n = 0 To 4
          If x_reel >= \Outil[n]\x1 And x_reel < \Outil[n]\x2
            y_reel.d = \Outil[n]\v[0]
            For nn = 1 To #Equation_Degree
              y_reel.d + \Outil[n]\v[nn] * Pow(x_reel, nn)
            Next
            Break
          EndIf
        Next
        
        \Contour[x]\R =(\D_primitif / 2 + 1.25 * \Module) - y_reel
        If \Contour[x]\R > \D_tete / 2
          \Contour[x]\R = \D_tete / 2
        EndIf
        If \Contour[x]\R < \D_pied / 2
          \Contour[x]\R = \D_pied / 2
        EndIf
        
        \Contour[x]\Angle = x * 2 * #PI / #Engrenage_ResolutionDent / \Z

      Next
      
      ;- Correction de l'angle
			
			; Centre de l'engrenage
			x_reel.d = 0
			y_reel.d =(\D_primitif / 2 + 1.25 * \Module)
			
			Correction.d = 1 / #Engrenage_ResolutionDent / \Z
			
      For Z = -#Engrenage_ResolutionDent * \Z / 8 To #Engrenage_ResolutionDent * \Z / 8
				
				Angle.d =  Z * 2 * #PI / #Engrenage_ResolutionDent / \Z
				
        For x = 0 To #Engrenage_ResolutionDent - 1
					
          Repeat
            
            Angle_reel.d = \Contour[x]\Angle + Angle
            x1_reel.d = x_reel + \Contour[x]\R * Sin(Angle_reel) - \D_primitif * Angle / 2
            y1_reel.d = y_reel - \Contour[x]\R * Cos(Angle_reel)
            
            While x1_reel >= \Pas And \Pas > 0
              x1_reel - \Pas
            Wend
            If x1_reel < 0
              x1_reel = 0
            EndIf
            For n = 0 To 4
              If x1_reel >= \Outil[n]\x1 And x1_reel < \Outil[n]\x2
                y2_reel.d = \Outil[n]\v[0]
                For nn = 1 To #Equation_Degree
                  y2_reel.d + \Outil[n]\v[nn] * Pow(x1_reel, nn)
                Next
                Break
              EndIf
            Next
            
            If y1_reel < y2_reel
              
              If x1_reel < \Pas / 2
                \Contour[x]\Angle + Correction
              Else
                \Contour[x]\Angle - Correction
              EndIf
              
            EndIf
            
          Until y1_reel >= y2_reel
          
          
        Next
      Next
    EndIf
  EndWith
EndProcedure

Procedure Engrenage_Dessin(Gadget, Image, *Calcul.Structure_Engrenage, Angle.d, Zoom.d = 0)
  ; Calcul du diamètre de l'engrenage
  ; Engrenage_Diametre(@*Calcul.Structure_Engrenage, Angle.d)
  
  LoadFont(1, "Tahoma", 9 * FiltreAA, #PB_Font_HighQuality)
  
  With * Calcul
    Largeur = ImageWidth(Image) * FiltreAA
    Hauteur = ImageHeight(Image) * FiltreAA
		Echelle.d =(2 * \Pas *(1 - Zoom) + \D_tete * Zoom) /(Largeur - 32 * FiltreAA)
    x0 = Largeur / 2
    y0 = Hauteur / 3 - 1.25 * \Module / Echelle
    
    ; De combien la crémaillère se déplace pour l'angle donné
    Avance.d = \D_primitif * Angle / 2
    
    CreateImage(Image, Largeur, Hauteur, 24)
    StartDrawing(ImageOutput(Image))
      DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
      Box(0, 0, Largeur, Hauteur, $FF000000)
      
      If \Module > 0 And \Z > 0 And \Angle_pression > 0 And \D_pied > 0
        
        ; Centre de l'engrenage
        x_reel.d = 0
        y_reel.d =(\D_primitif / 2 + 1.25 * \Module)
        ; Dessin de l'engrenage
        Angle_reel.d = \Contour[0]\Angle + Angle
        x1_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
        y1_reel.d = y_reel - \Contour[0]\R * Cos(Angle_reel)
        For nn = 0 To \Z - 1
          For n = 1 To #Engrenage_ResolutionDent - 1
            Angle_reel.d = \Contour[n]\Angle + 2 * #PI * nn / \Z + Angle
            x2_reel.d = x_reel + \Contour[n]\R * Sin(Angle_reel)
            y2_reel.d = y_reel - \Contour[n]\R * Cos(Angle_reel)
            ; Debug StrD(x2_reel, 4) + " / " + StrD(y2_reel, 4)
            LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage_Couleur)
            x1_reel = x2_reel
            y1_reel = y2_reel
          Next
        Next
        Angle_reel.d = \Contour[0]\Angle + Angle
        x2_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
        y2_reel.d = y_reel - \Contour[0]\R * Cos(Angle_reel)
        LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage_Couleur)
        
        ; Remplissage de l'engrenage
        If y0 + y_reel / Echelle > Hauteur
          y = Hauteur - 1
        Else
          y = y0 + y_reel / Echelle
        EndIf
        FillArea(x0, y, #Engrenage_Couleur, #Engrenage_Couleur)
         
        ; Dessin de la crémaillère et de l'outil
        For x = 0 To Largeur - 1
          x_reel.d =(x - x0) * Echelle - Avance
          If x_reel < 0
            x_reel = -x_reel
          EndIf
          While x_reel >= \Pas And \Pas > 0
            x_reel - \Pas
          Wend
          If x_reel < 0
            x_reel = 0
          EndIf
          
          ; Dessin de la crémaillère
          For n = 0 To 4
            If x_reel >= \Cremaillere[n]\x1 And x_reel < \Cremaillere[n]\x2
              y_reel.d = \Cremaillere[n]\v[0]
              For nn = 1 To #Equation_Degree
                y_reel.d + \Cremaillere[n]\v[nn] * Pow(x_reel, nn)
              Next
              Break
            EndIf
          Next
          y = y_reel / Echelle + y0
          LineXY(x, y, x, 0, #Cremaillere_Couleur)
          
          ; Dessin de l'outil d'usinage
          For n = 0 To 4
            If x_reel >= \Outil[n]\x1 And x_reel < \Outil[n]\x2
              y_reel.d = \Outil[n]\v[0]
              For nn = 1 To #Equation_Degree
                y_reel.d + \Outil[n]\v[nn] * Pow(x_reel, nn)
              Next
              Break
            EndIf
          Next
          y = y_reel / Echelle + y0
          LineXY(x, y, x, 0, #Cremaillere_Couleur)
          
        Next
        
				; Centre de l'engrenage
        x_reel.d = 0
        y_reel.d =(\D_primitif / 2 + 1.25 * \Module)
				; Dessin du diametre de pied
        Circle(x0, y0 + y_reel / Echelle,(\D_pied / 2) / Echelle,#Engrenage_Diametre)
        Box(0, y0 +(2.5 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
        ; Dessin du diametre primitif
        Circle(x0, y0 + y_reel / Echelle,(\D_primitif / 2) / Echelle,#Engrenage_Diametre)
        Box(0, y0 +(1.25 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
        ; Dessin du diametre de tête
        Circle(x0, y0 + y_reel / Echelle,(\D_tete / 2) / Echelle,#Engrenage_Diametre)
        Box(0, y0 +(0.25 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
        ; pied de la crémaillère
        Box(0, y0 - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
        ; Tête de la crémaillère
        Box(0, y0 +(2.25 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
        ; centre
        Box(x0 - FiltreAA / 2, 0, FiltreAA, Hauteur, #Cremaillere_Hauteur)
				
        ; Centre de l'engrenage
        x_reel.d = 0
        y_reel.d = (1.25 * \Module - \D_primitif / 2)
        ; Dessin de l'engrenage
        Angle_reel.d = -\Contour[0]\Angle + Angle + #PI / \Z
        x1_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
        y1_reel.d = y_reel + \Contour[0]\R * Cos(Angle_reel)
        For nn = 0 To \Z - 1
					For n = 1 To #Engrenage_ResolutionDent - 1
						Angle_reel.d = \Contour[n]\Angle + 2 * #PI * nn / \Z + Angle + #PI / \Z
						x2_reel.d = x_reel + \Contour[n]\R * Sin(Angle_reel)
						y2_reel.d = y_reel + \Contour[n]\R * Cos(Angle_reel)
						; Debug StrD(x2_reel, 4) + " / " + StrD(y2_reel, 4)
						LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage2_Couleur)
						x1_reel = x2_reel
						y1_reel = y2_reel
					Next
				Next
        Angle_reel.d = -\Contour[0]\Angle + Angle + #PI / \Z
        x2_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
        y2_reel.d = y_reel + \Contour[0]\R * Cos(Angle_reel)
        LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage2_Couleur)
				
				
        ; Dessin de l'échelle
        DrawingFont(FontID(1))
        Longueur.d = 1 / Echelle
        Texte.s = "1 mm"
        If TextWidth(Texte + "  ") > Longueur
          Longueur.d = 5 / Echelle
          Texte.s = "5 mm"
        EndIf
        If TextWidth(Texte + "  ") > Longueur
          Longueur.d = 10 / Echelle
          Texte.s = "1 cm"
        EndIf
        If TextWidth(Texte + "  ") > Longueur
          Longueur.d = 50 / Echelle
          Texte.s = "5 cm"
        EndIf
        If TextWidth(Texte + "  ") > Longueur
          Longueur.d = 100 / Echelle
          Texte.s = "1 dm"
        EndIf
        If TextWidth(Texte + "  ") > Longueur
          Longueur.d = 500 / Echelle
          Texte.s = "5 dm"
        EndIf
        If TextWidth(Texte + "  ") > Longueur
          Longueur.d = 1000 / Echelle
          Texte.s = "1 m"
        EndIf
        DrawText(x0 +(Longueur - TextWidth(Texte)) / 2, Hauteur - 16 * FiltreAA - TextHeight(Texte), Texte, $FFFFFFFF)
        Box(x0, Hauteur - 16 * FiltreAA, Longueur, FiltreAA, $FFFFFFFF)
        Box(x0, Hauteur - 16 * FiltreAA - Longueur, FiltreAA, Longueur, $FFFFFFFF)
        
      EndIf
    StopDrawing()
    If FiltreAA > 1
      ResizeImage(Image, Largeur / FiltreAA, Hauteur / FiltreAA, #PB_Image_Smooth)
    EndIf
    SetGadgetState(#G_Dessin, ImageID(0))
    
    FreeFont(1)
    
  EndWith
EndProcedure

Procedure Affichage(Parametre.i)
	
	Repeat
		
		While Dessin = 0 And Compteur < 50
			Delay(20)
			If FiltreAA = 1
				Compteur + 1
			EndIf
		Wend
		
		If Dessin > 0
			Dessin = 0
			FiltreAA = 1
			Affichage = 1
		EndIf
		If Compteur >= 50
			FiltreAA = 4
			Compteur = 0
			Affichage = 1
		EndIf
		
		If Affichage
			Affichage = 0
			
			Engrenage_Dessin(#G_Dessin, 0, @Engrenage, Dessin_Angle, Dessin_Zoom)
			
		EndIf
		
	Until Dessin < 0
	
EndProcedure



; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 800, 600, "Taillage d'engrenage", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
  End
EndIf

LoadFont(0, "Tahoma", 9, #PB_Font_HighQuality)
SetGadgetFont(#PB_Default, FontID(0))

Engrenage\Module = 1
Engrenage\Z = 13
Engrenage\Angle_pression = 20

x = 4
y = 4
Largeur = 192
TextGadget(#PB_Any, x, y, Largeur, 16, "Module")
y + 16
StringGadget(#G_Module, x, y, Largeur, 24, AfficheValeur(Engrenage\Module))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Z (Nombre de dents)")
y + 16
StringGadget(#G_Z, x, y, Largeur, 24, AfficheValeur(Engrenage\Z))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Angle de pression (en °)")
y + 16
StringGadget(#G_Angle_Pression, x, y, Largeur, 24, AfficheValeur(Engrenage\Angle_pression))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Diamètre primitif")
y + 16
StringGadget(#G_D_primitif, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Diamètre de tête")
y + 16
StringGadget(#G_D_tete, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Diamètre de pied")
y + 16
StringGadget(#G_D_pied, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Hauteur de dent")
y + 16
StringGadget(#G_H_dent, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Pas")
y + 16
StringGadget(#G_Pas, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8

TextGadget(#PB_Any, x, y, Largeur, 16, "Zoom d'affichage")
y + 16
TrackBarGadget(#G_Zoom, x, y, Largeur, 32, 0, 10, #PB_TrackBar_Ticks)
Dessin_Zoom.d = 0
y + 32
TextGadget(#PB_Any, x, y, Largeur, 16, "Rotation de l'engrenage")
y + 16
TrackBarGadget(#G_Angle, x, y, Largeur, 32, 0, 36, #PB_TrackBar_Ticks)
Dessin_Angle.d = 0
y + 32

CreateImage(0, 600 - 8, 600 - 8, 24)
ImageGadget(#G_Dessin, 204, 4, 0, 0, ImageID(0))

Engrenage_Calcul(@Engrenage)
Engrenage_Diametre(@Engrenage)
Engrenage_Dessin(#G_Dessin, 0, @Engrenage, 0)

Dessin = 1
Thread = CreateThread(@Affichage(), 0)

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget() ; Gadgets
        Case #G_Module, #G_Z, #G_Angle_Pression
          If EventType() = #PB_EventType_Change
            Engrenage\Module = ValD(GetGadgetText(#G_Module))
            Engrenage\Z = ValD(GetGadgetText(#G_Z))
            Engrenage\Angle_pression = ValD(GetGadgetText(#G_Angle_Pression))
            Engrenage_Calcul(@Engrenage)
            Engrenage_Diametre(@Engrenage)
            Dessin + 1
          EndIf
        Case #G_Zoom
          Dessin_Zoom = GetGadgetState(#G_Zoom) / 10
          Dessin + 1
        Case #G_Angle
          Dessin_Angle.d = GetGadgetState(#G_Angle) * 2 * #PI /(36 * Engrenage\Z)
          Dessin + 1
      EndSelect
  EndSelect
  
Until Event = #PB_Event_CloseWindow

; Fermeture de thread
Dessin = -1
While IsThread(Thread)
	Delay(10)
Wend
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
venom
Messages : 3137
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par venom »

8O meme si je ne suis pas le sujet, le rendu est stupéfiant.
bien jouer Soldat 8)






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par Fig »

Visuellement c'est bluffant en tout cas. 8O
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par Cool Dji »

Bravo Soldat Inconnu,

C'est du Great !

Merci pour le code, belle démonstration 8)
J'avais abondonné et je dessinais mes engrenage sur Illustrator...:(

Chapeau !!!! :P
Only PureBasic makes it possible
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par Le Soldat Inconnu »

j'ai quand même un bug avec les engrenages qui ont peu de dents. J'ai commencé la correction mais j'ai visiblement un problème d'arrondi qui me cause des erreurs.
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
Cool Dji
Messages : 1126
Inscription : ven. 05/sept./2008 11:42
Localisation : Besançon
Contact :

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par Cool Dji »

Vi, j'avais vu le petit bug du faible nombre de dents mais bon, de toutes façons il doit forcément y avoir une limite "physique".
De mémoire, les pignons de vélos des roues arrières ne descendaient guère au dessous des 11 dents (fallait déjà des bonnes jambes pour les tirer)...

En tout les cas, ton code est vraiment clean !
Only PureBasic makes it possible
SULREN
Messages : 56
Inscription : mar. 27/janv./2009 12:07
Localisation : Très proche de Toulouse, au nord-ouest

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par SULREN »

Bonjour,
Je voudrais tout d’abord vous remercier tous pour votre aide et en particulier Fred, Dobro le Soldat et Jces, et je m’excuse de vous avoir fait perdre du temps faute d’avoir passé moi-même un peu de temps à exploiter les tutos. Dans mon post précédent je suis passé pour un gros « neuneu » (n’ayons pas peur des mots) avec mes questions stupides et mes fausses manips dues au fait que j’étais fatigué et excédé par les plantages incessants de l’exécutable.
J’ai donc repris le problème par le bon bout, comme l’avait fort justement suggéré Dobro, et j’ai potassé les tutos. J’ai pu ainsi terminer mon application et elle fonctionne parfaitement. Je viens d’ouvrir un fil pour la présenter.

Il faut dire que tous les codes que j’avais écrits jusqu’à ce jour étaient constitués de pur calcul sans aucune interactivité. Je rentrais quelques valeurs numériques dans une fenêtre console (je n’ouvrais même pas une fenêtre de dialogue), j’appuyais sur Enter et basta.
Par exemple : pour générer la vue 2D suivante et les fichiers associés dont j’ai besoin, il me suffit de rentrer 4 valeurs, celles qui sont rappelées dans le titre de la vue. Elle est moins belle que celle du Soldat mais elle est plus complète.

Image

Bravo Le Soldat Inconnu pour ton magnifique travail de pro!. Comparé à cela je ne suis qu’un âne en PureBasic. Outre tes capacités en programmation (cela va sans dire), j'ai été impressionné par ta capacité à analyser le problème. Chapeau! Je suis heureux de t’avoir branché sur le sujet des engrenages.
Le problème que tu rencontres avec les petits nombres de dents s’appelle « problème d’interférence ». Il commence en dessous de 20 dents environ. Pour le résoudre il faut introduire la notion de déport. Dans l'image ci-dessus tu verras que pour 15 dents j’ai déjà du prendre un déport de 0,12 m.
Il faut que tu prennes en compte cette notion et aussi que tu ajoutes l'arrondi au bout de la dent de la crémaillère. La norme l'exige.
Il ne restera plus qu'à générer le fichier des coordonnées du fly-cutter pour son exécution sur le tour.

Cool Dji a dit:
De mémoire, les pignons de vélos des roues arrières ne descendaient guère au dessous des 11 dents
On peut descendre à 6 dents dans le profil en développante de cercle. Il y en a à 6 dents dans les ponts roulants. En voici un (qui va intriguer le Soldat):
PIGNON DEVELOPPANTE 6 DENTS

Mais ces engrenages à faible nombre de dents ne peuvent être que menants. Quand ils sont menés ils ont un très mauvais rendement de transmission.
Les engrenages horlogers à profil ogival gardent, eux, un bon rendement en pignons menés. Dans presque toutes les pendules les pignons ont 6 dents et sont menés. En voici un mais à 7 dents. Je n'ai trouvé que cela dans ma bibliothèque d'images. Je pourrais en sortir un en 6 dents et même à 5. Les couleurs autour, ce n'est pas pour faire joli. C'est le résultat d'une simulation faite il y 4 ans en PureBasic 3.94.
PIGNON HORLOGER

Cordialement.
SULREN
Il faut savoir rire dans la tragédie et être profond dans la joie.
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par djes »

Chouette post :)

LSI> Du grand LSI!!!
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par Le Soldat Inconnu »

Bon, j'ai résolu mon souci avec de petit nombre de dent. par contre, moi, je n'ai pas de déport. Mais ça peut s'intégrer. Faut que je fouille.

il ne me reste plus qu'a trouver l'équation de ellipse pour arrondir le haut de la crémaillère qui sert à "usiner l'engrenage"

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 4.40
;
; Explication du programme :
; Dessiner un engrenage


; Le filtre permet d'émuler de l'antialiasing sur le dessin de l'engrenage, ne pas mettre au dessus de 8
Global FiltreAA = 4, Dessin_Angle.d, Dessin_Zoom.d, Dessin.i


Enumeration
  #G_Module
  #G_Z
  #G_Angle_Pression
  #G_D_primitif
  #G_D_pied
  #G_D_tete
  #G_H_dent
  #G_Pas
  #G_Zoom
  #G_Dessin
  #G_Angle
EndEnumeration

#Engrenage_ResolutionDent = 200
#Equation_Degree = 2
#Engrenage_Couleur = $FF00FFFF
#Engrenage_Diametre = $200000FF
#Engrenage2_Couleur = $FF0000FF
#Cremaillere_Couleur = $40FFFFFF
#Cremaillere_Hauteur = $400000FF
Structure Structure_Equation
  x1.d
  x2.d
  v.d[#Equation_Degree + 1]
EndStructure
Structure Structure_Rayon
  R.d
  Angle.d
EndStructure
Structure Structure_Engrenage
  Module.d
  Z.d
  D_primitif.d
  D_tete.d
  D_pied.d
  H_dent.d
  Angle_pression.d
  Pas.d
  Contour.Structure_Rayon[#Engrenage_ResolutionDent]
  Cremaillere.Structure_Equation[5]
  Outil.Structure_Equation[5]
EndStructure

Global Engrenage.Structure_Engrenage

Procedure.s AfficheValeur(Valeur.d)
  ProcedureReturn Trim(Trim(Trim(StrD(Valeur), "0"), "."), ",")
EndProcedure

Procedure Engrenage_Calcul(*Calcul.Structure_Engrenage)
  With * Calcul
    ;- Paramètres de l'engrenage
    \D_primitif = \Z * \Module
    \D_tete = \D_primitif + 2 * \Module
    \D_pied = \D_primitif - 2.5 * \Module
    \Pas = #PI * \Module
    \H_dent = 2.25 * \Module
    ;- Equation de la crémaillère
    Largeur_zone_inclinee.d = 2.25 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_tete.d = \Pas / 2 - 2 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_pied.d = \Pas / 2 - 2.5 * \Module * Sin(\Angle_pression * #PI / 180)
    
    ; Zone 1
    \Cremaillere[0]\x1 = 0
    \Cremaillere[0]\x2 = Largeur_zone_tete / 2
    \Cremaillere[0]\v[0] = \H_dent
    ; zone 2
    \Cremaillere[1]\x1 = \Cremaillere[0]\x2
    \Cremaillere[1]\x2 = \Cremaillere[1]\x1 + Largeur_zone_inclinee
    \Cremaillere[1]\v[1] = -2.25 * \Module / Largeur_zone_inclinee
    \Cremaillere[1]\v[0] = \H_dent - \Cremaillere[1]\v[1] * Largeur_zone_tete / 2
    ; zone 3
    \Cremaillere[2]\x1 = \Cremaillere[1]\x2
    \Cremaillere[2]\x2 = \Cremaillere[2]\x1 + Largeur_zone_pied
    ; \Cremaillere[2]\v[2] = 2 * \Module / Largeur_zone_inclinee / Largeur_zone_pied
    ; \Cremaillere[2]\v[1] = \Cremaillere[1]\v[1] - 2 * \Cremaillere[2]\v[2] * \Cremaillere[2]\x1
    ; \Cremaillere[2]\v[0] = 0.25 * \Module - \Cremaillere[2]\v[2] * \Cremaillere[2]\x1 * \Cremaillere[2]\x1 - \Cremaillere[2]\v[1] * \Cremaillere[2]\x1
    ; Zone 4
    \Cremaillere[3]\x1 = \Cremaillere[2]\x2
    \Cremaillere[3]\x2 = \Cremaillere[3]\x1 + Largeur_zone_inclinee
    \Cremaillere[3]\v[1] = 2.25 * \Module / Largeur_zone_inclinee
    \Cremaillere[3]\v[0] = -\Cremaillere[3]\v[1] *(Largeur_zone_tete / 2 + Largeur_zone_inclinee + Largeur_zone_pied)
    ; Zone 5
    \Cremaillere[4]\x1 = \Cremaillere[3]\x2
    \Cremaillere[4]\x2 = \Pas
    \Cremaillere[4]\v[0] = \H_dent
    
    
    Largeur_zone_inclinee.d = 2.25 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_tete.d = \Pas / 2 - 2.5 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_pied.d = \Pas / 2 - 2 * \Module * Sin(\Angle_pression * #PI / 180)
    ; Zone 1
    \Outil[0]\x1 = 0
    \Outil[0]\x2 = Largeur_zone_tete / 2
    \Outil[0]\v[0] = \H_dent + 0.25 * \Module
    ; zone 2
    \Outil[1]\x1 = \Outil[0]\x2
    \Outil[1]\x2 = \Outil[1]\x1 + Largeur_zone_inclinee
    \Outil[1]\v[1] = -2.25 * \Module / Largeur_zone_inclinee
    \Outil[1]\v[0] = \H_dent + 0.25 * \Module - \Outil[1]\v[1] * Largeur_zone_tete / 2
    ; zone 3
    \Outil[2]\x1 = \Outil[1]\x2
    \Outil[2]\x2 = \Outil[2]\x1 + Largeur_zone_pied
    \Outil[2]\v[0] = 0.25 * \Module
    ; Zone 4
    \Outil[3]\x1 = \Outil[2]\x2
    \Outil[3]\x2 = \Outil[3]\x1 + Largeur_zone_inclinee
    \Outil[3]\v[1] = 2.25 * \Module / Largeur_zone_inclinee
    \Outil[3]\v[0] = 0.25 * \Module - \Outil[3]\v[1] *(Largeur_zone_tete / 2 + Largeur_zone_inclinee + Largeur_zone_pied)
    ; Zone 5
    \Outil[4]\x1 = \Outil[3]\x2
    \Outil[4]\x2 = \Pas
    \Outil[4]\v[0] = \H_dent + 0.25 * \Module
    
		; CopyMemory(@\Cremaillere, @\Outil, SizeOf(Structure_Equation) * 5)
		
    ; Reset de la taille de l'engrenage
    For x = 0 To #Engrenage_ResolutionDent - 1
      \Contour[x]\R = \D_tete / 2
      \Contour[x]\Angle = x * 2 * #PI / #Engrenage_ResolutionDent / \Z
    Next
    
    ;- Affichage des résultats
    SetGadgetText(#G_D_primitif, AfficheValeur(Engrenage\D_primitif))
    SetGadgetText(#G_D_tete, AfficheValeur(Engrenage\D_tete))
    SetGadgetText(#G_D_pied, AfficheValeur(Engrenage\D_pied))
    SetGadgetText(#G_H_dent, AfficheValeur(Engrenage\H_dent))
    SetGadgetText(#G_Pas, AfficheValeur(Engrenage\Pas))
    
  EndWith
EndProcedure

Procedure Engrenage_Diametre(*Calcul.Structure_Engrenage)
  With * Calcul
    If \Module > 0 And \Z > 0 And \Angle_pression > 0 And \D_pied > 0
      
      ;- Calcul des rayons avec l'angle par défaut
      For x = 0 To #Engrenage_ResolutionDent - 1
        Angle_reel.d = x * 2 * #PI / #Engrenage_ResolutionDent / \Z
        x_reel.d = \D_primitif * Angle_reel / 2
        
        While x_reel >= \Pas And \Pas > 0
          x_reel - \Pas
        Wend
        If x_reel < 0
          x_reel = 0
        EndIf
        For n = 0 To 4
          If x_reel >= \Outil[n]\x1 And x_reel < \Outil[n]\x2
            y_reel.d = \Outil[n]\v[0]
            For nn = 1 To #Equation_Degree
              y_reel.d + \Outil[n]\v[nn] * Pow(x_reel, nn)
            Next
            Break
          EndIf
        Next
        
        \Contour[x]\R =(\D_primitif / 2 + 1.25 * \Module) - y_reel
        If \Contour[x]\R > \D_tete / 2
          \Contour[x]\R = \D_tete / 2
        EndIf
        If \Contour[x]\R < \D_pied / 2
          \Contour[x]\R = \D_pied / 2
        EndIf
        
        \Contour[x]\Angle = x * 2 * #PI / #Engrenage_ResolutionDent / \Z
        
      Next
      
      ;- Correction de l'angle
      
      ; Centre de l'engrenage
      x_reel.d = 0
      y_reel.d =(\D_primitif / 2 + 1.25 * \Module)
      
      Correction.d = 1 / #Engrenage_ResolutionDent / \Z
      
			Rotation.d = #Engrenage_ResolutionDent * \Z / 4
			If Rotation < #Engrenage_ResolutionDent * 2
				Rotation = #Engrenage_ResolutionDent * 2
			EndIf
			
      For Z = -Rotation To Rotation
        
        Angle.d = Z * 2 * #PI / #Engrenage_ResolutionDent / \Z
        Avance.d = \D_primitif * Angle / 2
        
        For x = 0 To #Engrenage_ResolutionDent - 1
          
          ; Correction positive
          Angle_correction_p.d = \Contour[x]\Angle
          Repeat
            
            Angle_reel.d = Angle_correction_p + Angle
            x1_reel.d = x_reel + \Contour[x]\R * Sin(Angle_reel) - Avance
            y1_reel.d = y_reel - \Contour[x]\R * Cos(Angle_reel)
            
            While x1_reel < 0 And \Pas > 0
              x1_reel + \Pas
            Wend
            While x1_reel >= \Pas And \Pas > 0
              x1_reel - \Pas
            Wend
            For n = 0 To 4
              If x1_reel >= \Outil[n]\x1 And x1_reel < \Outil[n]\x2
                y2_reel.d = \Outil[n]\v[0]
                For nn = 1 To #Equation_Degree
                  y2_reel.d + \Outil[n]\v[nn] * Pow(x1_reel, nn)
                Next
                Break
              EndIf
            Next
            
            If y1_reel < y2_reel
              
              Angle_correction_p + Correction
              
            EndIf
            
          Until y1_reel >= y2_reel
          
          ; Correction négative
          Angle_correction_n.d = \Contour[x]\Angle
          Repeat
            
            Angle_reel.d = Angle_correction_n + Angle
            x1_reel.d = x_reel + \Contour[x]\R * Sin(Angle_reel) - Avance
            y1_reel.d = y_reel - \Contour[x]\R * Cos(Angle_reel)
            
            While x1_reel < 0 And \Pas > 0
              x1_reel + \Pas
            Wend
            While x1_reel >= \Pas And \Pas > 0
              x1_reel - \Pas
            Wend
            For n = 0 To 4
              If x1_reel >= \Outil[n]\x1 And x1_reel < \Outil[n]\x2
                y2_reel.d = \Outil[n]\v[0]
                For nn = 1 To #Equation_Degree
                  y2_reel.d + \Outil[n]\v[nn] * Pow(x1_reel, nn)
                Next
                Break
              EndIf
            Next
            
            If y1_reel < y2_reel
              
              Angle_correction_n - Correction
              
            EndIf
            
          Until y1_reel >= y2_reel
          
          ; Choix de la corretion
          If \Contour[x]\Angle - Angle_correction_n < Angle_correction_p - \Contour[x]\Angle
            \Contour[x]\Angle = Angle_correction_n
          Else
            \Contour[x]\Angle = Angle_correction_p
          EndIf
          
        Next
      Next
    EndIf
  EndWith
EndProcedure

Procedure Engrenage_Dessin(Gadget, Image, *Calcul.Structure_Engrenage, Angle.d, Zoom.d = 0)
  ; Calcul du diamètre de l'engrenage
  ; Engrenage_Diametre(@*Calcul.Structure_Engrenage, Angle.d)
  
  LoadFont(1, "Tahoma", 9 * FiltreAA, #PB_Font_HighQuality)
  
  With * Calcul
    Largeur = GadgetWidth(Gadget) * FiltreAA
    Hauteur = GadgetHeight(Gadget) * FiltreAA
    Echelle.d =(2 * \Pas *(1 - Zoom) + \D_tete * Zoom) /(Largeur - 32 * FiltreAA)
    x0 = Largeur / 2
    y0 = Hauteur / 3 - 1.25 * \Module / Echelle
    
    ; De combien la crémaillère se déplace pour l'angle donné
    Avance.d = \D_primitif * Angle / 2
    
    CreateImage(Image, Largeur, Hauteur, 24)
    StartDrawing(ImageOutput(Image))
      DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
      Box(0, 0, Largeur, Hauteur, $FF000000)
      
      If \Module > 0 And \Z > 0 And \Angle_pression > 0 And \D_pied > 0
        
        If Dessin = 0 Or FiltreAA = 1
          ; Centre de l'engrenage
          x_reel.d = 0
          y_reel.d =(\D_primitif / 2 + 1.25 * \Module)
          ; Dessin de l'engrenage
          Angle_reel.d = \Contour[0]\Angle + Angle
          x1_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
          y1_reel.d = y_reel - \Contour[0]\R * Cos(Angle_reel)
          For nn = 0 To \Z - 1
            For n = 1 To #Engrenage_ResolutionDent - 1
              Angle_reel.d = \Contour[n]\Angle + 2 * #PI * nn / \Z + Angle
              x2_reel.d = x_reel + \Contour[n]\R * Sin(Angle_reel)
              y2_reel.d = y_reel - \Contour[n]\R * Cos(Angle_reel)
              ; Debug StrD(x2_reel, 4) + " / " + StrD(y2_reel, 4)
              LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage_Couleur)
              x1_reel = x2_reel
              y1_reel = y2_reel
            Next
          Next
          Angle_reel.d = \Contour[0]\Angle + Angle
          x2_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
          y2_reel.d = y_reel - \Contour[0]\R * Cos(Angle_reel)
          LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage_Couleur)
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Remplissage de l'engrenage
          If y0 + y_reel / Echelle > Hauteur
            y = Hauteur - 1
          Else
            y = y0 + y_reel / Echelle
          EndIf
          FillArea(x0, y, #Engrenage_Couleur, #Engrenage_Couleur)
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Dessin de la crémaillère et de l'outil
          For x = 0 To Largeur - 1
            x_reel.d =(x - x0) * Echelle - Avance
            While x_reel < 0 And \Pas > 0
              x_reel + \Pas
            Wend
            While x_reel >= \Pas And \Pas > 0
              x_reel - \Pas
            Wend
            
            ; Dessin de la crémaillère
            For n = 0 To 4
              If x_reel >= \Cremaillere[n]\x1 And x_reel < \Cremaillere[n]\x2
                y_reel.d = \Cremaillere[n]\v[0]
                For nn = 1 To #Equation_Degree
                  y_reel.d + \Cremaillere[n]\v[nn] * Pow(x_reel, nn)
                Next
                Break
              EndIf
            Next
            y = y_reel / Echelle + y0
            LineXY(x, y, x, 0, #Cremaillere_Couleur)
            
            ; Dessin de l'outil d'usinage
            For n = 0 To 4
              If x_reel >= \Outil[n]\x1 And x_reel < \Outil[n]\x2
                y_reel.d = \Outil[n]\v[0]
                For nn = 1 To #Equation_Degree
                  y_reel.d + \Outil[n]\v[nn] * Pow(x_reel, nn)
                Next
                Break
              EndIf
            Next
            y = y_reel / Echelle + y0
            LineXY(x, y, x, 0, #Cremaillere_Couleur)
            
          Next
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Centre de l'engrenage
          x_reel.d = 0
          y_reel.d =(\D_primitif / 2 + 1.25 * \Module)
          ; Dessin du diametre de pied
          Circle(x0, y0 + y_reel / Echelle,(\D_pied / 2) / Echelle, #Engrenage_Diametre)
          Box(0, y0 +(2.5 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; Dessin du diametre primitif
          Circle(x0, y0 + y_reel / Echelle,(\D_primitif / 2) / Echelle, #Engrenage_Diametre)
          Box(0, y0 +(1.25 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; Dessin du diametre de tête
          Circle(x0, y0 + y_reel / Echelle,(\D_tete / 2) / Echelle, #Engrenage_Diametre)
          Box(0, y0 +(0.25 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; pied de la crémaillère
          Box(0, y0 - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; Tête de la crémaillère
          Box(0, y0 +(2.25 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; centre
          Box(x0 - FiltreAA / 2, 0, FiltreAA, Hauteur, #Cremaillere_Hauteur)
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Centre de l'engrenage
          x_reel.d = 0
          y_reel.d =(1.25 * \Module - \D_primitif / 2)
          ; Dessin de l'engrenage
          Angle_reel.d = -\Contour[0]\Angle + Angle + #PI / \Z
          x1_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
          y1_reel.d = y_reel + \Contour[0]\R * Cos(Angle_reel)
          For nn = 0 To \Z - 1
            For n = 1 To #Engrenage_ResolutionDent - 1
              Angle_reel.d = \Contour[n]\Angle + 2 * #PI * nn / \Z + Angle + #PI / \Z
              x2_reel.d = x_reel + \Contour[n]\R * Sin(Angle_reel)
              y2_reel.d = y_reel + \Contour[n]\R * Cos(Angle_reel)
              ; Debug StrD(x2_reel, 4) + " / " + StrD(y2_reel, 4)
              LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage2_Couleur)
              x1_reel = x2_reel
              y1_reel = y2_reel
            Next
          Next
          Angle_reel.d = -\Contour[0]\Angle + Angle + #PI / \Z
          x2_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
          y2_reel.d = y_reel + \Contour[0]\R * Cos(Angle_reel)
          LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage2_Couleur)
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Dessin de l'échelle
          DrawingFont(FontID(1))
          Longueur.d = 1 / Echelle
          Texte.s = "1 mm"
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 5 / Echelle
            Texte.s = "5 mm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 10 / Echelle
            Texte.s = "1 cm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 50 / Echelle
            Texte.s = "5 cm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 100 / Echelle
            Texte.s = "1 dm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 500 / Echelle
            Texte.s = "5 dm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 1000 / Echelle
            Texte.s = "1 m"
          EndIf
          DrawText(x0 +(Longueur - TextWidth(Texte)) / 2, Hauteur - 16 * FiltreAA - TextHeight(Texte), Texte, $FFFFFFFF)
          Box(x0, Hauteur - 16 * FiltreAA, Longueur, FiltreAA, $FFFFFFFF)
          Box(x0, Hauteur - 16 * FiltreAA - Longueur, FiltreAA, Longueur, $FFFFFFFF)
        EndIf
        
      EndIf
    StopDrawing()
    If Dessin = 0 Or FiltreAA = 1
      If FiltreAA > 1
        ResizeImage(Image, Largeur / FiltreAA, Hauteur / FiltreAA, #PB_Image_Smooth)
      EndIf
      SetGadgetState(#G_Dessin, ImageID(0))
    EndIf
    
    FreeFont(1)
    
  EndWith
EndProcedure

Procedure Affichage(Parametre.i)
  
  Repeat
    
    While Dessin = 0 And Compteur < 50
      Delay(20)
      If FiltreAA = 1
        Compteur + 1
      EndIf
    Wend
    
    If Dessin > 0
      Dessin = 0
      FiltreAA = 1
      Affichage = 1
    EndIf
    If Compteur >= 50
      FiltreAA = 4
      Compteur = 0
      Affichage = 1
    EndIf
    
    If Affichage
      Affichage = 0
      
      Engrenage_Dessin(#G_Dessin, 0, @Engrenage, Dessin_Angle, Dessin_Zoom)
      
    EndIf
    
  Until Dessin < 0
  MessageRequester("oups", "fin")
EndProcedure



; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 800, 600, "Taillage d'engrenage", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
  End
EndIf

LoadFont(0, "Tahoma", 9, #PB_Font_HighQuality)
SetGadgetFont(#PB_Default, FontID(0))

Engrenage\Module = 1
Engrenage\Z = 15
Engrenage\Angle_pression = 20

x = 4
y = 4
Largeur = 192
TextGadget(#PB_Any, x, y, Largeur, 16, "Module")
y + 16
StringGadget(#G_Module, x, y, Largeur, 24, AfficheValeur(Engrenage\Module))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Z (Nombre de dents)")
y + 16
StringGadget(#G_Z, x, y, Largeur, 24, AfficheValeur(Engrenage\Z))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Angle de pression (en °)")
y + 16
StringGadget(#G_Angle_Pression, x, y, Largeur, 24, AfficheValeur(Engrenage\Angle_pression))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Diamètre primitif")
y + 16
StringGadget(#G_D_primitif, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Diamètre de tête")
y + 16
StringGadget(#G_D_tete, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Diamètre de pied")
y + 16
StringGadget(#G_D_pied, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Hauteur de dent")
y + 16
StringGadget(#G_H_dent, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Pas")
y + 16
StringGadget(#G_Pas, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8

TextGadget(#PB_Any, x, y, Largeur, 16, "Zoom d'affichage")
y + 16
TrackBarGadget(#G_Zoom, x, y, Largeur, 32, 0, 10, #PB_TrackBar_Ticks)
Dessin_Zoom.d = 0
y + 32
TextGadget(#PB_Any, x, y, Largeur, 16, "Rotation de l'engrenage")
y + 16
TrackBarGadget(#G_Angle, x, y, Largeur, 32, 0, 36, #PB_TrackBar_Ticks)
Dessin_Angle.d = 0
y + 32

CreateImage(0, 600 - 8, 600 - 8, 24)
ImageGadget(#G_Dessin, 204, 4, ImageWidth(0), ImageHeight(0), ImageID(0))

Engrenage_Calcul(@Engrenage)
Engrenage_Diametre(@Engrenage)
Engrenage_Dessin(#G_Dessin, 0, @Engrenage, 0)

Dessin = 1
Thread = CreateThread(@Affichage(), 0)

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget() ; Gadgets
        Case #G_Module, #G_Z, #G_Angle_Pression
          If EventType() = #PB_EventType_Change
            Engrenage\Module = ValD(GetGadgetText(#G_Module))
            Engrenage\Z = ValD(GetGadgetText(#G_Z))
            Engrenage\Angle_pression = ValD(GetGadgetText(#G_Angle_Pression))
            Engrenage_Calcul(@Engrenage)
            Engrenage_Diametre(@Engrenage)
            Dessin + 1
          EndIf
        Case #G_Zoom
          Dessin_Zoom = GetGadgetState(#G_Zoom) / 10
          Dessin + 1
        Case #G_Angle
          Dessin_Angle.d = GetGadgetState(#G_Angle) * 2 * #PI /(36 * Engrenage\Z)
          Dessin + 1
      EndSelect
  EndSelect
  
Until Event = #PB_Event_CloseWindow
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par kernadec »

bonjour Soldat inconnu
je suis admiratif de ton travail, merci pour le partage.

bonne journée et bon voyage.

cordialement
SULREN
Messages : 56
Inscription : mar. 27/janv./2009 12:07
Localisation : Très proche de Toulouse, au nord-ouest

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par SULREN »

Bonjour Le Soldat,
Toujours aussi impressionnant!
Cela a l'air de tourner correctement maintenant pour les petits nombres de dents, avec phénomène d'interférence (creusement du pied de la dent par la pointe de la crémaillère) en l'absence de déport de denture.

Fais comme tu l'entends, mais si tu veux répondre pleinement au problème posé je te suggère:
- De ne plus parler d'ellipse au sujet de la pointe de la crémaillère. Il s'agit de deux arcs de cercle de rayon 0,38 module. Regarde le dessin de la norme que j'ai posté plus haut.
- D'inclure la possibilité de faire du déport de denture: décalage de la crémaillère vers le haut pour les pignons, ou vers le bas pour les roues. Voir lien ci-dessous, avec déport de 1 module (oui je sais, on dirait une paire de n......).
PIGNON 6 DENTS - DEPORT 1
- D'éditer le fichier de la courbe du profil du fly-cutter dans un repère d'axes. L'objectif final de l'exercice n'est pas d'éditer une belle image mais de permettre la réalisation d'un outil de coupe pour tailler un engrenage réel. Pour usiner cet outil on a besoin de ses côtes.

Merci pour ton énorme travail.
Il faut savoir rire dans la tragédie et être profond dans la joie.
SULREN
Messages : 56
Inscription : mar. 27/janv./2009 12:07
Localisation : Très proche de Toulouse, au nord-ouest

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par SULREN »

Re
Le Soldat Inconnu a dit:
par contre, moi, je n'ai pas de déport. Mais ça peut s'intégrer. Faut que je fouille.
Vas bien sûr chercher des infos sur le sujet, ne serait-ce que pour vérifier ce que je dis, car nul, n’est à l’ abri d’une erreur, même un gars rigoureux. Quand j’ai eu à faire ces recherches il y a une paire d’années, j’y ai passé beaucoup de temps parce qu’il n’existait aucun document de synthèse. La norme AFNOR que j’ai n’en parle pas non plus.
Je te donne ci-dessous ce que j’ai compris de ce sujet:
1) Quand on fait du taillage sans déport, la ligne génératrice de la crémaillère roule sur le cercle primitif de l’ébauche à tailler. Je ne dis pas roue à tailler car le terme de roue est réservé à l’un des deux éléments de l’engrenage constitué par le couple roue / pignon
2) Le taillage avec déport revient à décaler la ligne génératrice de la crémaillère d’une certaine distance par rapport au cercle primitif de la roue. Ce décalage peut être positif ou négatif. Il s’exprime en général sous la forme d’un nombre « x » sans dimension qui vient multiplier le module. Déport en mm = module * x = m*x
3) Quand on taille avec déport il faut augmenter le diamètre extérieur de la roue à tailler d’une quantité 2*m*x dans le but bien sûr que la crémaillère puisse rencontrer de la matière à couper. Ce diamètre devient : Dext. = (Z+2+2*x)*m au lieu de Dext. = (Z+2)*m sans déport. Z est le nombre de dents.
4) Quand on taille le pignon avec un déport de « x », on peut :
Soit tailler la roue avec un déport de « - x » si on veut conserver l’entraxe théorique du couple roue / pignon, c'est-à-dire : Entraxe= (Zp + Zr)*m/2
Soit tailler la roue sans déport et à ce moment on doit augmenter l’entraxe de la quantité m*x.

Les raisons de pratiquer le déport sont :
1) En général, la nécessité d’éviter le phénomène d’interférence, qui commence à se poser vers, disons, Zp = 20 dents pour le pignon. Ce nombre est variable car il dépend aussi du nombre Zr de dents de la roue. Il existe un jeu d’équations pour déterminer s’il y aura interférence ou pas, en fonction de Zp et Zr.
2) Des raisons mécaniques : besoin d’augmenter l’entraxe, de rendre plus trapues les dents du pignon, etc.

C’est donc le concepteur de l’engrenage qui détermine le déport. Il faut lui laisser ce choix dans le menu de départ et peut être lui faire une proposition de déport basée sur la limite d’interférence.
En espérant que cela pourra t'aider.
@+
SULREN
Dernière modification par SULREN le lun. 01/mars/2010 12:12, modifié 1 fois.
Il faut savoir rire dans la tragédie et être profond dans la joie.
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par Le Soldat Inconnu »

Ajout du déport + optimisation du code, j'ai trouvé plus simple.

Une question sur le déport, un déport de 1 signifie que j'augmente le rayon primitif de l'engrenage de 1 mm ? (en gros) ou il faut partir du module comme tu le dis ?
Car je n'obtiens pas la même chose que toi.

Il ne me reste plus qu'à arrondir ma crémaillère. J'ai pigé comment faire (enfin j'espère)

derrière, pour le fichier de sortie, je ne sais pas de quoi tu as besoin

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 4.40
;
; Explication du programme :
; Dessiner un engrenage


; Le filtre permet d'émuler de l'antialiasing sur le dessin de l'engrenage, ne pas mettre au dessus de 8
Global FiltreAA = 4, Dessin_Angle.d, Dessin_Zoom.d, Dessin.i


Enumeration
  #G_Module
  #G_Z
  #G_Angle_Pression
  #G_D_primitif
  #G_D_pied
  #G_D_tete
  #G_H_dent
  #G_Pas
  #G_Deport
  #G_Zoom
  #G_Dessin
  #G_Angle
EndEnumeration

#Engrenage_ResolutionDent = 314
#Equation_Degree = 2
#Engrenage_Couleur = $FF00FFFF
#Engrenage_Diametre = $200000FF
#Engrenage2_Couleur = $FF0000FF
#Cremaillere_Couleur = $40FFFFFF
#Cremaillere_Hauteur = $400000FF
Structure Structure_Cercle
  x.d
  y.d
  R.d
EndStructure
Structure Structure_Equation
  x1.d
  x2.d
  v.d[#Equation_Degree + 1]
  c.Structure_Cercle
EndStructure
Structure Structure_Rayon
  R.d
  Angle.d
  Zone.b
EndStructure
Structure Structure_Engrenage
  Module.d
  Z.d
  D_primitif.d
  D_tete.d
  D_pied.d
  H_dent.d
  Angle_pression.d
  Pas.d
  Deport.d
  Contour.Structure_Rayon[#Engrenage_ResolutionDent]
  Cremaillere.Structure_Equation[5]
  Outil.Structure_Equation[5]
EndStructure

Global Engrenage.Structure_Engrenage

Procedure.s AfficheValeur(Valeur.d)
  ProcedureReturn Trim(Trim(Trim(StrD(Valeur), "0"), "."), ",")
EndProcedure

Procedure Engrenage_Calcul(*Calcul.Structure_Engrenage)
  With * Calcul
    ;- Paramètres de l'engrenage
    \D_primitif = \Z * \Module
    \D_tete = \D_primitif + 2 * \Module
    \D_pied = \D_primitif - 2.5 * \Module
    \Pas = #PI * \Module
    \H_dent = 2.25 * \Module
    ;- Equation de la crémaillère
    Largeur_zone_inclinee.d = 2.25 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_tete.d = \Pas / 2 - 2 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_pied.d = \Pas / 2 - 2.5 * \Module * Sin(\Angle_pression * #PI / 180)
    
    ; Zone 1
    \Cremaillere[0]\x1 = 0
    \Cremaillere[0]\x2 = Largeur_zone_tete / 2
    \Cremaillere[0]\v[0] = \H_dent
    ; zone 2
    \Cremaillere[1]\x1 = \Cremaillere[0]\x2
    \Cremaillere[1]\x2 = \Cremaillere[1]\x1 + Largeur_zone_inclinee
    \Cremaillere[1]\v[1] = -2.25 * \Module / Largeur_zone_inclinee
    \Cremaillere[1]\v[0] = \H_dent - \Cremaillere[1]\v[1] * Largeur_zone_tete / 2
    ; zone 3
    \Cremaillere[2]\x1 = \Cremaillere[1]\x2
    \Cremaillere[2]\x2 = \Cremaillere[2]\x1 + Largeur_zone_pied
    ; \Cremaillere[2]\v[2] = 2 * \Module / Largeur_zone_inclinee / Largeur_zone_pied
    ; \Cremaillere[2]\v[1] = \Cremaillere[1]\v[1] - 2 * \Cremaillere[2]\v[2] * \Cremaillere[2]\x1
    ; \Cremaillere[2]\v[0] = 0.25 * \Module - \Cremaillere[2]\v[2] * \Cremaillere[2]\x1 * \Cremaillere[2]\x1 - \Cremaillere[2]\v[1] * \Cremaillere[2]\x1
    ; Zone 4
    \Cremaillere[3]\x1 = \Cremaillere[2]\x2
    \Cremaillere[3]\x2 = \Cremaillere[3]\x1 + Largeur_zone_inclinee
    \Cremaillere[3]\v[1] = 2.25 * \Module / Largeur_zone_inclinee
    \Cremaillere[3]\v[0] = -\Cremaillere[3]\v[1] *(Largeur_zone_tete / 2 + Largeur_zone_inclinee + Largeur_zone_pied)
    ; Zone 5
    \Cremaillere[4]\x1 = \Cremaillere[3]\x2
    \Cremaillere[4]\x2 = \Pas
    \Cremaillere[4]\v[0] = \H_dent
    
    
    Largeur_zone_inclinee.d = 2.25 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_tete.d = \Pas / 2 - 2.5 * \Module * Sin(\Angle_pression * #PI / 180)
    Largeur_zone_pied.d = \Pas / 2 - 2 * \Module * Sin(\Angle_pression * #PI / 180)
    ; Zone 1
    \Outil[0]\x1 = 0
    \Outil[0]\x2 = Largeur_zone_tete / 2
    \Outil[0]\v[0] = \H_dent + 0.25 * \Module
    ; zone 2
    \Outil[1]\x1 = \Outil[0]\x2
    \Outil[1]\x2 = \Outil[1]\x1 + Largeur_zone_inclinee
    \Outil[1]\v[1] = -2.25 * \Module / Largeur_zone_inclinee
    \Outil[1]\v[0] = \H_dent + 0.25 * \Module - \Outil[1]\v[1] * Largeur_zone_tete / 2
    ; zone 3
    \Outil[2]\x1 = \Outil[1]\x2
    \Outil[2]\x2 = \Outil[2]\x1 + Largeur_zone_pied
    \Outil[2]\v[0] = 0.25 * \Module
    ; Zone 4
    \Outil[3]\x1 = \Outil[2]\x2
    \Outil[3]\x2 = \Outil[3]\x1 + Largeur_zone_inclinee
    \Outil[3]\v[1] = 2.25 * \Module / Largeur_zone_inclinee
    \Outil[3]\v[0] = 0.25 * \Module - \Outil[3]\v[1] *(Largeur_zone_tete / 2 + Largeur_zone_inclinee + Largeur_zone_pied)
    ; Zone 5
    \Outil[4]\x1 = \Outil[3]\x2
    \Outil[4]\x2 = \Pas
    \Outil[4]\v[0] = \H_dent + 0.25 * \Module
    
    ; CopyMemory(@\Cremaillere, @\Outil, SizeOf(Structure_Equation) * 5)
    
    ; Reset de la taille de l'engrenage
    For x = 0 To #Engrenage_ResolutionDent - 1
      \Contour[x]\R = \D_tete / 2
      \Contour[x]\Angle = x * 2 * #PI / #Engrenage_ResolutionDent / \Z
    Next
    
    ;- Affichage des résultats
    SetGadgetText(#G_D_primitif, AfficheValeur(Engrenage\D_primitif))
    SetGadgetText(#G_D_tete, AfficheValeur(Engrenage\D_tete))
    SetGadgetText(#G_D_pied, AfficheValeur(Engrenage\D_pied))
    SetGadgetText(#G_H_dent, AfficheValeur(Engrenage\H_dent))
    SetGadgetText(#G_Pas, AfficheValeur(Engrenage\Pas))
    
  EndWith
EndProcedure

Procedure Engrenage_Diametre(*Calcul.Structure_Engrenage)
  With * Calcul
    If \Module > 0 And \Z > 0 And \Angle_pression > 0 And \D_pied > 0
      
      ;- Calcul des rayons avec l'angle par défaut
      For x = 0 To #Engrenage_ResolutionDent - 1
        \Contour[x]\Angle.d = x * 2 * #PI / #Engrenage_ResolutionDent / \Z
        x_reel.d = \D_primitif * \Contour[x]\Angle / 2
        
        While x_reel >= \Pas And \Pas > 0
          x_reel - \Pas
        Wend
        If x_reel < 0
          x_reel = 0
        EndIf
        For n = 0 To 4
          If x_reel >= \Outil[n]\x1 And x_reel < \Outil[n]\x2
            y_reel.d = \Outil[n]\v[0]
            For nn = 1 To #Equation_Degree
              y_reel.d + \Outil[n]\v[nn] * Pow(x_reel, nn)
            Next
            Break
          EndIf
        Next
        
        \Contour[x]\R =(\D_primitif / 2 + 1.25 * \Module) + \Deport - y_reel
        If \Contour[x]\R > \D_tete / 2 + \Deport
          \Contour[x]\R = \D_tete / 2 + \Deport
        EndIf
        If \Contour[x]\R < \D_pied / 2 + \Deport
          \Contour[x]\R = \D_pied / 2 + \Deport
        EndIf
        
        If \Contour[x]\Angle < #PI / \Z
          \Contour[x]\Zone = 1
        Else
          \Contour[x]\Zone = 2
        EndIf
        
      Next
      
      ;- Correction de l'angle
      
      ; Centre de l'engrenage
      x_reel.d = 0
      y_reel.d =(\D_primitif / 2 + 1.25 * \Module) + \Deport
      
      Correction.d = 1 / #Engrenage_ResolutionDent / \Z
      
      Rotation.d = #Engrenage_ResolutionDent * \Z / 4
      If Rotation < #Engrenage_ResolutionDent * 2
        Rotation = #Engrenage_ResolutionDent * 2
      EndIf
      
      For Z = -Rotation To Rotation
        
        Angle.d = Z * 2 * #PI / #Engrenage_ResolutionDent / \Z
        Avance.d = \D_primitif * Angle / 2
        
        For x = 0 To #Engrenage_ResolutionDent - 1
          If \Contour[x]\R
            
            Repeat
              
              Angle_reel.d = \Contour[x]\Angle + Angle
              x1_reel.d = x_reel + \Contour[x]\R * Sin(Angle_reel) - Avance
              y1_reel.d = y_reel - \Contour[x]\R * Cos(Angle_reel)
              
              While x1_reel < 0 And \Pas > 0
                x1_reel + \Pas
              Wend
              While x1_reel >= \Pas And \Pas > 0
                x1_reel - \Pas
              Wend
              For n = 0 To 4
                If x1_reel >= \Outil[n]\x1 And x1_reel < \Outil[n]\x2
                  y2_reel.d = \Outil[n]\v[0]
                  For nn = 1 To #Equation_Degree
                    y2_reel.d + \Outil[n]\v[nn] * Pow(x1_reel, nn)
                  Next
                  Break
                EndIf
              Next
              
              If y1_reel < y2_reel
                
                If \Contour[x]\Zone = 1
                  \Contour[x]\Angle + Correction
                  If \Contour[x]\Angle > #PI / \Z
                    \Contour[x]\R = 0
                  EndIf
                Else
                  \Contour[x]\Angle - Correction
                  If \Contour[x]\Angle < #PI / \Z
                    \Contour[x]\R = 0
                  EndIf
                EndIf
                
              EndIf
              
            Until y1_reel >= y2_reel
            
          EndIf
        Next
      Next
    EndIf
  EndWith
EndProcedure

Procedure Engrenage_Dessin(Gadget, Image, *Calcul.Structure_Engrenage, Angle.d, Zoom.d = 0)
  ; Calcul du diamètre de l'engrenage
  ; Engrenage_Diametre(@*Calcul.Structure_Engrenage, Angle.d)
  
  LoadFont(1, "Tahoma", 9 * FiltreAA, #PB_Font_HighQuality)
  
  With * Calcul
    Largeur = GadgetWidth(Gadget) * FiltreAA
    Hauteur = GadgetHeight(Gadget) * FiltreAA
    Echelle.d =(2 * \Pas *(1 - Zoom) + \D_tete * Zoom) /(Largeur - 32 * FiltreAA)
    x0 = Largeur / 2
    y0 = Hauteur / 3 - 1.25 * \Module / Echelle
    
    ; De combien la crémaillère se déplace pour l'angle donné
    Avance.d = \D_primitif * Angle / 2
    
    CreateImage(Image, Largeur, Hauteur, 24)
    StartDrawing(ImageOutput(Image))
      DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_Transparent)
      Box(0, 0, Largeur, Hauteur, $FF000000)
      
      If \Module > 0 And \Z > 0 And \Angle_pression > 0 And \D_pied > 0
        
        If Dessin = 0 Or FiltreAA = 1
          ; Centre de l'engrenage
          x_reel.d = 0
          y_reel.d =(\D_primitif / 2 + 1.25 * \Module) + \Deport
          ; Dessin de l'engrenage
          Angle_reel.d = \Contour[0]\Angle + Angle
          x1_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
          y1_reel.d = y_reel - \Contour[0]\R * Cos(Angle_reel)
          For nn = 0 To \Z - 1
            For n = 1 To #Engrenage_ResolutionDent - 1
							If \Contour[n]\R
								Angle_reel.d = \Contour[n]\Angle + 2 * #PI * nn / \Z + Angle
								x2_reel.d = x_reel + \Contour[n]\R * Sin(Angle_reel)
								y2_reel.d = y_reel - \Contour[n]\R * Cos(Angle_reel)
								; Debug StrD(x2_reel, 4) + " / " + StrD(y2_reel, 4)
								LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage_Couleur)
								x1_reel = x2_reel
								y1_reel = y2_reel
							EndIf
            Next
          Next
          Angle_reel.d = \Contour[0]\Angle + Angle
          x2_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
          y2_reel.d = y_reel - \Contour[0]\R * Cos(Angle_reel)
          LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage_Couleur)
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Remplissage de l'engrenage
          If y0 + y_reel / Echelle > Hauteur
            y = Hauteur - 1
          Else
            y = y0 + y_reel / Echelle
          EndIf
          FillArea(x0, y, #Engrenage_Couleur, #Engrenage_Couleur)
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Dessin de la crémaillère et de l'outil
          For x = 0 To Largeur - 1
            x_reel.d =(x - x0) * Echelle - Avance
            While x_reel < 0 And \Pas > 0
              x_reel + \Pas
            Wend
            While x_reel >= \Pas And \Pas > 0
              x_reel - \Pas
            Wend
            
            ; Dessin de la crémaillère
            For n = 0 To 4
              If x_reel >= \Cremaillere[n]\x1 And x_reel < \Cremaillere[n]\x2
                y_reel.d = \Cremaillere[n]\v[0]
                For nn = 1 To #Equation_Degree
                  y_reel.d + \Cremaillere[n]\v[nn] * Pow(x_reel, nn)
                Next
                Break
              EndIf
            Next
            y = y_reel / Echelle + y0
            LineXY(x, y, x, 0, #Cremaillere_Couleur)
            
            ; Dessin de l'outil d'usinage
            For n = 0 To 4
              If x_reel >= \Outil[n]\x1 And x_reel < \Outil[n]\x2
                y_reel.d = \Outil[n]\v[0]
                For nn = 1 To #Equation_Degree
                  y_reel.d + \Outil[n]\v[nn] * Pow(x_reel, nn)
                Next
                Break
              EndIf
            Next
            y = y_reel / Echelle + y0
            LineXY(x, y, x, 0, #Cremaillere_Couleur)
            
          Next
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Centre de l'engrenage
          x_reel.d = 0
          y_reel.d =(\D_primitif / 2 + 1.25 * \Module) + \Deport
          ; Dessin du diametre de pied
          Circle(x0, y0 + y_reel / Echelle,(\D_pied / 2) / Echelle, #Engrenage_Diametre)
          Box(0, y0 +(2.5 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; Dessin du diametre primitif
          Circle(x0, y0 + y_reel / Echelle,(\D_primitif / 2) / Echelle, #Engrenage_Diametre)
          Box(0, y0 +(1.25 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; Dessin du diametre de tête
          Circle(x0, y0 + y_reel / Echelle,(\D_tete / 2) / Echelle, #Engrenage_Diametre)
          Box(0, y0 +(0.25 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; pied de la crémaillère
          Box(0, y0 - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; Tête de la crémaillère
          Box(0, y0 +(2.25 * \Module) / Echelle - FiltreAA / 2, Largeur, FiltreAA, #Cremaillere_Hauteur)
          ; centre
          Box(x0 - FiltreAA / 2, 0, FiltreAA, Hauteur, #Cremaillere_Hauteur)
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Centre de l'engrenage
          x_reel.d = 0
          y_reel.d =(1.25 * \Module - \D_primitif / 2) - \Deport
          ; Dessin de l'engrenage
          Angle_reel.d = -\Contour[0]\Angle + Angle + #PI / \Z
          x1_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
          y1_reel.d = y_reel + \Contour[0]\R * Cos(Angle_reel)
          For nn = 0 To \Z - 1
            For n = 1 To #Engrenage_ResolutionDent - 1
              Angle_reel.d = \Contour[n]\Angle + 2 * #PI * nn / \Z + Angle + #PI / \Z
							If \Contour[n]\R
								x2_reel.d = x_reel + \Contour[n]\R * Sin(Angle_reel)
								y2_reel.d = y_reel + \Contour[n]\R * Cos(Angle_reel)
								; Debug StrD(x2_reel, 4) + " / " + StrD(y2_reel, 4)
								LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage2_Couleur)
								x1_reel = x2_reel
								y1_reel = y2_reel
							EndIf
            Next
          Next
          Angle_reel.d = -\Contour[0]\Angle + Angle + #PI / \Z
          x2_reel.d = x_reel + \Contour[0]\R * Sin(Angle_reel)
          y2_reel.d = y_reel + \Contour[0]\R * Cos(Angle_reel)
          LineXY(x0 + x1_reel / Echelle, y0 + y1_reel / Echelle, x0 + x2_reel / Echelle, y0 + y2_reel / Echelle, #Engrenage2_Couleur)
        EndIf
        
        If Dessin = 0 Or FiltreAA = 1
          ; Dessin de l'échelle
          DrawingFont(FontID(1))
          Longueur.d = 1 / Echelle
          Texte.s = "1 mm"
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 5 / Echelle
            Texte.s = "5 mm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 10 / Echelle
            Texte.s = "1 cm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 50 / Echelle
            Texte.s = "5 cm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 100 / Echelle
            Texte.s = "1 dm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 500 / Echelle
            Texte.s = "5 dm"
          EndIf
          If TextWidth(Texte + "  ") > Longueur
            Longueur.d = 1000 / Echelle
            Texte.s = "1 m"
          EndIf
          DrawText(x0 +(Longueur - TextWidth(Texte)) / 2, Hauteur - 16 * FiltreAA - TextHeight(Texte), Texte, $FFFFFFFF)
          Box(x0, Hauteur - 16 * FiltreAA, Longueur, FiltreAA, $FFFFFFFF)
          Box(x0, Hauteur - 16 * FiltreAA - Longueur, FiltreAA, Longueur, $FFFFFFFF)
        EndIf
        
      EndIf
    StopDrawing()
    If Dessin = 0 Or FiltreAA = 1
      If FiltreAA > 1
        ResizeImage(Image, Largeur / FiltreAA, Hauteur / FiltreAA, #PB_Image_Smooth)
      EndIf
      SetGadgetState(#G_Dessin, ImageID(0))
    EndIf
    
    FreeFont(1)
    
  EndWith
EndProcedure

Procedure Affichage(Parametre.i)
  
  Repeat
    
    While Dessin = 0 And Compteur < 50
      Delay(20)
      If FiltreAA = 1
        Compteur + 1
      EndIf
    Wend
    
    If Dessin > 0
      Dessin = 0
      FiltreAA = 1
      Affichage = 1
    EndIf
    If Compteur >= 50
      FiltreAA = 4
      Compteur = 0
      Affichage = 1
    EndIf
    
    If Affichage
      Affichage = 0
      
      Engrenage_Dessin(#G_Dessin, 0, @Engrenage, Dessin_Angle, Dessin_Zoom)
      
    EndIf
    
  Until Dessin < 0
  MessageRequester("oups", "fin")
EndProcedure



; Création de la fenêtre et de la GadgetList
If OpenWindow(0, 0, 0, 800, 600, "Taillage d'engrenage", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget) = 0
  End
EndIf

LoadFont(0, "Tahoma", 9, #PB_Font_HighQuality)
SetGadgetFont(#PB_Default, FontID(0))

Engrenage\Module = 1
Engrenage\Z = 15
Engrenage\Angle_pression = 20

x = 4
y = 4
Largeur = 192
TextGadget(#PB_Any, x, y, Largeur, 16, "Module")
y + 16
StringGadget(#G_Module, x, y, Largeur, 24, AfficheValeur(Engrenage\Module))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Z (Nombre de dents)")
y + 16
StringGadget(#G_Z, x, y, Largeur, 24, AfficheValeur(Engrenage\Z))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Angle de pression (en °)")
y + 16
StringGadget(#G_Angle_Pression, x, y, Largeur, 24, AfficheValeur(Engrenage\Angle_pression))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Déport (en mm)")
y + 16
StringGadget(#G_Deport, x, y, Largeur, 24, AfficheValeur(Engrenage\Deport))
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Diamètre primitif")
y + 16
StringGadget(#G_D_primitif, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Diamètre de tête")
y + 16
StringGadget(#G_D_tete, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Diamètre de pied")
y + 16
StringGadget(#G_D_pied, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Hauteur de dent")
y + 16
StringGadget(#G_H_dent, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8
TextGadget(#PB_Any, x, y, Largeur, 16, "Pas")
y + 16
StringGadget(#G_Pas, x, y, Largeur, 24, "", #PB_String_ReadOnly)
y + 24
y + 8

TextGadget(#PB_Any, x, y, Largeur, 16, "Zoom d'affichage")
y + 16
TrackBarGadget(#G_Zoom, x, y, Largeur, 32, 0, 10, #PB_TrackBar_Ticks)
Dessin_Zoom.d = 0
y + 32
TextGadget(#PB_Any, x, y, Largeur, 16, "Rotation de l'engrenage")
y + 16
TrackBarGadget(#G_Angle, x, y, Largeur, 32, 0, 72)
Dessin_Angle.d = 0
y + 32

CreateImage(0, 600 - 8, 600 - 8, 24)
ImageGadget(#G_Dessin, 204, 4, ImageWidth(0), ImageHeight(0), ImageID(0))

Engrenage_Calcul(@Engrenage)
Engrenage_Diametre(@Engrenage)
Engrenage_Dessin(#G_Dessin, 0, @Engrenage, 0)

Dessin = 1
Thread = CreateThread(@Affichage(), 0)

Repeat
  Event = WaitWindowEvent()
  
  Select Event
    Case #PB_Event_Gadget
      Select EventGadget() ; Gadgets
        Case #G_Module, #G_Z, #G_Angle_Pression, #G_Deport
          If EventType() = #PB_EventType_Change
            Engrenage\Module = ValD(GetGadgetText(#G_Module))
            Engrenage\Z = ValD(GetGadgetText(#G_Z))
            Engrenage\Angle_pression = ValD(GetGadgetText(#G_Angle_Pression))
            Engrenage\Deport = ValD(GetGadgetText(#G_Deport))
            Engrenage_Calcul(@Engrenage)
            Engrenage_Diametre(@Engrenage)
            Dessin + 1
          EndIf
        Case #G_Zoom
          Dessin_Zoom = GetGadgetState(#G_Zoom) / 10
          Dessin + 1
        Case #G_Angle
          Dessin_Angle.d = GetGadgetState(#G_Angle) * 2 * #PI /(36 * Engrenage\Z)
          Dessin + 1
      EndSelect
  EndSelect
  
Until Event = #PB_Event_CloseWindow
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
SULREN
Messages : 56
Inscription : mar. 27/janv./2009 12:07
Localisation : Très proche de Toulouse, au nord-ouest

Re: Comment faire des tracés sur image - Taillage d'engrenages.

Message par SULREN »

Pas de chance, nos posts se sont croisés. Je venais de te parler du déport quand tu m'as posé la question à son sujet.

Concernant le fichier de sortie. Il s'agit de décrire le profil du fly-cutter par un tableau de chiffres. Ce profil est exactement celui du creux entre deux dents, puisque c'est le fly-cutter qui doit découper ce creux lors du taillage. Il suffit d'expliquer comment exploiter ces chiffres: soit par l'impression d'un dessin sur l'écran en montrant le profil et les variables associées, soit par un petit texte affiché sur l'ecran ou dans un fichier .txt.

Je vois le profil du fly-cutter représenté comme suit.
- Tu a vu la tête qu'il a sur les vues que je génère: une espèce de "courbe en cloche" dirigée vers le bas.
- On peut représenter cette cloche, dirigée vers le haut, dans un repère de coordonnées {0; x; y}
L'axe des y passe par l'axe de symétrie de la cloche et la coupe au point d'ordonnée y0
Les pieds de la cloche reposent sur l'axe des x en deux points: -x0 et +x0.
- Tu sors un fichier comportant deux colonnes: une x et une y.
- Dans la x on trouve en lisant du haut vers le bas les valeurs : 0, vx1, vx2, vx3,..........x0
- Dans la y on trouve en lisant du haut vers le bas les valeurs : y0, vy1, vy2, vy3,...... ....0

Cela donne le demi profil de la cloche. Ensuite l'utilisateur l'exploitera comme il veut pour générer les commandes de son tour en fonction de ses habitudes. Il fera sa tambouille sur Excel.

Quant à la différence de profil entre ce que tu trouves et ce que je trouve, à première vue je n'en vois pas, ton profil est correct sauf:
- Le fond de dent parce que tu n'utilises pas encore le bout arrondi pour la crémaillère.
- La forme des dents pour les pignons peu nombrés et c'est parce ce que tu ne tiens pas compte du déport qui est nécessaire. Mais la forme que tu trouve en l'absence de déport me parait correcte même pour des pignons de 6 dents.

PS je vais "digitaliser" le profil des dents de ton pignon de 6 dents avec l'outil que j'ai décrit dans mon autre fil de discussion. Hé Hé !
Il faut savoir rire dans la tragédie et être profond dans la joie.
Répondre