Page 1 sur 1

Tout sur les Bspline

Publié : sam. 17/mai/2025 18:55
par SPH
Enjoy

Code : Tout sélectionner

; Real BSpline code by Crisot / SPH
sph_nb=2000

Dim x.f(sph_nb)
Dim y.f(sph_nb)


InitSprite() 
InitKeyboard() 
InitMouse() 

ExamineDesktops()

ddw = DesktopWidth(0)
ddh = DesktopHeight(0)

OpenScreen(ddw,ddh,32,"Bezier") 

cw = RGB(255,255,255) 
cr = RGB(255,0,0) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Exemple=Random(12)+1
nombre=4+Random(10)
synchro=Random(1)

For i=0 To sph_nb
  x(i)=Random(ddw-1)
  y(i)=Random(ddh-1)
Next

;Exemple 1: 4 points de base (comme le mec), qui tracent une vrai bspline
;Exemple 2: Pareil que le 1, mais la courbe passe par les points début et fin
;  grace au triplage des points début et fin
;Exemple 3: 4 points en carré, qui tracent un quart de cercle
;Exemple 4: 7 points en carré, qui tracent cercle complet
;Exemple 5: Plein de points au pif
;Exemple 6: Plein de points au pif, courbe qui passe par les points début et fin

;synchro = 1: sert juste aux courbes qui passent par les points début et fin, car
;  pour ces courbes, les points sont répétés 3 fois, et il faut pouvoir déplacer les 3
;  en même temps, sinon ça nique tout :)

Procedure bspline(x0,y0,x1,y1,x2,y2,x3,y3,color) 

  For i = 0 To 100

    t1.f = i/100
    t2.f = t1*t1
    t3.f = t1*t1*t1

  	k1.f = 1 - 3*t1 + 3*t2 - t3
    k2.f = 4 - 6*t2 + 3*t3
  	k3.f = 1 + 3*t1 + 3*t2 - 3*t3

    xfinal.f = (x0 * k1 + x1 * k2 + x2 * k3 + x3 * t3) / 6
		yfinal.f = (y0 * k1 + y1 * k2 + y2 * k3 + y3 * t3) / 6

    Plot (xfinal,yfinal,color)   

  Next I


EndProcedure 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Repeat 
  ClearScreen(0) 
  
  ExamineKeyboard() 
  ExamineMouse() 

  If MouseButton(1) And mousepush=0
    key=key+1 : key=key%nombre
    MouseLocate(x(key),y(key))
  EndIf 
  mousepush=MouseButton(1) 

  x(key)=MouseX() : y(key)=MouseY() ; Déplacement du point

  If synchro=1            ; Juste une gruge pour bouger les points, rien à voir avec la courbe.
    x(1)=x(0) : y(1)=y(0)
    x(2)=x(0) : y(2)=y(0)
    x(nombre-1)=x(nombre-3) : y(nombre-1)=y(nombre-3)
    x(nombre-2)=x(nombre-3) : y(nombre-2)=y(nombre-3)
  EndIf

  StartDrawing(ScreenOutput())
  DrawingMode(4)
  For n=0 To nombre-1   ; On trace les cercles...
    If n=key : Circle(x(n),y(n),5,cr) : Else : Circle(x(n),y(n),5,cw) : EndIf
  Next
  For n=0 To nombre-4   ; On trace la bspline
    bspline(x(n),y(n),x(n+1),y(n+1),x(n+2),y(n+2),x(n+3),y(n+3),cw)
  Next
  StopDrawing() 

  FlipBuffers() 
  
Until KeyboardPushed(1)



Re: Tout sur les Bspline

Publié : lun. 19/mai/2025 6:36
par manababel
Bonjour
j'ai un probeme avec "ExamineKeyboard()" qui ne marche pas sur mon pc (pb v6.12 LTS x64)
voici une version modifiee en mode fenetre

Code : Tout sélectionner

; Real BSpline code by Crisot / SPH

Dim x.f(200)
Dim y.f(200)

Exemple=6
;Exemple 1: 4 points de base (comme le mec), qui tracent une vrai bspline
;Exemple 2: Pareil que le 1, mais la courbe passe par les points début et fin
;  grace au triplage des points début et fin
;Exemple 3: 4 points en carré, qui tracent un quart de cercle
;Exemple 4: 7 points en carré, qui tracent cercle complet
;Exemple 5: Plein de points au pif
;Exemple 6: Plein de points au pif, courbe qui passe par les points début et fin

;synchro = 1: sert juste aux courbes qui passent par les points début et fin, car
;  pour ces courbes, les points sont répétés 3 fois, et il faut pouvoir déplacer les 3
;  en même temps, sinon ça nique tout :)

If exemple=1
  nombre=4
  x(0)=0 : y(0)=0
  x(1)=1023 : y(1)=0
  x(2)=0 : y(2)=767
  x(3)=1023 : y(3)=767
EndIf

If exemple=2
  nombre=8
  synchro=1   ; Gruge pour déplacer les points 3 par 3, car x0=x1=x2, etc...
  x(0)=0 : y(0)=0
  x(1)=x(0) : y(1)=y(0)
  x(2)=x(0) : y(2)=y(0)
  x(3)=1023 : y(3)=0
  x(4)=0 : y(4)=767
  x(5)=1023 : y(5)=767
  x(6)=x(5) : y(6)=y(5)
  x(7)=x(5) : y(7)=y(5)
EndIf

If exemple=3
  nombre=4
  x(0)=0 : y(0)=0
  x(1)=1023 : y(1)=0
  x(2)=1023 : y(2)=767
  x(3)=0 : y(3)=767
EndIf

If exemple=4
  nombre=7
  x(0)=0 : y(0)=0
  x(1)=1023 : y(1)=0
  x(2)=1023 : y(2)=767
  x(3)=0 : y(3)=767
  x(4)=x(0) : y(4)=y(0)
  x(5)=x(1) : y(5)=y(1)
  x(6)=x(2) : y(6)=y(2)
EndIf

If exemple=5
  nombre=12
  x(0)=0 : y(0)=0
  x(1)=80 : y(1)=100
  x(2)=60 : y(2)=600
  x(3)=800 : y(3)=700
  x(4)=500 : y(4)=0
  x(5)=1000 : y(5)=300
  x(6)=700 : y(6)=100
  x(7)=200 : y(7)=0
  x(8)=0 : y(8)=700
  x(9)=100 : y(9)=0
  x(10)=0 : y(10)=200
  x(11)=300 : y(11)=300
EndIf

If exemple=6
  nombre=12
  synchro=1   ; Gruge pour déplacer les points 3 par 3, car x0=x1=x2, etc...
  x(0)=100 : y(0)=100
  x(1)=x(0) : y(1)=y(0)
  x(2)=x(0) : y(2)=y(0)
  x(3)=300 : y(3)=150
  x(4)=400 : y(4)=350
  x(5)=200 : y(5)=450
  x(6)=500 : y(6)=200
  x(7)=700 : y(7)=700
  x(8)=600 : y(8)=600
  x(9)=1000 : y(9)=550
  x(10)=x(9) : y(10)=y(9)
  x(11)=x(9) : y(11)=y(10)
EndIf


Procedure bspline(x0,y0,x1,y1,x2,y2,x3,y3,color) 

  For i = 0 To 100 

    t1.f = i/100
    t2.f = t1*t1
    t3.f = t1*t1*t1

  	k1.f = 1 - 3*t1 + 3*t2 - t3
    k2.f = 4 - 6*t2 + 3*t3
  	k3.f = 1 + 3*t1 + 3*t2 - 3*t3

    xfinal.f = (x0 * k1 + x1 * k2 + x2 * k3 + x3 * t3) / 6
		yfinal.f = (y0 * k1 + y1 * k2 + y2 * k3 + y3 * t3) / 6

    Plot (xfinal,yfinal,color)   

  Next I


EndProcedure 


ExamineDesktops()

ddw = DesktopWidth(0) *0.5
ddh = DesktopHeight(0) *0.5

OpenWindow(0, ddw * 0.5 , ddh * 0.5 , ddw , ddh , "Bezier")

InitSprite() 
InitKeyboard() 
InitMouse() 
OpenWindowedScreen(WindowID(0), 0,0,ddw,ddh) 


cw = RGB(255,255,255) 
cr = RGB(255,0,0) 

Repeat 
  Event = WaitWindowEvent()
  ExamineKeyboard() 
  ExamineMouse() 

  If MouseButton(1) And mousepush=0
    key=key+1 : key=key%nombre
    MouseLocate(x(key),y(key))
  EndIf 
  mousepush=MouseButton(1) 

  x(key)=MouseX() : y(key)=MouseY() ; Déplacement du point

  If synchro=1            ; Juste une gruge pour bouger les points, rien à voir avec la courbe.
    x(1)=x(0) : y(1)=y(0)
    x(2)=x(0) : y(2)=y(0)
    x(nombre-1)=x(nombre-3) : y(nombre-1)=y(nombre-3)
    x(nombre-2)=x(nombre-3) : y(nombre-2)=y(nombre-3)
  EndIf

  StartDrawing(ScreenOutput())
  DrawingMode(4)
  For n=0 To nombre-1   ; On trace les cercles...
    If n=key : Circle(x(n),y(n),5,cr) : Else : Circle(x(n),y(n),5,cw) : EndIf
  Next
  For n=0 To nombre-4   ; On trace la bspline
    bspline(x(n),y(n),x(n+1),y(n+1),x(n+2),y(n+2),x(n+3),y(n+3),cw)
  Next
  StopDrawing() 

  FlipBuffers() 
  ClearScreen(0) 
  If KeyboardPushed(1)
    End
    EndIf
Until Event = #PB_Event_CloseWindow

Re: Tout sur les Bspline

Publié : lun. 19/mai/2025 7:49
par SPH

Code : Tout sélectionner

; Real BSpline code by Crisot / SPH

Dim x.f(200)
Dim y.f(200)

Exemple=6
;Exemple 1: 4 points de base (comme le mec), qui tracent une vrai bspline
;Exemple 2: Pareil que le 1, mais la courbe passe par les points début et fin
;  grace au triplage des points début et fin
;Exemple 3: 4 points en carré, qui tracent un quart de cercle
;Exemple 4: 7 points en carré, qui tracent cercle complet
;Exemple 5: Plein de points au pif
;Exemple 6: Plein de points au pif, courbe qui passe par les points début et fin

;synchro = 1: sert juste aux courbes qui passent par les points début et fin, car
;  pour ces courbes, les points sont répétés 3 fois, et il faut pouvoir déplacer les 3
;  en même temps, sinon ça nique tout :)

If exemple=1
  nombre=4
  x(0)=0 : y(0)=0
  x(1)=1023 : y(1)=0
  x(2)=0 : y(2)=767
  x(3)=1023 : y(3)=767
EndIf

If exemple=2
  nombre=8
  synchro=1   ; Gruge pour déplacer les points 3 par 3, car x0=x1=x2, etc...
  x(0)=0 : y(0)=0
  x(1)=x(0) : y(1)=y(0)
  x(2)=x(0) : y(2)=y(0)
  x(3)=1023 : y(3)=0
  x(4)=0 : y(4)=767
  x(5)=1023 : y(5)=767
  x(6)=x(5) : y(6)=y(5)
  x(7)=x(5) : y(7)=y(5)
EndIf

If exemple=3
  nombre=4
  x(0)=0 : y(0)=0
  x(1)=1023 : y(1)=0
  x(2)=1023 : y(2)=767
  x(3)=0 : y(3)=767
EndIf

If exemple=4
  nombre=7
  x(0)=0 : y(0)=0
  x(1)=1023 : y(1)=0
  x(2)=1023 : y(2)=767
  x(3)=0 : y(3)=767
  x(4)=x(0) : y(4)=y(0)
  x(5)=x(1) : y(5)=y(1)
  x(6)=x(2) : y(6)=y(2)
EndIf

If exemple=5
  nombre=12
  x(0)=0 : y(0)=0
  x(1)=80 : y(1)=100
  x(2)=60 : y(2)=600
  x(3)=800 : y(3)=700
  x(4)=500 : y(4)=0
  x(5)=1000 : y(5)=300
  x(6)=700 : y(6)=100
  x(7)=200 : y(7)=0
  x(8)=0 : y(8)=700
  x(9)=100 : y(9)=0
  x(10)=0 : y(10)=200
  x(11)=300 : y(11)=300
EndIf

If exemple=6
  nombre=12
  synchro=1   ; Gruge pour déplacer les points 3 par 3, car x0=x1=x2, etc...
  x(0)=100 : y(0)=100
  x(1)=x(0) : y(1)=y(0)
  x(2)=x(0) : y(2)=y(0)
  x(3)=300 : y(3)=150
  x(4)=400 : y(4)=350
  x(5)=200 : y(5)=450
  x(6)=500 : y(6)=200
  x(7)=700 : y(7)=700
  x(8)=600 : y(8)=600
  x(9)=1000 : y(9)=550
  x(10)=x(9) : y(10)=y(9)
  x(11)=x(9) : y(11)=y(10)
EndIf


Procedure bspline(x0,y0,x1,y1,x2,y2,x3,y3,color) 

  For i = 0 To 100 

    t1.f = i/100
    t2.f = t1*t1
    t3.f = t1*t1*t1

  	k1.f = 1 - 3*t1 + 3*t2 - t3
    k2.f = 4 - 6*t2 + 3*t3
  	k3.f = 1 + 3*t1 + 3*t2 - 3*t3

    xfinal.f = (x0 * k1 + x1 * k2 + x2 * k3 + x3 * t3) / 6
		yfinal.f = (y0 * k1 + y1 * k2 + y2 * k3 + y3 * t3) / 6

    Plot (xfinal,yfinal,color)   

  Next I


EndProcedure 


ExamineDesktops()

ddw = DesktopWidth(0) *0.8
ddh = DesktopHeight(0) *0.8

OpenWindow(0, ddw * 0.8 , ddh * 0.8 , ddw , ddh , "Bezier",#PB_Window_ScreenCentered)

InitSprite() 
InitKeyboard() 
InitMouse() 
OpenWindowedScreen(WindowID(0), 0,0,ddw,ddh) 


cw = RGB(255,255,255) 
cr = RGB(255,0,0) 

Repeat 
  Event = WaitWindowEvent()
  ExamineKeyboard() 
  ExamineMouse() 

  If MouseButton(1) And mousepush=0
    key=key+1 : key=key%nombre
    MouseLocate(x(key),y(key))
  EndIf 
  mousepush=MouseButton(1) 

  x(key)=MouseX() : y(key)=MouseY() ; Déplacement du point

  If synchro=1            ; Juste une gruge pour bouger les points, rien à voir avec la courbe.
    x(1)=x(0) : y(1)=y(0)
    x(2)=x(0) : y(2)=y(0)
    x(nombre-1)=x(nombre-3) : y(nombre-1)=y(nombre-3)
    x(nombre-2)=x(nombre-3) : y(nombre-2)=y(nombre-3)
  EndIf

  StartDrawing(ScreenOutput())
  DrawingMode(4)
  For n=0 To nombre-1   ; On trace les cercles...
    If n=key : Circle(x(n),y(n),5,cr) : Else : Circle(x(n),y(n),5,cw) : EndIf
  Next
  For n=0 To nombre-4   ; On trace la bspline
    bspline(x(n),y(n),x(n+1),y(n+1),x(n+2),y(n+2),x(n+3),y(n+3),cw)
  Next
  StopDrawing() 

  FlipBuffers() 
  ClearScreen(0) 
  If KeyboardPushed(1)
    End
    EndIf
Until Event = #PB_Event_CloseWindow
Manababel :ton code faisait sur mon ordi une erreur "Plot". Le plot etait hors ecran.
Par contre, j'ai remarqué une lenteur inexpliquée.

:idea:

Re: Tout sur les Bspline

Publié : lun. 19/mai/2025 19:01
par manababel
apres quelques tests , ce n'est pas un probleme de vitesse mais un probleme de latence de la souris , le programme tourne a 60fps , je ne sais pas d'ou vient le probleme.
voici le programme sans "acceleration materielle" et il tourne tres bien meme avec le debugger activé ( attention programme buggé )

Code : Tout sélectionner

; Real BSpline code by Crisot / SPH

Dim x.f(200)
Dim y.f(200)

Exemple=6
;Exemple 1: 4 points de base (comme le mec), qui tracent une vrai bspline
;Exemple 2: Pareil que le 1, mais la courbe passe par les points début et fin
;  grace au triplage des points début et fin
;Exemple 3: 4 points en carré, qui tracent un quart de cercle
;Exemple 4: 7 points en carré, qui tracent cercle complet
;Exemple 5: Plein de points au pif
;Exemple 6: Plein de points au pif, courbe qui passe par les points début et fin

;synchro = 1: sert juste aux courbes qui passent par les points début et fin, car
;  pour ces courbes, les points sont répétés 3 fois, et il faut pouvoir déplacer les 3
;  en même temps, sinon ça nique tout :)

If exemple=1
  nombre=4
  x(0)=0 : y(0)=0
  x(1)=1023 : y(1)=0
  x(2)=0 : y(2)=767
  x(3)=1023 : y(3)=767
EndIf

If exemple=2
  nombre=8
  synchro=1   ; Gruge pour déplacer les points 3 par 3, car x0=x1=x2, etc...
  x(0)=0 : y(0)=0
  x(1)=x(0) : y(1)=y(0)
  x(2)=x(0) : y(2)=y(0)
  x(3)=1023 : y(3)=0
  x(4)=0 : y(4)=767
  x(5)=1023 : y(5)=767
  x(6)=x(5) : y(6)=y(5)
  x(7)=x(5) : y(7)=y(5)
EndIf

If exemple=3
  nombre=4
  x(0)=0 : y(0)=0
  x(1)=1023 : y(1)=0
  x(2)=1023 : y(2)=767
  x(3)=0 : y(3)=767
EndIf

If exemple=4
  nombre=7
  x(0)=0 : y(0)=0
  x(1)=1023 : y(1)=0
  x(2)=1023 : y(2)=767
  x(3)=0 : y(3)=767
  x(4)=x(0) : y(4)=y(0)
  x(5)=x(1) : y(5)=y(1)
  x(6)=x(2) : y(6)=y(2)
EndIf

If exemple=5
  nombre=12
  x(0)=0 : y(0)=0
  x(1)=80 : y(1)=100
  x(2)=60 : y(2)=600
  x(3)=800 : y(3)=700
  x(4)=500 : y(4)=0
  x(5)=1000 : y(5)=300
  x(6)=700 : y(6)=100
  x(7)=200 : y(7)=0
  x(8)=0 : y(8)=700
  x(9)=100 : y(9)=0
  x(10)=0 : y(10)=200
  x(11)=300 : y(11)=300
EndIf

If exemple=6
  nombre=12
  synchro=1   ; Gruge pour déplacer les points 3 par 3, car x0=x1=x2, etc...
  x(0)=100 : y(0)=100
  x(1)=x(0) : y(1)=y(0)
  x(2)=x(0) : y(2)=y(0)
  x(3)=300 : y(3)=150
  x(4)=400 : y(4)=350
  x(5)=200 : y(5)=450
  x(6)=500 : y(6)=200
  x(7)=700 : y(7)=700
  x(8)=600 : y(8)=600
  x(9)=1000 : y(9)=550
  x(10)=x(9) : y(10)=y(9)
  x(11)=x(9) : y(11)=y(10)
EndIf


Procedure bspline(x0,y0,x1,y1,x2,y2,x3,y3,color,ligne) 
  
  For i = 0 To 100 
    
    t1.f = i/100
    t2.f = t1*t1
    t3.f = t1*t1*t1
    
    k1.f = 1 - 3*t1 + 3*t2 - t3
    k2.f = 4 - 6*t2 + 3*t3
    k3.f = 1 + 3*t1 + 3*t2 - 3*t3
    
    xfinal.f = (x0 * k1 + x1 * k2 + x2 * k3 + x3 * t3) / 6
    yfinal.f = (y0 * k1 + y1 * k2 + y2 * k3 + y3 * t3) / 6
    
    If xfinal >= 0  And yfinal >= 0; And xfinal < ddw And yfinal < ddh 
      If ligne = 0
        Plot (xfinal,yfinal,color)  
      Else
        If i > 0 
        LineXY(mxf,myf,xfinal,yfinal,color)
        EndIf
        mxf = xfinal
        myf = yfinal
      EndIf
    EndIf
    
  Next I
  
EndProcedure 

ExamineDesktops()

ddw = DesktopWidth(0) *0.8
ddh = DesktopHeight(0) *0.8
ligne = 0

OpenWindow(0, ddw * 0.8 , ddh * 0.8 , ddw , ddh , "Bezier",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)

img = CreateImage(0,ddw,ddh)

cw = RGB(255,255,255) 
cr = RGB(255,0,0) 

Repeat 
  Event = WaitWindowEvent()
  Select event
    Case #PB_Event_CloseWindow
      quit = 1
      
    Case  #PB_Event_LeftClick
      key=key+1 : key=key%nombre
      mx = WindowMouseX(0) - x(key)
      my = WindowMouseY(0) - y(key)
      
    Case #PB_Event_RightClick
      ligne = (ligne + 1) & 1  
      Debug ligne
  EndSelect

  x(key)=WindowMouseX(0) - mx
  y(key)=WindowMouseY(0) - my

  If synchro=1            ; Juste une gruge pour bouger les points, rien à voir avec la courbe.
    x(1)=x(0) : y(1)=y(0)
    x(2)=x(0) : y(2)=y(0)
    x(nombre-1)=x(nombre-3) : y(nombre-1)=y(nombre-3)
    x(nombre-2)=x(nombre-3) : y(nombre-2)=y(nombre-3)
  EndIf

  StartDrawing(ImageOutput(0))
  Box(0,0,ddw-1,ddh-1,0)
  DrawingMode(4)
  For n=0 To nombre-1   ; On trace les cercles...
    If n=key : Circle(x(n),y(n),5,cr) : Else : Circle(x(n),y(n),5,cw) : EndIf
  Next
  For n=0 To nombre-4   ; On trace la bspline
    bspline(x(n),y(n),x(n+1),y(n+1),x(n+2),y(n+2),x(n+3),y(n+3),cw,ligne)
  Next
  StopDrawing()
  
  StartDrawing(WindowOutput(0))
  DrawImage(img,0,0)
  StopDrawing()
  
Until Event = #PB_Event_CloseWindow Or quit = 1

Re: Tout sur les Bspline

Publié : lun. 19/mai/2025 19:06
par SPH
manababel a écrit : lun. 19/mai/2025 19:01( attention programme buggé )
Justement, où est le bug ?!!

Car ce code est court et facile a comprendre. Mais comme il date de plus de 10 ans, je ne me rappelle plus de la mécanique du code...

8O

Re: Tout sur les Bspline

Publié : mar. 20/mai/2025 19:05
par SPH
J'ai corrigé le premier post.
Si vous vouez choisir une situation particuliere, donnez des valeurs a la place des random.

Re: Tout sur les Bspline

Publié : lun. 26/mai/2025 13:29
par falsam
Un simple "Enjoy" pour expliquer ton code c'est insuffisant. J'ai déplacé ton code de la section tutoriel vers la section débutant.

Ton code ne fonctionne pas avec la version 6.20 de PureBasic et je ne suis pas certain que tout va bien avec la version 6.21 actuellement en phase Beta.