Re: Des cercles a dessiner sans "circle"
Publié : mer. 24/avr./2019 7:39
Bravo Ar-s c'est très réussi, j'adore et je te remercie pour le partage.
Forums PureBasic - Français
http://forums.purebasic.com/french/
Code : Tout sélectionner
;https://fr.wikipedia.org/wiki/Algorithme_de_trac%C3%A9_de_cercle_d%27Andres
;https://fr.wikipedia.org/wiki/Algorithme_de_trac%C3%A9_d%27arc_de_cercle_de_Bresenham
Structure XY
X.i
Y.i
EndStructure
Global NewList Cercle_Bresenham.XY()
Global NewList Cercle_Andres.XY()
;algorithme de tracé de cercle de Bresenham
Procedure TracerCercleBresenham(rayon,x_centre,y_centre)
y=rayon ; // on se place en haut du cercle
m=5-4*rayon ; // initialisation
While x <= y; // tant qu'on est dans le second octant
AddElement(cercle_bresenham())
cercle_bresenham()\x=x+x_centre:cercle_bresenham()\y=y+y_centre
AddElement(cercle_bresenham())
cercle_bresenham()\x=y+x_centre:cercle_bresenham()\y=x+y_centre
AddElement(cercle_bresenham())
cercle_bresenham()\x=-x+x_centre:cercle_bresenham()\y=y+y_centre
AddElement(cercle_bresenham())
cercle_bresenham()\x=-y+x_centre:cercle_bresenham()\y=x+y_centre
AddElement(cercle_bresenham())
cercle_bresenham()\x=x+x_centre:cercle_bresenham()\y=-y+y_centre
AddElement(cercle_bresenham())
cercle_bresenham()\x=y+x_centre:cercle_bresenham()\y=-x+y_centre
AddElement(cercle_bresenham())
cercle_bresenham()\x=-x+x_centre:cercle_bresenham()\y=-y+y_centre
AddElement(cercle_bresenham())
cercle_bresenham()\x=-y+x_centre:cercle_bresenham()\y=-x+y_centre
If m > 0 ;choix du point F
y - 1
m=m-8*y
EndIf
x+1 ;
m=m + 8*x+4 ;
Wend
EndProcedure
;algorithme de tracé de cercle d'Andres
Procedure TracerCercleAndres(rayon,x_centre,y_centre)
;x=0
y=rayon
d=rayon - 1
While y>=x
AddElement(cercle_Andres())
Cercle_Andres()\x=x+x_centre:Cercle_Andres()\y=y+y_centre
AddElement(Cercle_Andres())
Cercle_Andres()\x=y+x_centre:Cercle_Andres()\y=x+y_centre
AddElement(Cercle_Andres())
Cercle_Andres()\x=-x+x_centre:Cercle_Andres()\y=y+y_centre
AddElement(Cercle_Andres())
Cercle_Andres()\x=-y+x_centre:Cercle_Andres()\y=x+y_centre
AddElement(Cercle_Andres())
Cercle_Andres()\x=x+x_centre:Cercle_Andres()\y=-y+y_centre
AddElement(Cercle_Andres())
Cercle_Andres()\x=y+x_centre:Cercle_Andres()\y=-x+y_centre
AddElement(Cercle_Andres())
Cercle_Andres()\x=-x+x_centre:Cercle_Andres()\y=-y+y_centre
AddElement(Cercle_Andres())
Cercle_Andres()\x=-y+x_centre:Cercle_Andres()\y=-x+y_centre
If d >= 2*x
d=d-2*x-1
x+1
ElseIf d < 2*(rayon-y);d <= 2*(rayon-y)
d=d+2*y-1
y-1
Else
d=d+2*(y-x-1)
y-1
x+1
EndIf
Wend
EndProcedure
If InitSprite() = 0 Or InitKeyboard() = 0
MessageRequester("Error", "Sprite system can't be initialized", 0)
End
EndIf
OpenWindow(0, 0, 0, 1024, 768, "Un écran dans une fenêtre...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 1024, 768)
ClearScreen(RGB(0,0,0))
;calcul 50 cercles concentriques avec les 2 méthodes, en incrémentant le rayon
For i=50 To 100
TracerCercleAndres(i,100,160)
TracerCercleBresenham(i,360,160)
Next i
Repeat
; Il est très important de traiter tous les évènements restants dans la file d'attente à chaque tour
;
Repeat
Event = WindowEvent()
Select Event
Case #PB_Event_CloseWindow
End
EndSelect
Until Event = 0
FlipBuffers()
StartDrawing(ScreenOutput())
;trace les cercles calculés avec Bresenham (en vert)
ForEach cercle_bresenham()
Plot(cercle_bresenham()\x,cercle_bresenham()\y,RGB(0,255,0))
Next
;trace les cercles calculés avec Andres (en jaune)
ForEach cercle_Andres()
Plot(cercle_Andres()\x,cercle_Andres()\y,RGB(255,255,0))
Next
StopDrawing()
; Delay(1)
ExamineKeyboard()
Until KeyboardPushed(#PB_Key_Escape)
Code : Tout sélectionner
Procedure plt(x,y,c) ; pour être sur que l'on dessine dans l'écran courant
If x>=0 And y>=0 And x<=639 And y<=479
Plot(x,y,c)
EndIf
EndProcedure
Procedure rasterCircle(cx, cy, r, Color) ; SMartin https://www.purebasic.fr/english/viewtopic.php?f=13&t=36896
Protected f= 1 - r
Protected ddF_X, ddF_Y = -2 * r
Protected x, y = r
Plt(cx, cy + r, Color)
Plt(cx, cy - r, Color)
Plt(cx + r, cy, Color)
Plt(cx - r, cy, Color)
While x < y
If f >= 0
y - 1
ddF_Y + 2
f + ddF_Y
EndIf
x + 1
ddF_X + 2
f + ddF_X + 1
Plt(cx + x, cy + y, Color)
Plt(cx - x, cy + y, Color)
Plt(cx + x, cy - y, Color)
Plt(cx - x, cy - y, Color)
Plt(cx + y, cy + x, Color)
Plt(cx - y, cy + x, Color)
Plt(cx + y, cy - x, Color)
Plt(cx - y, cy - x, Color)
Wend
EndProcedure
InitSprite()
InitKeyboard()
OpenScreen(640,480,32,"")
Repeat
ExamineKeyboard()
StartDrawing(ScreenOutput())
rasterCircle(Random(640),Random(480),Random(80),RGB(Random(200)+55,Random(200)+55,Random(200)+55))
StopDrawing()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Code : Tout sélectionner
.-------- --
| | |
| | |
| b | d|
| | |
.-------- --
| c | a|
.-------- --
BalanceOllivier a écrit :Tu veux un code ?
Code : Tout sélectionner
;**********************************************************************************************************
; (j'ai beau en rajouter des '*' ça me coupe tjr les lignes de codes...
Procedure Disc(cx,cy,r,color)
f = 1 - r
ddF_Y = -2 * r
y = r
Repeat
If f > 0
Box(cx - x, cy + y, 2 * x, 1, color)
Box(cx - x, cy - y, 2 * x, 1, color)
Box(cx - y, cy + x, 2 * y, OldX - x, color)
Box(cx - y, cy - x, 2 * y, x - OldX, color)
y - 1
ddF_Y + 2
f + ddF_Y
oldX = x
EndIf
x + 1
ddF_X + 2
f + ddF_X + 1
Until x > y
EndProcedure
Ollivier a écrit :Qu'est-ce que tu entends par << cercle évidé >> ?
Parce que tu dis que tu veux refaire un jeu ancien assez connu. Seulement, moi je suis vide de cette culture. Donc, précise, mets un lien Youtube ou un titre.
Normalement, avec ce qu'il y a au-dessus, c'est suffisant et les calculs sont là, non optimisés, spécialement pour faire les modifs. N'hésite pas aussi à demander à Fred si c'est cet algo aussi : tu demandes ici ce qu'il a fait alors qu'il est présent sur le site anglais pour sa dernière beta... T'es pas toujours réveillé là !
Code : Tout sélectionner
DrawingMode(#PB_2DDrawing_Outlined)