Page 1 sur 1

Dessiner un camembert en 3D

Publié : mer. 28/avr./2004 13:39
par Le Soldat Inconnu
Salut,

j'ai fait un code qui permet de dessiner un camembert en 3D

j'ai utilisé la fonction de l'API Pie_() qui permet de dessiner un camembert en 2D et j'ai bidouillé pour donner un effet de 3D

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 3.90
; 
; Explication du programme :
; Dessiner un camembert en 3D

Procedure Pie3D(HDC.l, X.l, Y.l, Rayon.l, Orientation.f, Hauteur.l, AngleDepart.f, AngleFin.f, Couleur.l)
 ; HDC : Handle du dessin
  ; X, Y : centre du camembert
  ; Rayon : Rayon du camembert
  ; Orientation : Orientation du camembert qui donne l'effet 3D. cette valeur doit être comprise entre 0 et 1
  ; Hauteur : Hauteur ou épaisseur du camembert
  ; AngleDepart : Angle de départ en radian
  ; AngleFin : Angle de fin en radian
  ; Couleur : Couleur du camenbert
  
  Protected R.l, G.l, B.l, n.l, AX1.l, AY1.l, AX2.l, AY2.l, Rayon2.l
  
  Rayon2 = Rayon * Orientation ; calul du rayon sur l'axe Y du camembert
  
  Y = Y - Hauteur / 2 ; on recentre le camemenbert en fonction de l'épaisseur
  
  R = Red(Couleur) : G = Green(Couleur) : B = Blue(Couleur) ; On décompose la couleur en RGB
  
  AX2 = Int(X + 100 * Cos(AngleDepart)) ; calcul du point d'arriver
  AY2 = Int(Y + 100 * Sin(AngleDepart) * Orientation)
  
  AX1 = Int(X + 100 * Cos(AngleFin)) ; calcul du point de départ
  AY1 = Int(Y + 100 * Sin(AngleFin) * Orientation)

  For n = Hauteur To 1 Step -1 ; On dessine l'épaisseur du camembert
    FrontColor(R * (0.8 - 0.08 * n / Hauteur), G * (0.8 - 0.08 * n / Hauteur), B * (0.8 - 0.08 * n / Hauteur)) ; Choix de la couleur du bord du camembert
    Pie_(HDC, X - Rayon, Y - Rayon2 + n, X + Rayon, Y + Rayon2 + n, AX1, AY1 + n, AX2, AY2 + n)
  Next
    
  FrontColor(R, G, B)
  Pie_(HDC, X - Rayon, Y - Rayon2, X + Rayon, Y + Rayon2, AX1, AY1, AX2, AY2) ; on dessine le dessus du camembert
  
EndProcedure



; 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

HDC = StartDrawing(WindowOutput())
  
  Pie3D(HDC, 150, 150, 120, 0.45, 20, 3 * #Pi / 4, 0 , RGB(100, 200, 100))
  
StopDrawing()

Repeat
  Event = WaitWindowEvent()
  
Until Event = #PB_EventCloseWindow

End

Publié : mer. 28/avr./2004 15:06
par Flype
wahouuu
c pas mal du tout regis

j'ai bidouillé pour avoir pls part de camenbert mais c pas si simple pour
que les parts ne se chevauchent pas... il faut respecter un ordre précis.

tu me diras sans doute que c évident :D

Publié : mer. 28/avr./2004 15:06
par Flype
Pie_() est dans windows depuis quelle version ?

Publié : mer. 28/avr./2004 15:44
par Le Soldat Inconnu
oui, pour faire 2 parts, on a 4 cas de figure. voici un exemple :

Code : Tout sélectionner

        If AngleF = 0
          Pie3D(HDC, #Cx, #Cy, 70, 0.55, 7, 0, 2 * #Pi, RGB(177, 177, 255))
        ElseIf AngleF <= #Pi / 2
          Pie3D(HDC, #Cx, #Cy, 70, 0.55, 7, #Pi + AngleF, 0, RGB(177, 177, 255))
          Pie3D(HDC, #Cx, #Cy, 70, 0.55, 7, #Pi, #Pi + AngleF, RGB(94, 164, 235))
          Pie3D(HDC, #Cx, #Cy, 70, 0.55, 7, 0, #Pi, RGB(177, 177, 255))
        ElseIf AngleF <= 3 * #Pi / 2
          Pie3D(HDC, #Cx, #Cy, 70, 0.55, 7, #Pi, #Pi + AngleF, RGB(94, 164, 235))
          Pie3D(HDC, #Cx, #Cy, 70, 0.55, 7, #Pi + AngleF, #Pi, RGB(177, 177, 255))
        Else
          Pie3D(HDC, #Cx, #Cy, 70, 0.55, 7, #Pi, 0, RGB(94, 164, 235))
          Pie3D(HDC, #Cx, #Cy, 70, 0.55, 7, #Pi + AngleF, #Pi, RGB(177, 177, 255))
          Pie3D(HDC, #Cx, #Cy, 70, 0.55, 7, 0, #Pi + AngleF, RGB(94, 164, 235))
        EndIf
AngleF est un float qui réprésente la taille du premier camembert en radian.

sinon, pour Pie_(), voila ce que dis ma doc :
Requires Windows NT 3.1 or later; Requires Windows 95 or later

Publié : dim. 30/janv./2005 15:30
par Le Soldat Inconnu
bon, j'ai fais un exemple de différents camemberts à partir de code de mes programmes

c'est amusant, j'ai est profité pour améliorer et mettre ça en animation

Code : Tout sélectionner

; Auteur : Le Soldat Inconnu
; Version de PB : 3.92
;
; Explication du programme :
; Dessiner un camembert en 3D

#Pi.f = 3.14159265

Procedure Pie3D(HDC.l, x.l, y.l, Rayon.l, Orientation.f, Hauteur.l, AngleDepart.f, AngleFin.f, Couleur.l)
  ; HDC : Handle du dessin
  ; X, Y : centre du camembert
  ; Rayon : Rayon du camembert
  ; Orientation : Orientation du camembert qui donne l'effet 3D. cette valeur doit être comprise entre 0 et 1
  ; Hauteur : Hauteur ou épaisseur du camembert
  ; AngleDepart : Angle de départ en radian
  ; AngleFin : Angle de fin en radian
  ; Couleur : Couleur du camenbert
  
  Protected R.l, G.l, b.l, n.l, AX1.l, AY1.l, AX2.l, AY2.l, Rayon2.l
  
  Rayon2 = Rayon * Orientation ; calul du rayon sur l'axe Y du camembert
  
  y = y - Hauteur / 2 ; on recentre le camemenbert en fonction de l'épaisseur
  
  R = Red(Couleur) : G = Green(Couleur) : b = Blue(Couleur) ; On décompose la couleur en RGB
  
  AX2 = Int(x + 100 * Cos(AngleDepart)) ; calcul du point d'arriver
  AY2 = Int(y + 100 * Sin(AngleDepart) * Orientation)
  
  AX1 = Int(x + 100 * Cos(AngleFin)) ; calcul du point de départ
  AY1 = Int(y + 100 * Sin(AngleFin) * Orientation)
  
  For n = Hauteur To 1 Step -1 ; On dessine l'épaisseur du camembert
    FrontColor(R * (0.8 - 0.08 * n / Hauteur), G * (0.8 - 0.08 * n / Hauteur), b * (0.8 - 0.08 * n / Hauteur)) ; Choix de la couleur du bord du camembert
    Pie_(HDC, x - Rayon, y - Rayon2 + n, x + Rayon, y + Rayon2 + n, AX1, AY1 + n, AX2, AY2 + n)
  Next
  
  ; On dessine le dessus du camembert
  FrontColor(R, G, b)
  Pie_(HDC, x - Rayon, y - Rayon2, x + Rayon, y + Rayon2, AX1, AY1, AX2, AY2) ; on dessine le dessus du camembert
  
EndProcedure

Procedure DoublePie3D(HDC.l, x.l, y.l, Rayon.l, Orientation.f, Hauteur.l, Decalage.l, Angle.f, Couleur1.l, Couleur2.l)
  ; HDC : Handle du dessin
  ; X, Y : centre du camembert
  ; Rayon : Rayon du camembert
  ; Orientation : Orientation du camembert qui donne l'effet 3D. cette valeur doit être comprise entre 0 et 1
  ; Hauteur : Hauteur ou épaisseur du camembert
  ; Decalage : Pour mettre un espace entre les 2 zone du camenbert
  ; Angle : Angle correspondant à la zone 1 du camembert
  ; Couleur1 : Couleur de la zone 1 du camenbert
  ; Couleur2 : Couleur de la zone 2 du camenbert
  
  DecalageX = Int(Decalage * Cos(Angle / 2))
  DecalageY = Int(Decalage * Sin(Angle / 2) * Orientation)
  
  If Angle = 0
    Pie3D(HDC, x, y, Rayon, Orientation, Hauteur, 0, 2 * #Pi, Couleur1)
  ElseIf Angle <= #Pi / 2
    Pie3D(HDC, x + DecalageX, y + DecalageY, Rayon, Orientation, Hauteur, #Pi + Angle, 0, Couleur1)
    Pie3D(HDC, x - DecalageX, y - DecalageY, Rayon, Orientation, Hauteur, #Pi, #Pi + Angle, Couleur2)
    Pie3D(HDC, x + DecalageX, y + DecalageY, Rayon, Orientation, Hauteur, 0, #Pi, Couleur1)
  ElseIf Angle <= 3 * #Pi / 2
    Pie3D(HDC, x - DecalageX, y - DecalageY, Rayon, Orientation, Hauteur, #Pi, #Pi + Angle, Couleur2)
    Pie3D(HDC, x + DecalageX, y + DecalageY, Rayon, Orientation, Hauteur, #Pi + Angle, #Pi, Couleur1)
  Else
    Pie3D(HDC, x - DecalageX, y - DecalageY, Rayon, Orientation, Hauteur, #Pi, 0, Couleur2)
    Pie3D(HDC, x + DecalageX, y + DecalageY, Rayon, Orientation, Hauteur, #Pi + Angle, #Pi, Couleur1)
    Pie3D(HDC, x - DecalageX, y - DecalageY, Rayon, Orientation, Hauteur, 0, #Pi + Angle, Couleur2)
  EndIf
EndProcedure



; 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

CreateImage(0, 600, 600)
ImageGadget(0, 0, 0, 0, 0, UseImage(0))

SetTimer_(WindowID(), 0, 50, 0)

Repeat
  Event = WaitWindowEvent()
  
  If Event = #WM_TIMER
    
    Angle.f + 0.02
    If Angle > 2 * #Pi
      Angle = 0
    EndIf
    
    HDC = StartDrawing(ImageOutput())
      Box(0, 0, 600, 600, 0)
      
      ; Camenbert normal (1 seule part)
      Pie3D(HDC, 150, 150, 120, 0.45, 20, Angle, 0, RGB(100, 200, 200))
      
      ; Camenbert normal (1 seule part)
      Pie3D(HDC, 150, 450, 120, 0.8, 20, #Pi, #Pi + Angle, RGB(100, 200, 200))
      
      ; Camenbert avec 2 parts
      DoublePie3D(HDC, 450, 150, 140, 0.6, 10, 0, Angle, RGB(100, 200, 200), RGB(0, 150, 150))
      
      ; Camenbert avec 2 parts et avec un espace entre les parts
      DoublePie3D(HDC, 450, 450, 100, 0.5, 15, 5, Angle, RGB(100, 200, 200), RGB(0, 150, 150))
      
      
    StopDrawing()
    SetGadgetState(0, UseImage(0))
    
  EndIf
  
Until Event = #PB_EventCloseWindow

KillTimer_(WindowID(), 0)

End

Publié : mar. 01/févr./2005 15:48
par KarLKoX
Vraiement sympas et tres pratique comme astuce, bravo !