Code : Tout sélectionner
;Comtois 21/01/07
;Reprise d'un code en C vite fait, faudra l'améliorer à l'occasion !
; http://fr.wikipedia.org/wiki/Courbe_de_B%C3%A9zier_en_C
InitSprite()
InitKeyboard()
InitMouse()
OpenScreen(800, 600, 32, "Bezier")
Structure Pointf
x.f
y.f
EndStructure
Structure Bezier
P.Pointf[4]
EndStructure
#PointControle = 4
;-Variables globales
Global Global_Bezier.Bezier
Global level, Proche, PointControle
Global_Bezier\P[0]\x = 10
Global_Bezier\P[0]\y = 510
Global_Bezier\P[1]\x = 260
Global_Bezier\P[1]\y = 20
Global_Bezier\P[2]\x = 380
Global_Bezier\P[2]\y = 300
Global_Bezier\P[3]\x = 748
Global_Bezier\P[3]\y = 400
level = 5
;-Dessine une ligne de couleur (r,v,b)
Procedure DrawLine( x1.l, y1.l, x2.l, y2.l, r.l, v.l, b.l)
If StartDrawing(ScreenOutput())
LineXY(x1,y1,x2,y2,RGB(r,v,b))
StopDrawing()
EndIf
EndProcedure
Procedure DrawBezierBase(*p.Bezier, r.l, v.l, b.l)
DrawLine(*p\P[0]\x,*p\P[0]\y,*p\P[1]\x,*p\P[1]\y,r,v,b)
DrawLine(*p\P[1]\x,*p\P[1]\y,*p\P[2]\x,*p\P[2]\y,r,v,b)
DrawLine(*p\P[2]\x,*p\P[2]\y,*p\P[3]\x,*p\P[3]\y,r,v,b)
EndProcedure
Procedure DrawBezierRecursive ( *b.Bezier, level.l)
Define.Bezier left, right
If level <= 0
;Dessine un segment
DrawLine(*b\P[0]\x + 0.5, *b\P[0]\y + 0.5, *b\P[3]\x + 0.5, *b\P[3]\y + 0.5, 255, 255, 255)
Else
;subdivide into 2 Bezier segments
left\P[0]\x = *b\P[0]\x
left\P[0]\y = *b\P[0]\y
left\P[1]\x = (*b\P[0]\x + *b\P[1]\x) / 2
left\P[1]\y = (*b\P[0]\y + *b\P[1]\y) / 2
left\P[2]\x = (*b\P[0]\x + 2**b\P[1]\x + *b\P[2]\x) / 4
left\P[2]\y = (*b\P[0]\y + 2**b\P[1]\y + *b\P[2]\y) / 4
left\P[3]\x = (*b\P[0]\x + 3**b\P[1]\x + 3**b\P[2]\x + *b\P[3]\x) / 8
left\P[3]\y = (*b\P[0]\y + 3**b\P[1]\y + 3**b\P[2]\y + *b\P[3]\y) / 8
;DrawBezierBase(@left,0,255,0);
right\P[0]\x = left\P[3]\x;
right\P[0]\y = left\P[3]\y;
right\P[1]\x = (*b\P[1]\x + 2**b\P[2]\x + *b\P[3]\x) / 4
right\P[1]\y = (*b\P[1]\y + 2**b\P[2]\y + *b\P[3]\y) / 4
right\P[2]\x = (*b\P[2]\x + *b\P[3]\x) / 2
right\P[2]\y = (*b\P[2]\y + *b\P[3]\y) / 2
right\P[3]\x = *b\P[3]\x
right\P[3]\y = *b\P[3]\y
;DrawBezierBase(@right,0,0,255)
;draw the 2 segments recursively
DrawBezierRecursive (@left,level -1)
DrawBezierRecursive (@right,level -1)
EndIf
EndProcedure
Procedure DrawBezier()
DrawBezierBase(@Global_Bezier,255,0,0)
DrawBezierRecursive(@Global_Bezier,level)
EndProcedure
Repeat
ClearScreen(#Black)
;-Souris
If ExamineMouse()
Mx = MouseX()
My = MouseY()
;Test si la souris est proche d'un point de contrôle
PointControle = -1
For i=0 To 3
If Mx > Global_Bezier\P[i]\x - #PointControle And Mx < Global_Bezier\P[i]\x + #PointControle
If My > Global_Bezier\P[i]\y - #PointControle And My < Global_Bezier\P[i]\y + #PointControle
Proche = i
PointControle = i
Break
EndIf
EndIf
Next
;La souris est proche d'un point de contrôle
If MouseButton(#PB_MouseButton_Left) And Proche>-1
Global_Bezier\P[Proche]\x = Mx
Global_Bezier\P[Proche]\y = My
Else
Proche = -1
EndIf
EndIf
;Calcule et trace la courbe de bézier
DrawBezier()
If StartDrawing(ScreenOutput())
;Affiche les points de contrôle
Circle(Global_Bezier\P[0]\x, Global_Bezier\P[0]\y,3,#Red)
Circle(Global_Bezier\P[1]\x, Global_Bezier\P[1]\y,3,#Red)
Circle(Global_Bezier\P[2]\x, Global_Bezier\P[2]\y,3,#Red)
Circle(Global_Bezier\P[3]\x, Global_Bezier\P[3]\y,3,#Red)
;Croix représentant la souris
LineXY(0, My, 799, My, #Green)
LineXY(Mx, 0, Mx, 599, #Green)
;La souris est proche d'un point de contrôle
If PointControle>-1
DrawingMode(#PB_2DDrawing_Outlined)
Circle(Mx, My, #PointControle+2, #Green)
EndIf
StopDrawing()
EndIf
ExamineKeyboard()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)