Page 3 sur 4

Publié : dim. 09/mai/2004 10:55
par Le Soldat Inconnu
j'arrive pas à faire le lissage, j'ai un problème avec la direction du lissage

voilà ou j'en suis :

Code : Tout sélectionner

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

Procedure.l Signe(nb.f)
  If Abs(nb) < 0.01
    Resultat.l = 0
  Else
    Resultat.l = nb / Abs(nb)
  EndIf
  ProcedureReturn Resultat
EndProcedure

Procedure Engrenage(x.l, y.l, Rayon.l, RayonAlesage.l, NbDents.l, HauteurDent.l, Decalage.f, Couleur.l)
  ; x, y : position duentre de l'engrenage
  ; Rayon : rayon de l'engrenage
  ; RayonAlesage : rayon du trou au centre de l'engrenage
  ; NbDents : nombre de dents
  ; HauteurDent : Hauteur des dents
  ; Decalage : norbre de dents de décalage par rapport à l'origine, utilise pour faire tourner l'engrenage
  ; Couleur : couleur de l'engrenage
  
  ; on crée une carte à la taille de l'image
  Dim CarteImage.l(ImageWidth(), ImageHeight())
  Dim CarteLissage.f(ImageWidth(), ImageHeight())
  
  StartDrawing(ImageOutput())
    
    ; on copie l'image de base pour le lissage
    For n = 0 To ImageWidth() - 1
      For nn = 0 To ImageHeight() - 1
        CarteImage(n, nn) = Point(n, nn)
      Next
    Next
    
    DrawingMode(4)
    Circle(x, y, Rayon - HauteurDent, Couleur) ; on dessine l'engrenage
    Circle(x, y, RayonAlesage, Couleur) ; on dessine le trou de l'engrenage
    DrawingMode(0) ; commenter ceci pour ne pas remplir l'engrenage
    FillArea(x, y + RayonAlesage + 3, Couleur, Couleur) ; on rempli l'engrenage
    
    LargeurDent = Int(Rayon * 3 / 5 * Sin(#PI / NbDents) + 0.5) ; on détermine la largeur d'une dents
    
    For n = 1 To NbDents ; on passe en revue toutes les dents
      
      Cos.f = Cos((n + Decalage) * 2 * #PI / NbDents) ; Calcul du cos de l'angle
      Sin.f = Sin((n + Decalage) * 2 * #PI / NbDents) ; Calcul du sin de l'angle
      
      ; Point haut gauche de la dent
      PosX1.f = x + Rayon * Cos + LargeurDent / 2 * Sin
      PosY1.f = y + Rayon * Sin - LargeurDent / 2 * Cos
      ; Point haut droit de la dent
      PosX2.f = x + Rayon * Cos - LargeurDent / 2 * Sin
      PosY2.f = y + Rayon * Sin + LargeurDent / 2 * Cos
      ; Point bas gauche de la dent
      PosX3.f = x + (Rayon - HauteurDent) * Cos + LargeurDent * Sin
      PosY3.f = y + (Rayon - HauteurDent) * Sin - LargeurDent * Cos
      ; Point bas droit de la dent
      PosX4.f = x + (Rayon - HauteurDent) * Cos - LargeurDent * Sin
      PosY4.f = y + (Rayon - HauteurDent) * Sin + LargeurDent * Cos
      ; Point vers le centre
      PosX5.f = x + (RayonAlesage + 5) * Cos
      PosY5.f = y + (RayonAlesage + 5) * Sin
      
      ; Dessin du contour de la dent
      LineXY(PosX1, PosY1, PosX2, PosY2, Couleur)
      LineXY(PosX1, PosY1, PosX3, PosY3, Couleur)
      LineXY(PosX2, PosY2, PosX4, PosY4, Couleur)
      LineXY(PosX3, PosY3, PosX5, PosY5, Couleur)
      LineXY(PosX4, PosY4, PosX5, PosY5, Couleur)
      
      ; Remplissage de la dent
      FillArea(Int(x + (Rayon - HauteurDent / 2) * Cos + 0.5), Int(y + (Rayon - HauteurDent / 2) * Sin + 0.5), Couleur, Couleur)
      
      ; On calcul le lissage de la dent
      PasX.f = (PosX2 - PosX1) / (5 * (LargeurDent + HauteurDent))
      PasY.f = (PosY2 - PosY1) / (5 * (LargeurDent + HauteurDent))
      For nn = 0 To (5 * (LargeurDent + HauteurDent))
        PosX = Int(PosX1 + PasX * nn + 0.5)
        PosY = Int(PosY1 + PasY * nn + 0.5)
        For i = -1 To 1
          For ii = -1 To 1
            CoefX.f = (PosX1 + PasX * nn - PosX - i)
            CoefY.f = (PosY1 + PasY * nn - PosY - ii)
            Coef.f = 1 - Sqr(Pow(CoefX, 2) + Pow(CoefY, 2))
            If Coef > CarteLissage(PosX + i, PosY + ii) And Signe(CoefX) = Signe(-Cos) And Signe(CoefY) = Signe(-Sin)
              CarteLissage(PosX + i, PosY + ii) = Coef
            EndIf
          Next
        Next
      Next
      
      PasX.f = (PosX3 - PosX1) / (5 * (LargeurDent + HauteurDent))
      PasY.f = (PosY3 - PosY1) / (5 * (LargeurDent + HauteurDent))
      For nn = 0 To (5 * (LargeurDent + HauteurDent))
        PosX = Int(PosX1 + PasX * nn + 0.5)
        PosY = Int(PosY1 + PasY * nn + 0.5)
        For i = -1 To 1
          For ii = -1 To 1
            CoefX.f = (PosX1 + PasX * nn - PosX - i)
            CoefY.f = (PosY1 + PasY * nn - PosY - ii)
            Coef.f = 1 - Sqr(Pow(CoefX, 2) + Pow(CoefY, 2))
            If Coef > CarteLissage(PosX + i, PosY + ii) And Signe(CoefX) = Signe(-Sin) And Signe(CoefY) = Signe(Cos)
              CarteLissage(PosX + i, PosY + ii) = Coef
            EndIf
          Next
        Next
      Next
      
      PasX.f = (PosX4 - PosX2) / (5 * (LargeurDent + HauteurDent))
      PasY.f = (PosY4 - PosY2) / (5 * (LargeurDent + HauteurDent))
      For nn = 0 To (5 * (LargeurDent + HauteurDent))
        PosX = Int(PosX2 + PasX * nn + 0.5)
        PosY = Int(PosY2 + PasY * nn + 0.5)
        For i = -1 To 1
          For ii = -1 To 1
            CoefX.f = (PosX2 + PasX * nn - PosX - i)
            CoefY.f = (PosY2 + PasY * nn - PosY - ii)
            Coef.f = 1 - Sqr(Pow(CoefX, 2) + Pow(CoefY, 2))
            If Coef > CarteLissage(PosX + i, PosY + ii) And Signe(CoefX) = Signe(Sin) And Signe(CoefY) = Signe(-Cos)
              CarteLissage(PosX + i, PosY + ii) = Coef
              If n = NbDents
                Debug Str(PosX) + " + " + Str(i)
                Debug Str(PosY) + " + " + Str(ii)
                Debug StrF(CoefX, 3) + " > " + Str(Signe(CoefX))
                Debug StrF(Sin, 3) + " > " + Str(Signe(Sin))
                Debug StrF(CoefY, 3) + " > " + Str(Signe(CoefY))
                Debug StrF(-Cos, 3) + " > " + Str(Signe(-Cos))
                Debug ""
              EndIf
            EndIf
          Next
        Next
      Next
      
    Next
    
    ; On affiche le lissage
    For i = 0 To ImageWidth() - 1
      For ii = 0 To ImageHeight() - 1
        If CarteLissage(i, ii) > 0
          Rouge = Int(Red(Couleur) * CarteLissage(i, ii) + Red(CarteImage(i, ii)) * (1 - CarteLissage(i, ii)) + 0.5)
          Vert = Int(Green(Couleur) * CarteLissage(i, ii) + Green(CarteImage(i, ii)) * (1 - CarteLissage(i, ii)) + 0.5)
          Bleu = Int(Blue(Couleur) * CarteLissage(i, ii) + Blue(CarteImage(i, ii)) * (1 - CarteLissage(i, ii)) + 0.5)
          Plot(i, ii, RGB(Rouge, Vert, Bleu))
        EndIf
      Next
    Next
    
  StopDrawing()
  
EndProcedure


;- Exemple

; Création de la fenêtre et dela GadgetList
If OpenWindow(0, 0, 0, 300, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Test") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf

; Création de l'image
CreateImage(0, 300, 300)
StartDrawing(ImageOutput())
  For n = 0 To 149
    Box(0, 2 * n, 300, 2, RGB(0, 0, 255 - n))
  Next
StopDrawing()

; On dessine l'engrenage
Engrenage(150, 150, 120, 40, 16, 30, 0.1, RGB(255, 255, 255))

; On affiche l'image
ImageGadget(0, 0, 0, 300, 300, UseImage(0))

; Sauvegarde de l'image
; UsePNGImageEncoder()
; SaveImage(0, "Engrenage.png", #PB_ImagePlugin_PNG)

Repeat
  Event = WaitWindowEvent()
  
Until Event = #PB_EventCloseWindow

End

Publié : dim. 09/mai/2004 13:00
par Flype
c pas si mal déjà regis

toute facon, je comprends rien à ton lissage.
apparemment tu créé une matrice de points...
ca effectivement pas l'air simple

Publié : dim. 09/mai/2004 15:20
par Le Soldat Inconnu
bon allez, un lissage pas génial mais qui marche ;)

c'est du travail de cochon mais bon

j'agrandie l'image, je dessine l'engrenage zoomé et je réduit l'image donc un léger effet de lissage. c'est super lent mais c'est mieux que rien, ça peut permettre de faire l'image tube pour GadAnim :D

Code : Tout sélectionner

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

#Pi.f = 3.14159265

Procedure Engrenage(ImageID.l, x.l, y.l, Rayon.l, RayonAlesage.l, NbDents.l, HauteurDent.l, Decalage.f, Couleur.l)
  ; Numero de l'image
  ; x, y : position duentre de l'engrenage
  ; Rayon : rayon de l'engrenage
  ; RayonAlesage : rayon du trou au centre de l'engrenage
  ; NbDents : nombre de dents
  ; HauteurDent : Hauteur des dents
  ; Decalage : norbre de dents de décalage par rapport à l'origine, utilise pour faire tourner l'engrenage
  ; Couleur : couleur de l'engrenage

  #Agrandissement = 10

  UseImage(ImageID)
  TailleX = ImageWidth()
  TailleY = ImageHeight()
  ResizeImage(ImageID, #Agrandissement * TailleX, #Agrandissement * TailleY)
  
  x = x * #Agrandissement
  y = y * #Agrandissement
  Rayon = Rayon * #Agrandissement
  RayonAlesage = RayonAlesage * #Agrandissement
  HauteurDent = HauteurDent * #Agrandissement
  
  UseImage(ImageID)
  StartDrawing(ImageOutput())
  
    DrawingMode(4)
    Circle(x, y, Rayon - HauteurDent, Couleur) ; on dessine l'engrenage
    Circle(x, y, RayonAlesage, Couleur) ; on dessine le trou de l'engrenage
    DrawingMode(0)
    FillArea(x, y + RayonAlesage + 2, Couleur, Couleur) ; on rempli l'engrenage
     
    LargeurDent = Int(Rayon * 3 / 5 * Sin(#Pi / NbDents) + 0.5) ; on détermine la largeur d'une dents
    
    For n = 1 To NbDents ; on passe en revue toutes les dents
      
      Cos.f = Cos((n + Decalage) * 2 * #Pi / NbDents) ; Calcul du cos de l'angle
      Sin.f = Sin((n + Decalage) * 2 * #Pi / NbDents) ; Calcul du sin de l'angle
      
      ; Point haut gauche de la dent
      PosX1.f = x + Rayon * Cos + LargeurDent / 2 * Sin
      PosY1.f = y + Rayon * Sin - LargeurDent / 2 * Cos
      ; Point haut droit de la dent
      PosX2.f = x + Rayon * Cos - LargeurDent / 2 * Sin
      PosY2.f = y + Rayon * Sin + LargeurDent / 2 * Cos
      ; Point bas gauche de la dent
      PosX3.f = x + (Rayon - HauteurDent) * Cos + LargeurDent * Sin
      PosY3.f = y + (Rayon - HauteurDent) * Sin - LargeurDent * Cos
      ; Point bas droit de la dent
      PosX4.f = x + (Rayon - HauteurDent) * Cos - LargeurDent * Sin
      PosY4.f = y + (Rayon - HauteurDent) * Sin + LargeurDent * Cos
      ; Point vers le centre
      PosX5.f = x + (RayonAlesage + 5) * Cos
      PosY5.f = y + (RayonAlesage + 5) * Sin
      
      ; Dessin du contour de la dent
      LineXY(PosX1, PosY1, PosX2, PosY2, Couleur)
      LineXY(PosX1, PosY1, PosX3, PosY3, Couleur)
      LineXY(PosX2, PosY2, PosX4, PosY4, Couleur)
      LineXY(PosX3, PosY3, PosX5, PosY5, Couleur)
      LineXY(PosX4, PosY4, PosX5, PosY5, Couleur)
      
      ; Remplissage de la dent
      FillArea(Int(x + (Rayon - HauteurDent / 2) * Cos + 0.5), Int(y + (Rayon - HauteurDent / 2) * Sin + 0.5), Couleur, Couleur)
      
    Next
  StopDrawing()
  
  ResizeImage(ImageID, TailleX, TailleY)
EndProcedure


;- Exemple

; Création de la fenêtre et dela GadgetList
If OpenWindow(0, 0, 0, 300, 300, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Test") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf

; Création de l'image
CreateImage(0, 300, 300)
StartDrawing(ImageOutput())
  Box(0, 0, 300, 300, RGB(255, 255, 255))
  Circle(50, 50, 50, RGB(255, 0, 0))
StopDrawing()

; On dessine l'engrenage
Engrenage(0, 150, 150, 120, 40, 16, 30, 0.6, RGB(0, 0, 0))

; On affiche l'image
ImageGadget(0, 0, 0, 300, 300, UseImage(0))

; Sauvegarde de l'image
; UsePNGImageEncoder()
; SaveImage(0, "Engrenage.png", #PB_ImagePlugin_PNG)

Repeat
  Event = WaitWindowEvent()
  
Until Event = #PB_EventCloseWindow

End

Publié : dim. 09/mai/2004 16:36
par Flype
merci regis, je vais en faire bon usage de ce pas :wink:

Publié : dim. 09/mai/2004 17:51
par Flype
voilà c cado
bon vaut mieux avoir un processeur puissant
parcequ'avec l'algo de regis, vaux mieux :D
Essayer aussi en dé-commentant la 2ème ligne du source 8)

Code : Tout sélectionner

;------------------------------------------------------------------

#nTile=10 : #add=0.1
; #nTile=100 : #add=0.01

UsePNGImageEncoder()

;------------------------------------------------------------------

Procedure Engrenage(ImageID.l, x.l, y.l, Rayon.l, RayonAlesage.l, NbDents.l, HauteurDent.l, Decalage.f, Couleur.l) 
  
  ; Numero de l'image 
  ; x, y : position duentre de l'engrenage 
  ; Rayon : rayon de l'engrenage 
  ; RayonAlesage : rayon du trou au centre de l'engrenage 
  ; NbDents : nombre de dents 
  ; HauteurDent : Hauteur des dents 
  ; Decalage : norbre de dents de décalage par rapport à l'origine, utilise pour faire tourner l'engrenage 
  ; Couleur : couleur de l'engrenage 

  #Agrandissement = 10 
  UseImage(ImageID) 
  TailleX = ImageWidth() 
  TailleY = ImageHeight() 
  ResizeImage(ImageID, #Agrandissement * TailleX, #Agrandissement * TailleY) 
  x = x * #Agrandissement 
  y = y * #Agrandissement 
  Rayon = Rayon * #Agrandissement 
  RayonAlesage = RayonAlesage * #Agrandissement 
  HauteurDent = HauteurDent * #Agrandissement 
  UseImage(ImageID) 
  StartDrawing(ImageOutput()) 
    DrawingMode(4) 
    Circle(x, y, Rayon - HauteurDent, Couleur)
    Circle(x, y, RayonAlesage, Couleur)
    DrawingMode(0) 
    FillArea(x, y + RayonAlesage + 2, Couleur, Couleur)
  StopDrawing() 
  LargeurDent = Int(Rayon * 3 / 5 * Sin(#Pi / NbDents) + 0.5)
  For n = 1 To NbDents
    Cos.f = Cos((n + Decalage) * 2 * #Pi / NbDents)
    Sin.f = Sin((n + Decalage) * 2 * #Pi / NbDents)
    PosX1.f = x + Rayon * Cos + LargeurDent / 2 * Sin 
    PosY1.f = y + Rayon * Sin - LargeurDent / 2 * Cos 
    PosX2.f = x + Rayon * Cos - LargeurDent / 2 * Sin 
    PosY2.f = y + Rayon * Sin + LargeurDent / 2 * Cos 
    PosX3.f = x + (Rayon - HauteurDent) * Cos + LargeurDent * Sin 
    PosY3.f = y + (Rayon - HauteurDent) * Sin - LargeurDent * Cos 
    PosX4.f = x + (Rayon - HauteurDent) * Cos - LargeurDent * Sin 
    PosY4.f = y + (Rayon - HauteurDent) * Sin + LargeurDent * Cos 
    PosX5.f = x + (RayonAlesage + 5) * Cos 
    PosY5.f = y + (RayonAlesage + 5) * Sin 
    StartDrawing(ImageOutput()) 
      LineXY(PosX1, PosY1, PosX2, PosY2, Couleur) 
      LineXY(PosX1, PosY1, PosX3, PosY3, Couleur) 
      LineXY(PosX2, PosY2, PosX4, PosY4, Couleur) 
      LineXY(PosX3, PosY3, PosX5, PosY5, Couleur) 
      LineXY(PosX4, PosY4, PosX5, PosY5, Couleur) 
      FillArea(Int(x + (Rayon - HauteurDent / 2) * Cos + 0.5), Int(y + (Rayon - HauteurDent / 2) * Sin + 0.5), Couleur, Couleur) 
    StopDrawing()
  Next 
  ResizeImage(ImageID, TailleX, TailleY) 
EndProcedure 

;------------------------------------------------------------------

Procedure RefreshTile()
  Static n
  SetGadgetState(0,UseImage(n))
  SetGadgetState(1,n)
  n + 1
  If n > #nTile-1
    n = 0
  EndIf
EndProcedure

;------------------------------------------------------------------

Procedure DrawTiles()

  rotation.f = 0.00
  TextX = 90
  TextY = 208
  
  For n=0 To #nTile-1
    
    CreateImage(n, 250, 230) 
    
    StartDrawing(ImageOutput()) 
      Box(0, 0, 250, 230, RGB(64,64,255) )
      For i=0 To 63
        Circle(80, 80, 70-i, RGB(0, 0, 128+(i*2))) 
      Next
      DrawingMode(3)
      Locate(TextX+Random(3),TextY+Random(3))
      FrontColor(220,220,64)
      DrawText("Purebasic")
    StopDrawing() 

    Engrenage(n, 130, 120, 100, 40, 16, 20, rotation, RGB(0,0,0))

    StartDrawing(ImageOutput()) 
      DrawingMode(3)
      Locate(TextX+72+Random(3),TextY-5+Random(3))
      FrontColor(255,255,64)
      DrawText("Rulez !")
    StopDrawing() 
        
    rotation + #add
    
    SaveImage(n,"Engrenage"+Str(n)+".png",#PB_ImagePlugin_PNG)
    
    SetGadgetState(0,UseImage(n))
    SetGadgetState(1,n)
    
  Next
  
  SetTimer_(WindowID(),1,50,@RefreshTile())
  
EndProcedure

;------------------------------------------------------------------

OpenWindow(0, 0, 0, 265, 270, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Test")
CreateGadgetList(WindowID())
ImageGadget(0,5,5,254,235,#Null,#PB_Image_Border)
ProgressBarGadget(1,5,245,254,20,0,#nTile-1,#PB_ProgressBar_Smooth)
CreateThread(@DrawTiles(),#Null)
Repeat : Until WaitWindowEvent() = #PB_EventCloseWindow 
KillTimer_(WindowID(),1)

;------------------------------------------------------------------

End

Publié : dim. 09/mai/2004 19:33
par Le Soldat Inconnu
je l'ai en 3D, mon engrenage :D c'est super beau et la je suis content de moi :wink: (en toute modestie)

faut encore que je fignole, je le poste demain :wink:

attends un peu avant de faire des trucs, Flype car je pense que ça t'intéresse 8)

Publié : dim. 09/mai/2004 20:07
par Flype
raaaa, je brule d'impatience...

Publié : lun. 10/mai/2004 9:27
par Fred
Sympa les engrenages :)

Publié : lun. 10/mai/2004 13:56
par Le Soldat Inconnu
et voila :wink:


4 engrenages 3D qui s'engrainent :D avec animation

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 3.90
;
; Explication du programme :
; Dessiner un engrenage en 3D avec une animation

#Pi.f = 3.14159265

Procedure Engrenage(x.f, y.f, Rayon.l, RayonAlesage.l, NbDents.l, HauteurDent.l, Decalage.f, Inclinaison.f, Epaisseur.l, Couleur.l)
  Protected x2.f, y2.f, nn.l, LargeurDent.l, n.l, Facteur.f, Cos.f, Sin.f, Cos2.f, Sin2.f, PosX.f, PosY.f, PosX1, PosY1, PosX2, PosY2, PosX3, PosY3, PosX4, PosY4, PosX5, PosY5
  ; x, y : position duentre de l'engrenage
  ; Rayon : rayon de l'engrenage
  ; RayonAlesage : rayon du trou au centre de l'engrenage
  ; NbDents : nombre de dents
  ; HauteurDent : Hauteur des dents
  ; Decalage : nombre de dents de décalage par rapport à l'origine, utilise pour faire tourner l'engrenage
  ; Inclinaison : L'inclinaison de l'engrenage pour l'effet 3D
  ; Epaisseur : l'épaisseur de l'engrenage
  ; Couleur : couleur de l'engrenage
  
  StartDrawing(ImageOutput())
    
    x2.f= x
    y2.f = y
    x = x + (Inclinaison * Cos(#Pi / 4)) * Rayon
    y = y + (Inclinaison * Cos(#Pi / 4)) * Rayon
    
    For nn = 0 To Epaisseur
      
      Couleur = RGB(Red(Couleur) * 0.98, Green(Couleur) * 0.98, Blue(Couleur) * 0.98)
      If nn = Epaisseur
        Couleur = RGB(Red(Couleur) * 0.9, Green(Couleur) * 0.9, Blue(Couleur) * 0.9)
      EndIf
      
      LargeurDent = Int(Rayon * 3 / 5 * Sin(#Pi / NbDents) + 0.5) ; on détermine la largeur d'une dents
      
      For n = 1 To NbDents + 1 ; on passe en revue toutes les dents
        
        Facteur.f = (1 - Inclinaison * Cos((n + Decalage) * 2 * #Pi / NbDents - #Pi / 4))
        
        Cos.f = Cos((n + Decalage) * 2 * #Pi / NbDents) ; Calcul du cos de l'angle
        Sin.f = Sin((n + Decalage) * 2 * #Pi / NbDents) ; Calcul du sin de l'angle
        
        PosX.f = x + Facteur * Rayon * Cos
        PosY.f = y + Facteur * Rayon * Sin
        
        Longueur.f = Sqr(Pow(PosX - x2, 2) + Pow(PosY - y2, 2))
        
        Cos2.f = (PosX - x2) / Longueur ; Calcul du cos de l'angle
        Sin2.f = (PosY - y2) / Longueur ; Calcul du sin de l'angle
              
        ; Point haut gauche de la dent
        PosX1 = Int(PosX + Facteur * LargeurDent / 2 * Sin2 + 0.5)
        PosY1 = Int(PosY - Facteur * LargeurDent / 2 * Cos2 + 0.5)
        ; Point haut droit de la dent
        PosX2 = Int(PosX - Facteur * LargeurDent / 2 * Sin2 + 0.5)
        PosY2 = Int(PosY + Facteur * LargeurDent / 2 * Cos2 + 0.5)
        ; Point bas gauche de la dent
        PosX3 = Int(PosX + Facteur * (-HauteurDent * Cos2 + LargeurDent * Sin2) + 0.5)
        PosY3 = Int(PosY + Facteur * (-HauteurDent * Sin2 - LargeurDent * Cos2) + 0.5)
        ; Point bas droit de la dent
        PosX4 = Int(PosX + Facteur * (-HauteurDent * Cos2 - LargeurDent * Sin2) + 0.5)
        PosY4 = Int(PosY + Facteur * (-HauteurDent * Sin2 + LargeurDent * Cos2) + 0.5)
        
        ; Dessin du contour de la dent
        LineXY(PosX1, PosY1, PosX2, PosY2, Couleur)
        LineXY(PosX1, PosY1, PosX3, PosY3, Couleur)
        LineXY(PosX4, PosY4, PosX2, PosY2, Couleur)
        
        If n > 1
          LineXY(PosX3, PosY3, PosX5, PosY5, Couleur)
        EndIf
        
        PosX5 = PosX4
        PosY5 = PosY4
  
      Next
      
      ; Remplissage de l'engrenage
      FillArea(x, y, Couleur, Couleur)
      
      x + 1
      y + 1
      x2 + 1
      y2 + 1
      
      ; Circle(x, y, RayonAlesage, RGB(255, 255, 255))
      ; Circle(x2, y2, RayonAlesage/2, RGB(255, 0, 0))
    Next
  StopDrawing()
EndProcedure



;- Exemple

; Création de la fenêtre et dela GadgetList
If OpenWindow(0, 0, 0, 600, 600, #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget, "Test") = 0 Or CreateGadgetList(WindowID()) = 0
  End
EndIf

; On crée les 20 images de l'animation
For n = 0 To 19

  ; Création de l'image
  CreateImage(n, 600, 600)
  StartDrawing(ImageOutput())
    Box(0, 0, 600, 600, RGB(255, 255, 255))
  StopDrawing()
  
  ; On dessine les engrenages
  ; Il est important de garder le même nombre de dents entre 2 engrenages qui s'engrainent, sinon les engrenages n'iront pas à la même vitesse
  Engrenage(420, 420, 136, 40, 15, 24, (16 - n) / 20, 0.2, 30, RGB(170, 170, 170))
  Engrenage(200, 200, 190, 70, 15, 40, n / 20, 0.2, 30, RGB(170, 170, 170))
  Engrenage(450, 450, 88, 40, 13, 22, (17 - n) / 20, 0.2,20, RGB(170, 170, 170)) ; on décale de l'épaisseur du premier engrenage cet engrenage afin de le positionner par dessus l'autre
  Engrenage(450, 250, 120, 30, 13, 28, (n - 7) / 20, 0.2,20, RGB(170, 170, 170))
   
;   Engrenage(210, 210, 68, 20, 15, 12, (17 - n) / 20, 0.2, 15, RGB(170, 170, 170))
;   Engrenage(100, 100, 95, 35, 15, 20, n / 20, 0.2, 15, RGB(170, 170, 170))
;   Engrenage(225, 225, 44, 20, 13, 11, (17 - n) / 20, 0.2,10, RGB(170, 170, 170)) ; on décale de l'épaisseur du premier engrenage cet engrenage afin de le positionner par dessus l'autre
;   Engrenage(225, 125, 60, 30, 13, 14, (n - 6) / 20, 0.2,10, RGB(170, 170, 170))
   
  ; On affiche l'image
  StartDrawing(WindowOutput())
    DrawImage(UseImage(n), 0, 0)
  StopDrawing()
  
Next

StartDrawing(WindowOutput())

  ; On lance un Timer toutes les 20 ms
  SetTimer_(WindowID(), 0, 20, 0)
  n = 0
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #WM_TIMER ; Si on a le Timer
      ; On passe à l'image suivante
      n + 1
      If n = 20 : n = 0 : EndIf
      ; On dessine les engrenages dans la nouvelle position
      DrawImage(UseImage(n), 0, 0)
    EndIf
    
  Until Event = #PB_EventCloseWindow
  
  ; On tue le Timer
  KillTimer_(WindowID(), Timer)

StopDrawing()
un petit screen :D
Image

Publié : lun. 10/mai/2004 19:24
par Flype
bravo regis c super ! 8)

c de la fausse 3D, non ? juste une question d'epaisseur, ca rend bien en tout cas

Publié : mar. 11/mai/2004 7:58
par Le Soldat Inconnu
non pas que de l'épaisseur, regarde, l'engrenage n'est pas rond ;)
si tu prends les dents entre le coté haut gauche et le coté bas droit, les dents n'ont pas la même taille non plus pour donner un effet de perpective :D

mais ça reste de la fausse 3D, tous n'en qu'empirique :wink:

Publié : mar. 11/mai/2004 9:07
par Dr. Dri
...

Publié : mar. 11/mai/2004 14:21
par Flype
c plus sympa quand çà tourne ;-)

Publié : mar. 11/mai/2004 14:26
par Flype
c'est le FillArea() qui est si lent où tout le reste ?
je parle pour tous les algos publiés ici...
parceque celui en fil de fer de ced est vachement fluide...

enfin moi, j'ai compris qu'il vaut mieux faire du précalcul et ensuite afficher tout çà ( pour un truc qui tourne fluide ) :roll:

et Polyline() on peut pas l'appliquer avec les engrenages ?

Je critique pas, je suis en admiration devant vos oeuvres, je demande juste si on peut pas faire tout çà en tps réel mais je rêve debout :roll:

:wink:

Publié : dim. 01/juil./2007 15:10
par Flype
j'ai mis à jour l'algo d'engrenage du soldat inconnu pour PB4.10.

le tout sur une fenêtre en transparence pour le fun (Win2000/XP/+)

Code : Tout sélectionner

;-
;- Description : Dessiner un engrenage en 3D avec une animation
;- Auteur      : Le Soldat Inconnu, Flype.
;- Version     : PureBasic 4.x
;- 

EnableExplicit

;- 
;- Procédure de tracé
;- 

Enumeration 0 ; #ULW_ for use with UpdateLayeredWindow()
  #ULW_OPAQUE
  #ULW_COLORKEY
  #ULW_ALPHA
EndEnumeration

Procedure.l DrawGear(x.f, y.f, Rayon.l, RayonAlesage.l, NbDents.l, HauteurDent.l, Decalage.f, Inclinaison.f, Epaisseur.l, Couleur.l, FillArea.l = #True)
  
  Protected PosX.f, PosY.f, PosX1, PosY1, PosX2, PosY2, PosX3, PosY3, PosX4, PosY4, PosX5, PosY5
  Protected x2.f, y2.f, nn.l, LargeurDent.l, Longueur.f, n.l, Facteur.f, Cos.f, Cos2.f, Sin.f, Sin2.f 
  
  ; x, y         : Position de l'engrenage
  ; Rayon        : Rayon de l'engrenage
  ; RayonAlesage : Rayon du trou au centre de l'engrenage
  ; NbDents      : Nombre de dents
  ; HauteurDent  : Hauteur des dents
  ; Decalage     : Nombre de dents de décalage par rapport à l'origine, utilisé pour faire tourner l'engrenage
  ; Inclinaison  : L'inclinaison de l'engrenage pour l'effet 3D
  ; Epaisseur    : L'épaisseur de l'engrenage
  ; Couleur      : Couleur de l'engrenage
  
  x2 = x
  y2 = y
  x  = x + ( Inclinaison * Cos(#PI / 4) ) * Rayon
  y  = y + ( Inclinaison * Cos(#PI / 4) ) * Rayon
  
  For nn = 0 To Epaisseur
    
    Couleur = RGB(Red(Couleur) * 0.98, Green(Couleur) * 0.98, Blue(Couleur) * 0.98)
    
    If nn = Epaisseur
      Couleur = RGB(Red(Couleur) * 0.9, Green(Couleur) * 0.9, Blue(Couleur) * 0.9)
    EndIf
    
    LargeurDent = Int(Rayon * 3 / 5 * Sin(#PI / NbDents) + 0.5) 
    
    For n = 1 To NbDents + 1 
      
      Facteur = (1 - Inclinaison * Cos((n + Decalage) * 2 * #PI / NbDents - #PI / 4))
      
      Sin = Sin((n + Decalage) * 2 * #PI / NbDents) 
      Cos = Cos((n + Decalage) * 2 * #PI / NbDents) 
      
      PosX = x + Facteur * Rayon * Cos
      PosY = y + Facteur * Rayon * Sin
      
      Longueur = Sqr(Pow(PosX - x2, 2) + Pow(PosY - y2, 2))
      
      Sin2 = (PosY - y2) / Longueur 
      Cos2 = (PosX - x2) / Longueur 
      
      ; Point haut gauche de la dent
      PosX1 = Int(PosX + Facteur * LargeurDent / 2 * Sin2 + 0.5)
      PosY1 = Int(PosY - Facteur * LargeurDent / 2 * Cos2 + 0.5)
      
      ; Point haut droit de la dent
      PosX2 = Int(PosX - Facteur * LargeurDent / 2 * Sin2 + 0.5)
      PosY2 = Int(PosY + Facteur * LargeurDent / 2 * Cos2 + 0.5)
      
      ; Point bas gauche de la dent
      PosX3 = Int(PosX + Facteur * (-HauteurDent * Cos2 + LargeurDent * Sin2) + 0.5)
      PosY3 = Int(PosY + Facteur * (-HauteurDent * Sin2 - LargeurDent * Cos2) + 0.5)
      
      ; Point bas droit de la dent
      PosX4 = Int(PosX + Facteur * (-HauteurDent * Cos2 - LargeurDent * Sin2) + 0.5)
      PosY4 = Int(PosY + Facteur * (-HauteurDent * Sin2 + LargeurDent * Cos2) + 0.5)
      
      ; Dessin du contour de la dent
      LineXY(PosX1, PosY1, PosX2, PosY2, Couleur)
      LineXY(PosX1, PosY1, PosX3, PosY3, Couleur)
      LineXY(PosX4, PosY4, PosX2, PosY2, Couleur)
      
      If n > 1
        LineXY(PosX3, PosY3, PosX5, PosY5, Couleur)
      EndIf
      
      PosX5 = PosX4
      PosY5 = PosY4
      
    Next
    
    If FillArea
      FillArea(x, y, Couleur, Couleur)
    EndIf
    
    x + 1
    y + 1
    x2 + 1
    y2 + 1
    
  Next
  
EndProcedure

Procedure.l SetWindowLayeredBitmap(WindowID.l, ImageID.l, ColorKey.l = #White, AlphaValue.l = 255)
  
  Protected hdc.l, hBmp.BITMAP, pt.POINT, blend.BLENDFUNCTION
  
  SetWindowLong_(WindowID(WindowID), #GWL_EXSTYLE, GetWindowLong_(WindowID(WindowID), #GWL_EXSTYLE) | #WS_EX_LAYERED)
  
  If GetObject_(ImageID(ImageID), SizeOf(BITMAP), @hBmp)
    
    hdc = StartDrawing(ImageOutput(ImageID))
    
    If hdc
      
      blend\BlendOp             = 0
      blend\BlendFlags          = 0
      blend\AlphaFormat         = 0
      blend\SourceConstantAlpha = AlphaValue
      
      UpdateLayeredWindow_(WindowID(WindowID), 0, 0, @hBmp\bmWidth, hdc, @pt, ColorKey, @blend, #ULW_COLORKEY|#ULW_ALPHA)
      
      StopDrawing()
      
    EndIf
    
  EndIf
  
  
EndProcedure

;- 
;- Programme de test
;- 

Define i.l, j.l, w.l = 380, h.l = 380

If OpenWindow(0, 0, 0, w, h, "DrawGear()", #PB_Window_BorderLess | #PB_Window_ScreenCentered | #PB_Window_Invisible ) 
  
  StickyWindow(0, #True)
  
  LoadFont(0, "Tahoma", 8, #PB_Font_HighQuality)
  
  For i = 0 To 19
    
    If CreateImage(i, w, h)
      
      If StartDrawing(ImageOutput(i))
        
        DrawingFont(FontID(0))
        Box(0, 0, w, h, #White)
        
        DrawingMode(#PB_2DDrawing_Default)
        DrawGear(340, 320,  20,  5, 10,  5, ( (17 - i) / 20), 0.2, 16, $22FFFF) 
        DrawGear(272, 240, 100, 20, 40,  5, ( ( i - 7) / 20), 0.2,  6, $8AFF8A)
        
        DrawingMode(#PB_2DDrawing_Default)
        DrawGear( 80, 200,  38,  7,  8, 10, ( (17 - i) / 20), 0.2, 25, $4444FF) 
        DrawGear( 50,  50,  20,  5,  6,  5,        ( i / 20), 0.2, 99, $666666)
        DrawGear(245,  95,  75, 20, 10, 10, ( (16 - i) / 20), 0.2, 25, $FF4444)
        DrawGear(125, 125,  50, 20,  8, 10,        ( i / 20), 0.2, 25, $DDDDDD)
        DrawGear(150, 150,  20,  5,  6,  5,        ( i / 20), 0.2, 99, $FFFFFF)
        
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(10, 10, w-20, h-20, (#Black|$F0F0F0))
        Box(12, 12, w-24, h-24, (#Black|$000000))
        
        DrawingMode(#PB_2DDrawing_Default)
        DrawGear(1, 340, 100, 20, 30, 10, (i / 20), 0.01, 8, $FFEEEE)
        
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawText(  20, 335, "PureBasic 4.10, Gear Demo", #Black)
        DrawText(  20, 350, "Copyright © 2007 Fantaisie Software", #Black)
        DrawText(w-80, 350, "RMB to Exit.", $DDDDDD)
        
        StopDrawing()
        
      EndIf
      
    EndIf
    
  Next
  
  SetTimer_(WindowID(0), 0, 5, 0)
  
  HideWindow(0, #False)
  
  i = 0
  
  Repeat
    
    Select WaitWindowEvent()
      
      Case #WM_CLOSE, #WM_KEYDOWN, #WM_RBUTTONDOWN
        Break
        
      Case #WM_LBUTTONDOWN
        SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
        
      Case #WM_TIMER 
        SetWindowLayeredBitmap(0, i, #White, 240)
        i + 1 : If i > 19 : i = 0 : EndIf
        
    EndSelect
    
  ForEver
  
  KillTimer_(WindowID(0), 0)
  
EndIf

;-
;-
;-

End