BezierGadget

Programmation d'applications complexes
Avatar de l’utilisateur
ZapMan
Messages : 460
Inscription : ven. 13/févr./2004 23:14
Localisation : France
Contact :

BezierGadget

Message par ZapMan »

Plusieurs fonctions de SoundEditor (le filtre volume, par exemple) vont se voir ajouter la possibilité d'être modulées à l'aide d'une courbe. J'ai donc pondu des procédures standards qui permettent de dessiner et de modifier les courbes de Bezier. En fait, j'ai repris ce que j'avais fait pour le synthétiseur et je l'ai amélioré (le code était assez crade).

Tant que j'y étais, j'ai ajouté la possibilité de gérer des Bezier standards. Ca pourra donc servir à tous ceux qui veulent faire un module de dessin avec ce type de courbe.

Je n'ai jamais bricolé les librairies et je ne saurais pas le mettre sous cette forme, mais si ça tente quelqu'un...

Code : Tout sélectionner

; Bezier Gadget
; By Zapman


#PaleYellow=255+ (250*256) + (220*256*256)
#PaleBlue  =220+ (255*256) + (255*256*256)
#Violet    =240 + (30*256) + (170*256*256)
#WM_MOUSEWHEEL=522

;
#MaxBPoints = 100
;
Structure BezierPoint
  x.l
  y.l
  t1x.l
  t1y.l
  t2x.l
  t2y.l
EndStructure
;
Dim DBPoints.BezierPoint(#MaxBPoints)
;
Structure BezierArea
  RefNumber.l
  leftP.l
  topP.l
  RightP.l
  BottomP.l
  BPoints.BezierPoint[#MaxBPoints]
  SelectedPoint.l
  OutOfAreaCursor.l
  InsideAreaCursor.l
  MoveCursor.l
  Image.l
  SDrawing.l
  BezierCallBack.l
  TimeType.l
  OnPoint.l
  OnLTangeante.l
  OnRTangeante.l
  SymTangeante.l
  ForgetBS.l
EndStructure

Declare AddBezierPoint (*Area.BezierArea,x,y,t1x,t1y,t2x,t2y)
Declare BezierGadget (NRef,*Area.BezierArea,vleft,vtop,vright,vbottom,TimeType,BezierCallBack)
Declare RedrawBezier (*Area.BezierArea)
Declare BezierCurve(x1,y1,x2,y2,x3,y3,x4,y4,DWide,color)
Declare ManageBezierEvents (*Area.BezierArea,WE)
Declare DestroyBezierGadget (*Area.BezierArea)


;
Procedure BezierCallBack1 (*Area.BezierArea)
  ; modifiez cette procédure si vous voulez dessinez un fond derrière votre courbe de Bezier
  Box(0,0,*Area\RightP-*Area\LeftP,*Area\BottomP-*Area\TopP,#PaleYellow)
  Line (0,((*Area\BottomP-*Area\TopP)/2),*Area\RightP-*Area\LeftP,0,#Violet)
EndProcedure 
;
;
Procedure BezierCallBack2 (*Area.BezierArea)
  ; modifiez cette procédure si vous voulez dessinez un fond derrière votre courbe de Bezier
  Box(0,0,*Area\RightP-*Area\LeftP,*Area\BottomP-*Area\TopP,#PaleBlue)
  Circle(150,100,30,#PaleYellow)
  Circle(350,130,30,255)
EndProcedure 

#NoWindow = 1
hwd = OpenWindow(#NoWindow, 0, 0, 510, 510,  #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar| #PB_Window_TitleBar | #PB_Window_ScreenCentered ,"BezierGadget Demo")
If hwd
  If CreateGadgetList(WindowID())
    ;- Gadget Constants
    
    #WDrawing = 479
    #HDrawing = 188
   
    #THelp      = 2
    #BSaw       = 3
    #BSinus     = 4
    #BRTime     = 5
    #BRNormal   = 6
    #TTitle1    = 7
    #TTitle2    = 8
    
    #Bezier1     = 10
    #Bezier2     = 11
    ;


    ButtonGadget(#BSaw     ,  13, 225, 70, 20, "Saw")
    ButtonGadget(#BSinus   ,  13, 250, 70, 20, "Sinus")
    OptionGadget(#BRTime   , 183, 225, 70, 20, "Time")
    OptionGadget(#BRNormal , 280, 225, 70, 20, "Normal")
    SetGadgetState (#BRTime,1)
    TimeOrNormal = 1

    BezierGadget (#Bezier1,BezierArea1.BezierArea,13,27,#WDrawing+13,#HDrawing+27,TimeOrNormal,@BezierCallBack1())
    tx.s= "Bouton droit : crée/modifie les tangeantes - Roue de souris : défilement"
    tx + Chr(13)+ "Appuyez sur majuscule pour avoir des tangeantes symétriques."
    tx + Chr(13)+ "Déplacez le point sélectionné avec les touches 'flèche'."
    tx + Chr(13)+ "<- (backspace) supprime le point sélectionné."
    TextGadget(#THelp, 83, #HDrawing+55, #WDrawing, 60, tx, #PB_Text_Center)
    TextGadget(#TTitle1, 13, 5, 80, 20, "Time/Normal")
    TextGadget(#TTitle2, 13, 290, 80, 20, "Normal")
    
    AddBezierPoint (BezierArea1,0,-#HDrawing*1/4,-#WDrawing*1/4,0,#WDrawing*1/4,0)
    AddBezierPoint (BezierArea1,#WDrawing/2,#HDrawing*1/4,-#WDrawing*1/4,0,#WDrawing*1/4,0)

    RedrawBezier(BezierArea1)
    
    BezierGadget (#Bezier2,BezierArea2.BezierArea,13,310,#WDrawing+13,#HDrawing+310,0,@BezierCallBack2())
    AddBezierPoint (BezierArea2,#WDrawing/2,-#HDrawing*1/4,-#WDrawing*1/4,0,#WDrawing*1/4,0)
    AddBezierPoint (BezierArea2,#WDrawing/2-150,#HDrawing*1/4,-#WDrawing*1/4,0,#WDrawing*1/4,0)
    AddBezierPoint (BezierArea2,#WDrawing/2+150,-#HDrawing*1/4,0,0,0,0)
    AddBezierPoint (BezierArea2,#WDrawing/2+150,#HDrawing*1/4,0,0,0,0)
    RedrawBezier(BezierArea2)

    ;
    QuitWSynthetiser = 0
    cont = 0

    Repeat
      Delay(10)
      WE = WindowEvent()
      If EventWindowID()<>#NoWindow
        WE = 0
      Else
        ManageBezierEvents (BezierArea1,WE)
        ManageBezierEvents (BezierArea2,WE)
      EndIf 

      If WE = #PB_EventCloseWindow
        Quit = 1
      EndIf
      If WE = #PB_EventGadget
                
        Select EventGadgetID()

          Case #BSinus
            BHigh = BezierArea1\BottomP-BezierArea1\TopP
            BWide = BezierArea1\RightP -BezierArea1\LeftP
            BezierArea1\BPoints[1]\x=-1
            AddBezierPoint (BezierArea1,0,-BHigh *1/4,-BWide*1/4,0,BWide*1/4,0)
            AddBezierPoint (BezierArea1,BWide/2,BHigh *1/4,-BWide*1/4,0,BWide*1/4,0)
            RedrawBezier (BezierArea1)
          Case #BSaw
            BHigh = BezierArea1\BottomP-BezierArea1\TopP
            BWide = BezierArea1\RightP -BezierArea1\LeftP
            BezierArea1\BPoints[1]\x=-1
            AddBezierPoint (BezierArea1,BWide/2,-BHigh *1/4,0,0,0,0)
            AddBezierPoint (BezierArea1,BWide/2+1,BHigh *1/4,0,0,0,0)
            RedrawBezier (BezierArea1)
          Case #BRTime
            TimeOrNormal = 1
            DestroyBezierGadget (BezierArea1)
            BezierGadget (#Bezier1,BezierArea1,13,27,#WDrawing+13,#HDrawing+27,TimeOrNormal,@BezierCallBack1())

            AddBezierPoint (BezierArea1,0,-#HDrawing*1/4,-#WDrawing*1/4,0,#WDrawing*1/4,0)
            AddBezierPoint (BezierArea1,#WDrawing/2,#HDrawing*1/4,-#WDrawing*1/4,0,#WDrawing*1/4,0)
            RedrawBezier (BezierArea1)
          Case #BRNormal
            TimeOrNormal = 0
            DestroyBezierGadget (BezierArea1)
            BezierGadget (#Bezier1,BezierArea1,13,27,#WDrawing+13,#HDrawing+27,TimeOrNormal,@BezierCallBack2())

            AddBezierPoint (BezierArea1,#WDrawing/2,-#HDrawing*1/4,-#WDrawing*1/4,0,#WDrawing*1/4,0)
            AddBezierPoint (BezierArea1,#WDrawing/2,#HDrawing*1/4,-#WDrawing*1/4,0,#WDrawing*1/4,0)
            RedrawBezier (BezierArea1)
        EndSelect 
      EndIf

    Until Quit 

    CloseWindow(#NoWindow)
  EndIf
EndIf






Procedure AddBezierPoint (*Area.BezierArea,x,y,t1x,t1y,t2x,t2y)
  ct = 1
  While *Area\BPoints[ct]\x<>-1 And ct<#MaxBPoints
    ct + 1
  Wend
  If *Area\BPoints[ct]\x=-1
    *Area\BPoints[ct]\x=x
    *Area\BPoints[ct]\y=y
    *Area\BPoints[ct]\t1x=t1x
    *Area\BPoints[ct]\t1y=t1y
    *Area\BPoints[ct]\t2x=t2x
    *Area\BPoints[ct]\t2y=t2y
    If ct<#MaxBPoints
      *Area\BPoints[ct+1]\x=-1
    EndIf
    *Area\SelectedPoint = x
    result = 1
  Else
    result = 0
  EndIf
  ProcedureReturn result 
EndProcedure 
;
Procedure BezierGadget (NRef,*Area.BezierArea,vleft,vtop,vright,vbottom,TimeType,BezierCallBack)
  *Area\RefNumber = NRef
  *Area\LeftP = vleft
  *Area\topP    = vtop
  *Area\RightP  = vright 
  *Area\BottomP = vbottom 
  *Area\BPoints[1]\x=-1
  *Area\SelectedPoint=-1
  *Area\OutOfAreaCursor=LoadCursor_(0, #IDC_ARROW)
  *Area\InsideAreaCursor=LoadCursor_(0, #IDC_CROSS)
  *Area\MoveCursor=LoadCursor_(0, #IDC_SIZEALL)
  *Area\Image = CreateImage(NRef,vright-vleft,vbottom-vtop)
  *Area\SDrawing = ImageGadget(NRef, vleft, vtop, vright-vleft, vbottom-vtop,*Area\Image, #PB_Image_Border)
  *Area\BezierCallBack=BezierCallBack
  *Area\TimeType = TimeType
  *Area\OnPoint = 0
  *Area\OnLTangeante = 0
  *Area\OnRTangeante = 0
  *Area\SymTangeante = 0
  *Area\ForgetBS = 0
  #BViolet    =240 + (30*256) + (170*256*256)
  ProcedureReturn 1
EndProcedure
;
Procedure DestroyBezierGadget (*Area.BezierArea)
  DestroyCursor_(*Area\OutOfAreaCursor)
  DestroyCursor_(*Area\InsideAreaCursor)
  DestroyCursor_(*Area\MoveCursor)
  FreeGadget (NRef)
EndProcedure 
;
Procedure BezierCurve(x1,y1,x2,y2,x3,y3,x4,y4,DWide,color)
  ; D'aprés une procédure de Rob, du Robsite German forum
  ; From a procedure of Rob - Robsite German forum
  i.f = 0
  oldx=x1 
  oldy=y1 
  cx.f=3*x2 
  bx.f=3*(x4+x3-x2-x1)-cx
  ax.f=x4-x1-cx-bx 
  cy.f=3*y2 
  by.f=3*(y4+y3-y2-y1)-cy 
  ay.f=y4-y1-cy-by 
  While i.f < 1 
    i+0.05 
    x=((ax*i+bx)*i+cx)*i+x1 
    y=((ay*i+by)*i+cy)*i+y1
    If i>0
      If x>DWide
        If oldx<DWide
          LineXY(oldx,oldy,x,y,color) 
        EndIf 
        xb=x-DWide
        oldxb=oldx-DWide
      Else
        xb=x
        oldxb=oldx
      EndIf
      yb=y
      oldyb=oldy
      If xb<0
        xb=0
      EndIf
      If oldxb<0
        If x<>oldx
          ps=oldxb*(y-oldy)/(x-oldx)
          oldyb=oldyb-ps
        Else
          oldyb=yb
        EndIf 
        oldxb=0
      EndIf 
      LineXY(oldxb,oldyb,xb,yb,color)
    EndIf  
    oldx=x 
    oldy=y 
  Wend 
EndProcedure
;
Procedure RedrawBezier (*Area.BezierArea) 
  change = *Area\TimeType 
  While change                ; Sort the array - Trie le tableau 
    change = 0 
    For ct=1 To #MaxBPoints-1 
      If *Area\BPoints[ct+1]\x=-1 Or *Area\BPoints[ct]\x=-1 
        If *Area\BPoints[ct]\x=-1 : ctend = ct : Else : ctend = ct+1 : EndIf 
        ct=#MaxBPoints 
      Else 
        If *Area\BPoints[ct+1]\x<*Area\BPoints[ct]\x 
          change = 1 
          mempoint.BezierPoint\x=*Area\BPoints[ct]\x 
          mempoint\y  =*Area\BPoints[ct]\y 
          mempoint\t1x=*Area\BPoints[ct]\t1x 
          mempoint\t1y=*Area\BPoints[ct]\t1y 
          mempoint\t2x=*Area\BPoints[ct]\t2x 
          mempoint\t2y=*Area\BPoints[ct]\t2y 
          *Area\BPoints[ct]\x  = *Area\BPoints[ct+1]\x 
          *Area\BPoints[ct]\y  = *Area\BPoints[ct+1]\y 
          *Area\BPoints[ct]\t1x= *Area\BPoints[ct+1]\t1x 
          *Area\BPoints[ct]\t1y= *Area\BPoints[ct+1]\t1y 
          *Area\BPoints[ct]\t2x= *Area\BPoints[ct+1]\t2x 
          *Area\BPoints[ct]\t2y= *Area\BPoints[ct+1]\t2y 
          *Area\BPoints[ct+1]\x  = mempoint\x 
          *Area\BPoints[ct+1]\y  = mempoint\y 
          *Area\BPoints[ct+1]\t1x= mempoint\t1x 
          *Area\BPoints[ct+1]\t1y= mempoint\t1y 
          *Area\BPoints[ct+1]\t2x= mempoint\t2x 
          *Area\BPoints[ct+1]\t2y= mempoint\t2y 
          If *Area\SelectedPoint = ct 
            *Area\SelectedPoint = ct + 1
            *Area\OnPoint = ct + 1
            *Area\OnLTangeante = ct + 1
            *Area\OnRTangeante = ct + 1
          Else 
            If *Area\SelectedPoint = ct+1 
              *Area\SelectedPoint = ct
              *Area\OnPoint = ct
              *Area\OnLTangeante = ct
              *Area\OnRTangeante = ct
            EndIf 
          EndIf 
        EndIf 
      EndIf 
    Next 
  Wend 
  DWide = *Area\RightP-*Area\LeftP 
  DHigh = *Area\BottomP-*Area\TopP 
  If *Area\TimeType 
    For ct=1 To #MaxBPoints-1 ; limit tangeantes lenght 
      If *Area\BPoints[ct]\x<>-1 
        If ct>1 
          If *Area\BPoints[ct]\t1x+*Area\BPoints[ct]\x<*Area\BPoints[ct-1]\x 
            *Area\BPoints[ct]\t1x=*Area\BPoints[ct-1]\x-*Area\BPoints[ct]\x 
          EndIf 
        Else 
          If *Area\BPoints[1]\t1x+*Area\BPoints[1]\x<*Area\BPoints[ctend-1]\x-DWide 
            *Area\BPoints[1]\t1x=*Area\BPoints[ctend-1]\x-DWide -*Area\BPoints[1]\x 
          EndIf 
        EndIf 
        If *Area\BPoints[ct+1]\x<>-1 
          If *Area\BPoints[ct]\t2x+*Area\BPoints[ct]\x>*Area\BPoints[ct+1]\x 
            *Area\BPoints[ct]\t2x=*Area\BPoints[ct+1]\x-*Area\BPoints[ct]\x 
          EndIf 
        Else 
          If *Area\BPoints[ct]\t2x+*Area\BPoints[ct]\x>*Area\BPoints[1]\x+DWide 
            *Area\BPoints[ct]\t2x=*Area\BPoints[1]\x+DWide -*Area\BPoints[ct]\x 
          EndIf 
          ct=#MaxBPoints 
        EndIf 
      EndIf 
    Next 
  EndIf 
  UseImage(*Area\RefNumber) 
  StartDrawing(ImageOutput()) 
  If *Area\BezierCallBack 
    CallFunctionFast(*Area\BezierCallBack,*Area) 
  Else 
    Box(0,0,*Area\RightP-*Area\LeftP,*Area\BottomP-*Area\TopP,#WHITE) 
  EndIf 
  For ct=1 To #MaxBPoints 
    If *Area\BPoints[ct]\x=-1 
      ctend=ct-1 
      ct=#MaxBPoints 
    Else 
      If ct=*Area\SelectedPoint 
        DrawingMode(0) 
      Else 
        DrawingMode(4) 
      EndIf 
      Box(*Area\BPoints[ct]\x-2,*Area\BPoints[ct]\y+(DHigh/2)-2,5,5,0) 
      If *Area\BPoints[ct]\t1x Or *Area\BPoints[ct]\t1y 
        DrawingMode(4) 
        Circle (*Area\BPoints[ct]\x+*Area\BPoints[ct]\t1x,*Area\BPoints[ct]\y+*Area\BPoints[ct]\t1y+(DHigh/2),3,#Red) 
        xt = *Area\BPoints[ct]\x+*Area\BPoints[ct]\t1x 
        yt = *Area\BPoints[ct]\y+*Area\BPoints[ct]\t1y+(DHigh/2) 
        If xt<0 
          ps=xt**Area\BPoints[ct]\t1y/(*Area\BPoints[ct]\x-xt) 
          yt=yt+ps 
          xt=0 
        EndIf 
        LineXY(*Area\BPoints[ct]\x,*Area\BPoints[ct]\y+(DHigh/2),xt,yt,#BViolet) 
      EndIf 
      If *Area\BPoints[ct]\t2x Or *Area\BPoints[ct]\t2y 
        DrawingMode(4) 
        Circle (*Area\BPoints[ct]\x+*Area\BPoints[ct]\t2x,*Area\BPoints[ct]\y+*Area\BPoints[ct]\t2y+(DHigh/2),3,#Red) 
        LineXY(*Area\BPoints[ct]\x,*Area\BPoints[ct]\y+(DHigh/2),*Area\BPoints[ct]\x+*Area\BPoints[ct]\t2x,*Area\BPoints[ct]\y+*Area\BPoints[ct]\t2y+(DHigh/2),#BViolet) 
      EndIf 
      If ct>1 
        BezierCurve(*Area\BPoints[ct-1]\x,*Area\BPoints[ct-1]\y+(DHigh/2),*Area\BPoints[ct-1]\t2x,*Area\BPoints[ct-1]\t2y,*Area\BPoints[ct]\t1x,*Area\BPoints[ct]\t1y,*Area\BPoints[ct]\x,*Area\BPoints[ct]\y+(DHigh/2),DWide,0) 
      EndIf 
    EndIf 
  Next 
  If ctend And *Area\TimeType 
    BezierCurve(*Area\BPoints[ctend]\x,*Area\BPoints[ctend]\y+(DHigh/2),*Area\BPoints[ctend]\t2x,*Area\BPoints[ctend]\t2y,*Area\BPoints[1]\t1x,*Area\BPoints[1]\t1y,*Area\BPoints[1]\x+DWide,*Area\BPoints[1]\y+(DHigh/2),DWide,0) 
  EndIf 
  StopDrawing() 
  SetGadgetState(*Area\RefNumber, UseImage(*Area\RefNumber)) 
EndProcedure 
; 
Procedure ManageBezierEvents (*Area.BezierArea,WE) 
  GetCursorPos_(@MP.Point) 
  MP\x = MP\x-2 
  MP\y = MP\y-2 
  GetWindowRect_(*Area\SDrawing,@re.RECT) 
  BHigh = *Area\BottomP-*Area\TopP 
  BWide = *Area\RightP -*Area\LeftP 
  re\right  =re\left  + BWide 
  re\bottom =re\top   + BHigh 
  If PtInRect_(re,MP\x,MP\y) 
    MO = 1 
  Else 
    MO = 0 
  EndIf 
  MP\x = MP\x - re\left 
  MP\y = MP\y - re\top 
  If GetAsyncKeyState_(#VK_LBUTTON) Or GetAsyncKeyState_(#VK_RBUTTON) 
    If GetAsyncKeyState_(#VK_LBUTTON) And GetAsyncKeyState_(#VK_CONTROL)=0 
      LBUTTONDOWN = 1 
      RBUTTONDOWN = 0 
    Else 
      RBUTTONDOWN = 1 
    EndIf 
    If MO 
      *Area\ForgetBS = 0 
    Else 
      *Area\ForgetBS = 1 
    EndIf 
  Else 
    RBUTTONDOWN = 0 
    LBUTTONDOWN = 0 
    *Area\OnPoint = 0 
    *Area\OnLTangeante = 0 
    *Area\OnRTangeante = 0 
    *Area\SymTangeante = 0 
  EndIf 
  ; 
  mp\y=mp\y-(BHigh /2) 
  ; 
  If MO 
    NCurs = *Area\InsideAreaCursor 
    ct = 0
    If *Area\OnPoint=0 And *Area\OnLTangeante=0 and *Area\OnRTangeante=0
      While *Area\BPoints[ct]\x<>-1 And ct<#MaxBPoints 
        If Abs(mp\x-*Area\BPoints[ct]\x)<5 And Abs(mp\y-*Area\BPoints[ct]\y)<5 
          NCurs = *Area\MoveCursor 
          If LBUTTONDOWN 
            *Area\OnPoint = ct 
          ElseIf RBUTTONDOWN 
            *Area\OnLTangeante = ct ; will reset the both tangeantes to zero 
            *Area\OnRTangeante = ct 
          EndIf
        EndIf 
        If Abs(mp\x-(*Area\BPoints[ct]\x+*Area\BPoints[ct]\t1x))<5 And Abs(mp\y-(*Area\BPoints[ct]\y+*Area\BPoints[ct]\t1y))<5 
          NCurs = *Area\MoveCursor 
          If LBUTTONDOWN Or RBUTTONDOWN 
            *Area\OnLTangeante = ct 
          EndIf 
        EndIf 
        If Abs(mp\x-(*Area\BPoints[ct]\x+*Area\BPoints[ct]\t2x))<5 And Abs(mp\y-(*Area\BPoints[ct]\y+*Area\BPoints[ct]\t2y))<5 
          NCurs = *Area\MoveCursor 
          If LBUTTONDOWN Or RBUTTONDOWN 
            *Area\OnRTangeante = ct 
          EndIf 
        EndIf 
        ct + 1 
      Wend
    EndIf 
    If *Area\OnPoint Or *Area\OnLTangeante Or *Area\OnRTangeante
      If *Area\OnLTangeante = *Area\OnRTangeante 
        *Area\SymTangeante = 1 
        If mp\x>*Area\BPoints[*Area\OnLTangeante]\x+*Area\BPoints[*Area\OnLTangeante]\t1x 
          *Area\OnLTangeante = 0 
        Else 
          *Area\OnRTangeante = 0 
        EndIf 
      EndIf 
      If *Area\TimeType 
        If *Area\OnLTangeante And mp\x>*Area\BPoints[*Area\OnLTangeante]\x 
          *Area\OnRTangeante = *Area\OnLTangeante 
          *Area\OnLTangeante = 0 
        EndIf 
        If *Area\OnRTangeante And mp\x<*Area\BPoints[*Area\OnRTangeante]\x 
          *Area\OnLTangeante = *Area\OnRTangeante 
          *Area\OnRTangeante = 0 
        EndIf 
      EndIf 
      If *Area\OnPoint 
        *Area\BPoints[*Area\OnPoint]\x=mp\x 
        *Area\BPoints[*Area\OnPoint]\y=mp\y 
        *Area\SelectedPoint = *Area\OnPoint 
        RedrawBezier (*Area) 
      ElseIf *Area\OnLTangeante 
        *Area\BPoints[*Area\OnLTangeante]\t1x=mp\x-*Area\BPoints[*Area\OnLTangeante]\x 
        *Area\BPoints[*Area\OnLTangeante]\t1y=mp\y-*Area\BPoints[*Area\OnLTangeante]\y 
        If *Area\SymTangeante Or GetAsyncKeyState_(#VK_SHIFT) 
          *Area\BPoints[*Area\OnLTangeante]\t2x=-*Area\BPoints[*Area\OnLTangeante]\t1x 
          *Area\BPoints[*Area\OnLTangeante]\t2y=-*Area\BPoints[*Area\OnLTangeante]\t1y 
        EndIf 
        *Area\SelectedPoint = OnLTangeante 
        RedrawBezier (*Area) 
      ElseIf *Area\OnRTangeante 
        *Area\BPoints[*Area\OnRTangeante ]\t2x=mp\x-*Area\BPoints[*Area\OnRTangeante ]\x 
        *Area\BPoints[*Area\OnRTangeante ]\t2y=mp\y-*Area\BPoints[*Area\OnRTangeante ]\y 
        If *Area\SymTangeante Or GetAsyncKeyState_(#VK_SHIFT) 
          *Area\BPoints[*Area\OnRTangeante]\t1x=-*Area\BPoints[*Area\OnRTangeante]\t2x 
          *Area\BPoints[*Area\OnRTangeante]\t1y=-*Area\BPoints[*Area\OnRTangeante]\t2y 
        EndIf 
        *Area\SelectedPoint = *Area\OnRTangeante 
        RedrawBezier (*Area) 
      EndIf 
    Else 
      If (LBUTTONDOWN Or RBUTTONDOWN)
        ct = 0
        While *Area\BPoints[ct]\x<>-1 And ct<#MaxBPoints : ct+1 : Wend
        If *Area\BPoints[ct]\x=-1
          NCurs = *Area\MoveCursor 
          *Area\BPoints[ct]\x=mp\x
          *Area\BPoints[ct]\y=mp\y 
          *Area\BPoints[ct]\t1x=0 
          *Area\BPoints[ct]\t1y=0 
          *Area\BPoints[ct]\t2x=0 
          *Area\BPoints[ct]\t2y=0 
          *Area\SelectedPoint = ct 
          If LBUTTONDOWN 
            *Area\OnPoint = ct 
          Else 
            *Area\OnLTangeante = ct 
            *Area\OnRTangeante = ct 
          EndIf 
          If ct<#MaxBPoints 
            *Area\BPoints[ct+1]\x=-1 
          EndIf 
          RedrawBezier (*Area)
        EndIf 
      EndIf 
    EndIf 
  Else 
    NCurs = *Area\OutOfAreaCursor 
  EndIf 
  If NCurs<>*Area\OutOfAreaCursor 
    SetCursor_(NCurs) 
  EndIf 
  ; 
  If WE = #WM_MOUSEWHEEL And *Area\TimeType And *Area\ForgetBS=0 
    s.l=-(EventwParam() >> 16)/20 
    For ct=1 To #MaxBPoints-1 
      If *Area\BPoints[ct]\x=-1 
        ct=#MaxBPoints 
      Else 
        mx = *Area\BPoints[ct]\x 
        *Area\BPoints[ct]\x=*Area\BPoints[ct]\x+s 
        If *Area\BPoints[ct]\x<0 
          *Area\BPoints[ct]\x=*Area\BPoints[ct]\x+BWide 
        EndIf 
        If *Area\BPoints[ct]\x>BWide 
          *Area\BPoints[ct]\x=*Area\BPoints[ct]\x-BWide 
        EndIf 
      EndIf 
    Next 
    RedrawBezier (*Area) 
  EndIf 
  If WE = #WM_KEYDOWN 
    ; Shortcuts - Gestion des touches rapides flèches et Backspace 
    If *Area\ForgetBS=0 And *Area\SelectedPoint>-1 
      If GetAsyncKeyState_(#VK_UP) 
        *Area\BPoints[*Area\SelectedPoint]\y-1 
        If *Area\BPoints[*Area\SelectedPoint]\y<(-BHigh/2+1) 
          *Area\BPoints[*Area\SelectedPoint]\y = -BHigh/2 
        EndIf 
        RedrawBezier(*Area) 
      EndIf 
      If GetAsyncKeyState_(#VK_DOWN) 
        *Area\BPoints[*Area\SelectedPoint]\y+1 
        If *Area\BPoints[*Area\SelectedPoint]\y>(BHigh/2-1) 
          *Area\BPoints[*Area\SelectedPoint]\y = BHigh/2 
        EndIf 
        RedrawBezier(*Area) 
      EndIf 
      If GetAsyncKeyState_(#VK_RIGHT) 
        *Area\BPoints[*Area\SelectedPoint]\x+1 
        If *Area\BPoints[*Area\SelectedPoint]\x>(BWide-1) 
          *Area\BPoints[*Area\SelectedPoint]\x =BWide 
        EndIf 
        RedrawBezier(*Area) 
      EndIf 
      If GetAsyncKeyState_(#VK_LEFT) 
        *Area\BPoints[*Area\SelectedPoint]\x-1 
        If *Area\BPoints[*Area\SelectedPoint]\x<1 
          *Area\BPoints[*Area\SelectedPoint]\x = 0 
        EndIf 
        RedrawBezier(*Area) 
      EndIf 
      If GetAsyncKeyState_(#VK_BACK) Or GetAsyncKeyState_(#VK_CLEAR) 
        ;- ClearPoint 
        For ct=*Area\SelectedPoint To #MaxBPoints-1 
          If ct >1 Or *Area\TimeType=0 Or *Area\BPoints[ct+1]\x>0 
            *Area\BPoints[ct]\x=*Area\BPoints[ct+1]\x 
            *Area\BPoints[ct]\y=*Area\BPoints[ct+1]\y 
            *Area\BPoints[ct]\t1x=*Area\BPoints[ct+1]\t1x 
            *Area\BPoints[ct]\t1y=*Area\BPoints[ct+1]\t1y 
            *Area\BPoints[ct]\t2x=*Area\BPoints[ct+1]\t2x 
            *Area\BPoints[ct]\t2y=*Area\BPoints[ct+1]\t2y 
            If *Area\BPoints[ct]\x=-1 
              ct = #MaxBPoints 
            EndIf 
          EndIf 
        Next 
        RedrawBezier(*Area) 
      EndIf 
    EndIf 
  EndIf 
EndProcedure  
Je viens de rajouter cette fonction (utilisable uniquement pour les "Time Bezier"):

Code : Tout sélectionner

Procedure CalcYFromXTimeBezier(xr,*area.BezierArea)
  DWide = *Area\RightP-*Area\LeftP
  DHigh = *Area\BottomP-*Area\TopP
  If *Area\BPoints[1]\x<>-1 And xr>-1 And xr<(DWide+1)
    For ct=1 To #MaxBPoints
      If *Area\BPoints[ct+1]\x=-1
        xend=*Area\BPoints[ct]\x
        ctend = ct
        ct = #MaxBPoints
      EndIf 
    Next
    ct = 1
    While *Area\BPoints[ct]\x<xr And ct<ctend : ct + 1 : Wend
    If ct = 1
      ctd = ctend
      ctf = ct
    ElseIf *Area\BPoints[ct]\x<xr
      ctd = ctend
      ctf = 1
    Else
      ctd = ct-1
      ctf = ct
    EndIf
    x1 = *Area\BPoints[ctd]\x
    y1 = *Area\BPoints[ctd]\y+(DHigh/2)
    x2 = *Area\BPoints[ctd]\t2x
    y2 = *Area\BPoints[ctd]\t2y
    x3 = *Area\BPoints[ctf]\t1x
    y3 = *Area\BPoints[ctf]\t1y
    x4 = *Area\BPoints[ctf]\x
    y4 = *Area\BPoints[ctf]\y+(DHigh/2)
    If ct = 1
      x1 = DWide - x1
    ElseIf *Area\BPoints[ct]\x<xr
      x4 + DWide
    EndIf
    cx.f=3*x2 
    bx.f=3*(x4+x3-x2-x1)-cx
    ax.f=x4-x1-cx-bx 
    cy.f=3*y2 
    by.f=3*(y4+y3-y2-y1)-cy 
    ay.f=y4-y1-cy-by
    lowlim.f=0
    Highlim.f = 1
    cont = 1
    While cont
      i.f=(Highlim-lowlim)/2+lowlim
      x=((ax*i+bx)*i+cx)*i+x1
      If xr>x
        lowlim=i
      ElseIf xr<x
        Highlim=i
      Else 
        cont = 0
        y=((ay*i+by)*i+cy)*i+y1
      EndIf
    Wend
    ProcedureReturn y
  EndIf
EndProcedure
Dernière modification par ZapMan le ven. 27/août/2004 5:19, modifié 1 fois.
Tout obstacle est un point d'appui potentiel.

Bibliothèques PureBasic et autres codes à télécharger :https://www.editions-humanis.com/downlo ... ads_FR.htm
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

waoou ! hight tech !! trop fort ! (pour moi) :D
Le Soldat Inconnu
Messages : 4312
Inscription : mer. 28/janv./2004 20:58
Localisation : Clermont ferrand OU Olsztyn
Contact :

Message par Le Soldat Inconnu »

extra :D
Je ne suis pas à moitié Polonais mais ma moitié est polonaise ... Vous avez suivi ?

[Intel quad core Q9400 2.66mhz, ATI 4870, 4Go Ram, XP (x86) / 7 (x64)]
Oliv
Messages : 2117
Inscription : mer. 21/janv./2004 18:39

Message par Oliv »

Bravo :D
Dr. Dri
Messages : 2527
Inscription : ven. 23/janv./2004 18:10

Message par Dr. Dri »

Impressionant !
la seule chose dommage est que lorsqu'on sélectionne un point rouge et qu'on le bouge, si on a le mahleur d'en survoller un autre (peut importe la couleur) ca le sélectionne (pas agréable)... Pour les points nirs je comprend vu que le but est de les voirs dans le temps, la courbe en x ne peut pas avoir deux y... mais pour les points rouges, pas cool


Dri :10:
garzul
Messages : 683
Inscription : mer. 26/mai/2004 0:33

Message par garzul »

:D Genial bien que je n'y comprend pas grand chose bravo pour le boss j'ai declarer ZAPMAN.!!!!
Avatar de l’utilisateur
ZapMan
Messages : 460
Inscription : ven. 13/févr./2004 23:14
Localisation : France
Contact :

Message par ZapMan »

Dr. Dri a écrit :la seule chose dommage est que lorsqu'on sélectionne un point rouge et qu'on le bouge, si on a le mahleur d'en survoller un autre (peut importe la couleur) ca le sélectionne (pas agréable)...
Fixé (à la super-glue + 2 vis... ça devrait tenir)
Tout obstacle est un point d'appui potentiel.

Bibliothèques PureBasic et autres codes à télécharger :https://www.editions-humanis.com/downlo ... ads_FR.htm
Répondre