Bezier : Blitzmax vers Purebasic

Programmation avancée de jeux en PureBasic
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Bezier : Blitzmax vers Purebasic

Message par Thyphoon »

j'ai trouvé un petit code en BlitzMax que j'aimerais convertir en purebasic

Code : Tout sélectionner

Graphics 800,600,0,0

Local sx:Float, sy:Float
Local ex:Float, ey:Float
Local p1x:Float, p1y:Float
Local p2x:Float, p2y:Float

'Start Point
sx = 100
sy = 300

'End Point
ex = 300
ey = 500

'Control Points
p1x = sx
If sy<ey Then p1y = sy-200 Else	p1y = ey-200
p2x = ex
p2y = p1y

Local fTimer:Float

While Not KeyHit(KEY_ESCAPE)
Cls

DrawText "S:  "+sx+", "+sy,5,5
DrawText "E:  "+ex+", "+ey,5,25
DrawText "P1: "+p1x+", "+p1y,5,45
DrawText "P2: "+p2x+", "+p2y,5,65

fTimer :+ (1.0 / 1.0) * 0.0005

If fTimer < 1 Then Bezier(sx,sy,ex,ey,p1x,p1y,p2x,p2y,fTimer)

Flip
Wend

Function Bezier(sx:Float,sy:Float,ex:Float,ey:Float,p1x:Float,p1y:Float,p2x:Float,p2y:Float,t:Float)
	Local pointx:Float = sx*(1-t)^3 + 3*p1x*(1-t)^2*t + 3*p2x*(1-t)*t^2 + ex*t^3
	Local pointy# = sy*(1-t)^3 + 3*p1y*(1-t)^2*t + 3*p2y*(1-t)*t^2 + ey*t^3
	Plot pointx,pointy
End Function
Est ce que parmis vous il n'y aurait pas un "Ancien?" de chez Blitzmax qui serait le convertir, mes tentatives n'ont jamais fonctionné ... :(
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

zut j'avais oublié de posté ma dernière tentative de conversion

Code : Tout sélectionner

If InitSprite() And  InitKeyboard()
OpenScreen(800, 600, 32, "Bezier")
Else
End
EndIf


;'Start Point
sx.f = 100
sy.f = 300

;'End Point
ex.f = 300
ey.f = 500

;'Control Points
p1x = sx
If sy<ey 
  p1y = sy-200 
Else	
  p1y = ey-200 
EndIf
p2x = ex
p2y = p1y

Procedure Bezier(sx.f,sy.f,ex.f,ey.f,p1x.f,p1y.f,p2x.f,p2y.f,t.f)
	pointx=sx*Pow((1-t),3) + 3*p1x*Pow((1-t),2)*t + 3*p2x*(1-t)*Pow(t,2) + ex*Pow(t,3)
	pointy= sy*Pow((1-t),3) + 3*p1y*Pow((1-t),2)*t + 3*p2y*(1-t)*Pow(t,2) + ey*Pow(t,3)
	Plot(pointx,pointy,#Red)
EndProcedure

Repeat
  FlipBuffers(0)
  ExamineKeyboard()
  ClearScreen(0)
  StartDrawing(ScreenOutput())
    
    DrawText(5,5,"S:  "+Str(sx)+", "+Str(sy))
    DrawText(5,25,"E:  "+Str(ex)+", "+Str(ey))
    DrawText(5,45,"P1: "+Str(p1x)+", "+Str(p1y))
    DrawText(5,65,"P2: "+Str(p2x)+", "+Str(p2y))
    
    fTimer+(1.0 / 1.0) * 0.0005
    
    If fTimer < 1 
     Bezier(sx,sy,ex,ey,p1x,p1y,p2x,p2y,fTimer)
    EndIf
    StopDrawing()

Until KeyboardPushed(#PB_Key_Escape)
comtois
Messages : 5186
Inscription : mer. 21/janv./2004 17:48
Contact :

Message par comtois »

peut-être comme ça ?

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 = 100
Global_Bezier\P[0]\y = 300
Global_Bezier\P[1]\x = 100
Global_Bezier\P[1]\y = 100
Global_Bezier\P[2]\x = 300
Global_Bezier\P[2]\y = 100
Global_Bezier\P[3]\x = 300
Global_Bezier\P[3]\y = 500
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)  
Nan , je déconne :) , voila une proposition

Code : Tout sélectionner

EnableExplicit
If InitSprite() And  InitKeyboard()
OpenScreen(800, 600, 32, "Bezier")
Else
End
EndIf

Define.f sx, sy, ex, ey, p1x, p1y, p2x, p2y, fTimer

CreateSprite(0,800,600)
;Start Point
sx = 100
sy = 300

;End Point
ex = 300
ey = 500

;Control Points
p1x = sx
If sy<ey 
  p1y = sy-200 
Else   
  p1y = ey-200
EndIf
  
p2x = ex
p2y = p1y


Procedure Bezier(sx.f,sy.f,ex.f,ey.f,p1x.f,p1y.f,p2x.f,p2y.F,t.f)
   Define pointx.f,pointy.f
   
   pointx = sx*Pow((1-t),3) + 3*p1x*Pow((1-t),2)*t + 3*p2x*(1-t)*Pow(t,2) + ex*Pow(t,3)
   pointy = sy*Pow((1-t),3) + 3*p1y*Pow((1-t),2)*t + 3*p2y*(1-t)*Pow(t,2) + ey*Pow(t,3)
   StartDrawing(SpriteOutput(0))
   Plot(pointx,pointy,#White)
   StopDrawing()
EndProcedure

Repeat
  FlipBuffers()
  ExamineKeyboard()
  ClearScreen(0)
    fTimer + (1.0 / 1.0) * 0.0005

    If fTimer < 1 
      Bezier(sx,sy,ex,ey,p1x,p1y,p2x,p2y,fTimer)
    EndIf
    DisplaySprite(0,0,0)
    StartDrawing(ScreenOutput())
      Circle(sx,sy,4,#Green)
      Circle(ex,ey,4,#Green)
      Circle(p1x,p1y,4,#Red)
      Circle(p2x,p2y,4,#Red)
    StopDrawing()
    
Until KeyboardPushed(#PB_Key_Escape)
http://purebasic.developpez.com/
Je ne réponds à aucune question technique en PV, utilisez le forum, il est fait pour ça, et la réponse peut profiter à tous.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Merci beaucoup comtois !

J'ai déjà étudier tes codes et d'autre pour dessiné une courbe de bezier.
Mais je n'ai jamais réussi a faire ce que je voulais jusqu'a present.
A savoir, faire une courbe avec une multitude de point. et avoir une fonction (simple)qui retourne les coordonées en fonction du temps, pour qu'un sprite puisse suivre la courbe...
Avec le code que tu m'a convertit j'arrive maintenant a donnée une durée entre le point de départ et le point d'arriver, et a avoir les coordonées en fonction du temps écouler. mais je n'ai pas encore trouvé comment avoir une multitude de point ou comment enchainer plusieur courbe de bezier pour que ça reste "souple" ?
Anonyme

Message par Anonyme »

Ta courbe possède 2 points de contrôle , si tu veut couplé deux courbe , tu prend le dernier point de controle de ta première courbe , puis le premier de la deuxième courbe , tu lui fait une inversion.
C'est à dire , si ton dernier point de controle de ta première courbe à un angle de 270° et une distance de -100 pixel ( il pointe vers le haut ) alors l'inversion et la suivante :
270 + 180 = 450 ( soit 90° )
-100 = 100

si j'ai le temps de me pencher dessus je te fait un p'tit exemple avec un zoli dessin :D
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Cpl.Bator a écrit :Ta courbe possède 2 points de contrôle , si tu veut couplé deux courbe , tu prend le dernier point de controle de ta première courbe , puis le premier de la deuxième courbe , tu lui fait une inversion.
C'est à dire , si ton dernier point de controle de ta première courbe à un angle de 270° et une distance de -100 pixel ( il pointe vers le haut ) alors l'inversion et la suivante :
270 + 180 = 450 ( soit 90° )
-100 = 100

si j'ai le temps de me pencher dessus je te fait un p'tit exemple avec un zoli dessin :D
C'est très intéressant ce que tu me dit là, mais j'avoue ne pas tout saisir
voici un code ou j'ai essayer de lié plusieurs point a la suite...
c'est pas tres propre c'est pour le principe

Code : Tout sélectionner

Edit: code changé voir le message suivant !! :o)
Dernière modification par Thyphoon le jeu. 13/déc./2007 17:54, modifié 1 fois.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

voici une tentative d'intégré les explications de Cpl.Bator
j'ai du faire une erreur...je cherche

Code : Tout sélectionner


EnableExplicit
If InitSprite() And  InitKeyboard()
OpenScreen(800, 600, 32, "Bezier")
Else
End
EndIf

Global sx.f, sy.f, ex.f, ey.f, p1x.f, p1y.f, p2x.f, p2y.f, fTimer.f

CreateSprite(0,800,600)
;Start Point
sx = 200
sy = 300

;End Point
ex = 300
ey = 400

p1x=150
p1y=20

p2x=400
p2y=300

;Control Points
;p1x = sx
;If sy<ey
;  p1y = sy-200
;Else   
;  p1y = ey-200
;EndIf
; 
;p2x = ex
;p2y = p1y

Global StartTime.l=ElapsedMilliseconds()
Procedure Bezier();sx.f,sy.f,ex.f,ey.f,p1x.f,p1y.f,p2x.f,p2y.F,t.f
   Define pointx.f,pointy.f,duration.l,t.f,hyp.f,Alpha.f
   duration=5000
   t=(ElapsedMilliseconds()-StartTime)/duration
   pointx = sx*Pow((1-t),3) + 3*p1x*Pow((1-t),2)*t + 3*p2x*(1-t)*Pow(t,2) + ex*Pow(t,3)
   pointy = sy*Pow((1-t),3) + 3*p1y*Pow((1-t),2)*t + 3*p2y*(1-t)*Pow(t,2) + ey*Pow(t,3)
   If pointx>0 And pointx<800 And pointy>0 And pointy<600
   StartDrawing(SpriteOutput(0))
   Plot(pointx,pointy,#White)
   StopDrawing()
   EndIf
   If t>1:
   Debug "POint suivant"
    StartTime.l=ElapsedMilliseconds()
    sx=ex
    sy=ey
    ;calcul p1
    hyp=Sqr((ex-p2x)*(ex-p2x)+(ey-p2y)*(ey-p2y))
    Alpha=ASin((ey-p2y)/hyp)+#PI
    
    p1x=Sin(Alpha)*hyp
    p1y=Cos(Alpha)*hyp
    ex=750
    ey=600
   EndIf
EndProcedure


Repeat
  FlipBuffers()
  ExamineKeyboard()
  ClearScreen(0)
    fTimer + (1.0 / 1.0) * 0.0005
      Debug StrF(fTimer)
    If fTimer < 1
      Bezier()
    EndIf
    DisplaySprite(0,0,0)
    StartDrawing(ScreenOutput())
      Circle(sx,sy,4,#Green)
      Circle(ex,ey,4,#Green)
      Circle(p1x,p1y,4,#Red)
      Circle(p2x,p2y,4,#Red)
    StopDrawing()
   
Until KeyboardPushed(#PB_Key_Escape)
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Youpie !! j'ai trouvé !! un grand Merci Cpl.Bator pour tes précisions !
Voici le code Brouillon

Code : Tout sélectionner

EnableExplicit
#RadToDeg = 180.0 / #PI
#RadToGrd = 200.0 / #PI
#DegToRad = #PI / 180.0
#DegToGrd = 200 / 180.0
#GrdToRad = #PI / 200.0
#GrdToDeg = 180 / 200.0



Macro RadToDeg(Rad)
  ((Rad) * #RadToDeg)
EndMacro

Macro RadToGrd(Rad)
  ((Rad) * #RadToGrd)
EndMacro

Macro DegToRad(Deg)
  ((Deg) * #DegToRad)
EndMacro

Macro DegToGrd(Deg)
  ((Deg) * #DegToGrd)
EndMacro

Macro GrdToRad(Grd)
  ((Grd) * #GrdToRad)
EndMacro

Macro GrdToDeg(Grd)
  ((Grd) * #GrdToDeg)
EndMacro
If InitSprite() And  InitKeyboard()
OpenScreen(800, 600, 32, "Bezier")
Else
End
EndIf

Global sx.f, sy.f, ex.f, ey.f, p1x.f, p1y.f, p2x.f, p2y.f, fTimer.f

CreateSprite(0,800,600)
;Start Point
sx = 200
sy = 300

;End Point
ex = 300
ey = 400

p1x=150
p1y=20

p2x=400
p2y=300

;Control Points
;p1x = sx
;If sy<ey
;  p1y = sy-200
;Else   
;  p1y = ey-200
;EndIf
;
;p2x = ex
;p2y = p1y

Global StartTime.l=ElapsedMilliseconds()
Procedure Bezier();sx.f,sy.f,ex.f,ey.f,p1x.f,p1y.f,p2x.f,p2y.F,t.f
   Define pointx.f,pointy.f,duration.l,t.f,hyp.f,Alpha.f
   duration=5000
   t=(ElapsedMilliseconds()-StartTime)/duration
   pointx = sx*Pow((1-t),3) + 3*p1x*Pow((1-t),2)*t + 3*p2x*(1-t)*Pow(t,2) + ex*Pow(t,3)
   pointy = sy*Pow((1-t),3) + 3*p1y*Pow((1-t),2)*t + 3*p2y*(1-t)*Pow(t,2) + ey*Pow(t,3)
   If pointx>0 And pointx<800 And pointy>0 And pointy<600
   StartDrawing(SpriteOutput(0))
   Plot(pointx,pointy,#White)
   StopDrawing()
   EndIf
   If t>1:
   Debug "POint suivant"
    StartTime.l=ElapsedMilliseconds()
    sx=ex
    sy=ey
    ;calcul p1
    hyp=-Sqr((ex-p2x)*(ex-p2x)+(ey-p2y)*(ey-p2y))
    Alpha=RadToDeg(ASin((ey-p2y)/hyp))+180
    Debug Alpha
   
    p1x=ex+Sin(DegToRad(Alpha))*hyp
    p1y=ey+Cos(DegToRad(Alpha))*hyp
    ex=750
    ey=600
   EndIf
EndProcedure


Repeat
  FlipBuffers()
  ExamineKeyboard()
  ClearScreen(0)
    fTimer + (1.0 / 1.0) * 0.0005
      Debug StrF(fTimer)
    If fTimer < 1
      Bezier()
    EndIf
    DisplaySprite(0,0,0)
    StartDrawing(ScreenOutput())
      Circle(sx,sy,4,#Green)
      Circle(ex,ey,4,#Green)
      Circle(p1x,p1y,4,#Blue)
      Circle(p2x,p2y,4,#Red)
    StopDrawing()
   
Until KeyboardPushed(#PB_Key_Escape) 
Me reste plus qu'a mettre ça au claire.
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Voici un nouveau code permettant de tracer une courbe puis de faire suivre cette courbe a une boule.

vous pouvez rajouter des points avec un clic droit, déplacer les points avec le clic gauche, et espace pour faire suivre a la balle la courbe.

Tout cela peut sûrement être améliorer et optimisé.
D'ailleurs si vous avez des suggestions pour en faire une lib n'hésitez pas !

Code : Tout sélectionner

;Remerciement a Comtois et Cpl.Bator pour leur aide.
Structure Pixel
  x.l
  y.l
EndStructure

Structure Bezier
  Nb.l          ;Nombre total de point
  StartTime.l   ;L'heure ou on a commencé a tracé
  PathPointer.l ;Point de depart de la section a calculer
EndStructure

Global Dim BezierPath.pixel(1),Bezier.Bezier

;Met a jour les valeurs d'un point
Procedure UpdatePoint(no.l,x,y)
 BezierPath(no)\x=x
 BezierPath(no)\y=y
 Select no%3
  Case 1 ;Un point Normal
    ;Si c'est un point normal rien d'autre a faire 
  
  Case 2 ;Si c'est un Point de Reference N°1
    
    If no>4;Modification du point de Reference N°2 de la section d'avant 
      x1=BezierPath(no)\x
      y1=BezierPath(no)\y
      x=BezierPath(no-1)\x
      y=BezierPath(no-1)\y
      l=(x1-x)
      h=(y1-y)
      BezierPath(no-2)\y=y-h
      BezierPath(no-2)\x=x-l
    EndIf
  Case 0 ;Si c'est un Point de Reference N°2
    If no<=Bezier\Nb-2;Modification du point de Reference N°1 de la section d'apres 
      x1=BezierPath(no)\x
      y1=BezierPath(no)\y
      x=BezierPath(no+1)\x
      y=BezierPath(no+1)\y
      l=(x1-x)
      h=(y1-y)
      BezierPath(no+2)\y=y-h
      BezierPath(no+2)\x=x-l
    EndIf
 EndSelect
EndProcedure

;On rajoute un point
Procedure AddPoint(x.l,y.l)
  Bezier\Nb+1
  ReDim BezierPath.pixel(Bezier\Nb)
  UpdatePoint(Bezier\Nb,x,y)
EndProcedure

;Depart du trajet
Procedure StartBezier()
  Bezier\StartTime.l=ElapsedMilliseconds()
  Bezier\PathPointer=1
EndProcedure

;Deplacement de la balle
Procedure RunBesier()
  If Bezier\StartTime>0
    duration=5000
    t.f=(ElapsedMilliseconds()-Bezier\StartTime)/duration
    no=Bezier\PathPointer
    x = BezierPath(no)\x*Pow((1-t),3) + 3*BezierPath(no+1)\x*Pow((1-t),2)*t + 3*BezierPath(no+2)\x*(1-t)*Pow(t,2) + BezierPath(no+3)\x*Pow(t,3)
    y = BezierPath(no)\y*Pow((1-t),3) + 3*BezierPath(no+1)\y*Pow((1-t),2)*t + 3*BezierPath(no+2)\y*(1-t)*Pow(t,2) + BezierPath(no+3)\y*Pow(t,3)
    If t>1
      Bezier\StartTime.l=ElapsedMilliseconds()
      Bezier\PathPointer+3
      If Bezier\PathPointer>Bezier\Nb-3
        Bezier\StartTime=0
      EndIf
    EndIf
    
    If x>0 And x<800 And y>0 And y<600


      Circle(x,y,20,#Blue)

    EndIf
  EndIf
EndProcedure

;Traçage rapide de la courbe
Procedure FastTrace()
  Nbp=Int((Bezier\Nb-1)/3)
  DrawText(0,10,Str(Nbp))
  old_x=BezierPath(1)\x
  old_y=BezierPath(1)\y
  For n=0 To Nbp-1
    no=n*3+1
    Esp.l=10
    For Bt=0 To Esp
      t.f=Bt/Esp
      x = BezierPath(no)\x*Pow((1-t),3) + 3*BezierPath(no+1)\x*Pow((1-t),2)*t + 3*BezierPath(no+2)\x*(1-t)*Pow(t,2) + BezierPath(no+3)\x*Pow(t,3)
      y = BezierPath(no)\y*Pow((1-t),3) + 3*BezierPath(no+1)\y*Pow((1-t),2)*t + 3*BezierPath(no+2)\y*(1-t)*Pow(t,2) + BezierPath(no+3)\y*Pow(t,3)
      LineXY(x,y,old_x,old_y,#White)
      old_x=x
      old_y=y
    Next
  Next
EndProcedure

;Traçace des différents point de Reference
Procedure TracePoint(no)
  If no%3=1 ;Si c'est point de depart ou d'arrivé
    Circle(BezierPath(no)\x,BezierPath(no)\y,10,#Red)
  Else ; il s'agit d'un point de reference
    Circle(BezierPath(no)\x,BezierPath(no)\y,10,#Green)
  EndIf
EndProcedure

If InitSprite() And  InitKeyboard() And OpenScreen(800, 600, 32, "Bezier") And InitMouse()

  Repeat
    FlipBuffers()
    ExamineKeyboard()
    ExamineMouse()
    
    If KeyboardPushed(#PB_Key_Space);Demarrage du mouvement
     
      StartBezier()
    EndIf
    
    If MouseButton(#PB_MouseButton_Left)
      ;Selection d'un point
      If MouseDeltaX()=0 And MouseDeltaY()=0
        For z=1 To Bezier\Nb
          If MouseX()>BezierPath(z)\x-10 And MouseX()<BezierPath(z)\x+10 And MouseY()>BezierPath(z)\y-10 And MouseY()<BezierPath(z)\y+10
            SelectedPoint=z
            Break;
          EndIf
        Next
      ;Deplacement d'un point
      Else
        UpdatePoint(SelectedPoint,BezierPath(SelectedPoint)\x+MouseDeltaX(),BezierPath(SelectedPoint)\y+MouseDeltaY())
      EndIf
    EndIf
    
    ;On ajoute un point a la courbe
    If MouseButton(#PB_MouseButton_Right)
      AddPoint(MouseX(),MouseY())
      Delay(250)
    EndIf
    ClearScreen(0)
    
    StartDrawing(ScreenOutput())
      For z=1 To Bezier\Nb
        TracePoint(z)  
      Next
      FastTrace() ; Traçage de la courbe rapidment
      RunBesier() ; Trçage de la balle
      Line(MouseX(),MouseY(),10,0,#White)
      Line(MouseX(),MouseY(),0,10,#White)
    StopDrawing()
    
  Until KeyboardPushed(#PB_Key_Escape) 
EndIf
Anonyme

Message par Anonyme »

Super boulot Typhoon , c'est exactement ce dont je t'ai parlé , c'est impecable ! je vais surement ajouté se genre de Fct° dans ma lib ! c'est très pratique en tout cas ! :D
Code à épinglé :wink:
Avatar de l’utilisateur
Thyphoon
Messages : 2706
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Message par Thyphoon »

Cpl.Bator a écrit :Super boulot Typhoon , c'est exactement ce dont je t'ai parlé , c'est impecable ! je vais surement ajouté se genre de Fct° dans ma lib ! c'est très pratique en tout cas ! :D
Code à épinglé :wink:
Merci mais sans toi je n'aurais jamais réussi ! C'est claire que si tu rajoute ça dans ta lib elle va devenir vite incontournable ! :D (vivement la version windows :wink: )
Répondre