Vector drawing : rotation et parents

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Vector drawing : rotation et parents

Message par blendman »

salut

pour mon logiciel "Cartoon", j'essaie d'ajouter un système de "parent/enfant", autrement :
- un élément (box, circle, curve, live...) peut avoir un parent : il hérite de certaines propriétés, comme : la position, le redimensionnement et la rotation (utile pour les futures fonctions d'animation).
chaque élément qui a des "enfants" transfère donc à leur enfants ces propriétés.

Pour le parenting avec la position, c'est relativement facile. Mais pour le parenting avec rotation et la vector lib, je n'ai pas reussi à obtenir ce que j'aimerais.
Je voudrais dans cet exemple que la boite jaune tourne en son centre autour de la boite pourpre (qui elle même tourne autour de la verte en son centre sur l'exemple).

Si vous avez une idée pour ça, ça me serait fortement utile ;).

Code : Tout sélectionner

; rotation heritage parenting with lib drawing canvas
; by blendman for "Cartoon !" (open-source 2D vector software)
; pb5.73

Structure sColor
  r.a
  g.a
  b.a
  a.a
EndStructure
Structure sParent
  id.W
  Startx.w
  starty.w
EndStructure
Structure sShape
  ; position
  x.d
  y.d
  ; final position with parent heritage
  finalx.d
  finaly.d
  ; size
  w.w
  h.w
  
  ; rotation
  Rot.d
  ; final rotation with parent heritage
  finalRot.d
  ; Final rotation center
  finalRotcx.d
  finalRotcY.d

  ; color
  color.scolor
  ; center of shape
  cx.w
  cy.w
  ; parent shape
  parent.sParent
EndStructure
Global Dim shape.SShape(0)
Global nbShape=-1


Procedure AddShape(x,y,w,h,rot,color,cx,cy,parent=-1)
  nbShape+1
  i=nbshape
  ReDim shape(i)
  With shape(i)
    \x = x 
    \y = y
    \cx = cx
    \cy = cy
    \w = w
    \h = h
    \color\a = Alpha(color)
    \color\r = Red(color)
    \color\g = Green(color)
    \color\b = Blue(color)
    \Rot = rot
    \parent\id = parent
    If parent>-1
      \parent\Startx = shape(parent)\x
      \parent\Starty = shape(parent)\y
    EndIf
  EndWith
  
EndProcedure

Procedure updatecanvas()
  Static rot.d
  Static a
  
  If StartVectorDrawing(CanvasVectorOutput(0))
    
    ; background
    AddPathBox(0,0,GadgetWidth(0),GadgetHeight(0))
    VectorSourceColor(RGBA(255,255,255,255))
    FillPath()
    For i=0 To ArraySize(shape())
      
      
      ; display shapes
      With shape(i)
        ResetCoordinates()
        
        ; to calcul the parent heritage : position (x,y) and rotation (rot)
        
        ; default rotation of parent
        RotParent.d= 0
        ; get the parentID
        p_ID = \parent\id
        ; if shape has a parent, we have to add the position and rotation from this parent
        If p_ID >-1
          
          ; the finalrotation of the parent
          RotParent = shape(p_ID)\finalRot
          
          ; final position
          \finalx = shape(p_ID)\x - \parent\startX + shape(p_ID)\finalx
          \finaly = shape(p_ID)\y - \parent\starty + shape(p_ID)\finaly
          
          ; final center For rotation
          \finalRotcx = shape(p_ID)\x + shape(p_ID)\cx-(\x+\cx+\finalx) + shape(p_ID)\finalRotcx + shape(p_ID)\finalx
          \finalRotcY = shape(p_ID)\y + shape(p_ID)\cy-(\y+\cy+\finaly) + shape(p_ID)\finalRotcy + shape(p_ID)\finaly
          
        EndIf
        
        
        ; default rotation by shape : 
        \finalRot = \rot + RotParent
        
        ; change rotation for some shapes
        If i=0 
          ; we rotate the box_0
          \finalRot = \rot + rot + RotParent
          
          ; animation of the positon X (for the Shape0)
          \x +a
          If a= 0
            a=1
          EndIf
          If \x> 500
            a=-1
          Else
            If \x<=50
              If a<0  
                a=1
              EndIf
            EndIf
          EndIf 
          
        ElseIf i = 1
          ; the box_1 isn't rotated
          \finalRot = \rot + RotParent
        ElseIf i = 2
          ; the box_2 should be rotated
          ; if I do a 2nd rotation, it doesn't work
          \finalRot = \rot +RotParent 
        EndIf
        
        ; then rotate the coordinates
        If \finalRot <> 0
          ; RotateCoordinates(\x+\cx+\finalRotcx,\y+\cy+\finalRotcy,\finalRot)
          RotateCoordinates(\x+\cx+\finalx+\finalRotcx,\y+\cy+\finaly+\finalRotcy,\finalRot)
         
          If i=2
            ; doesn't work
            ; \finalRot + rot
            ; RotateCoordinates(\x+\cx,\y+\cy,\finalRot)
            
            ; doesn't work
            RotateCoordinates(\x+\cx+\finalx,\y+\cy+\finaly, Rot)
          EndIf
          
        EndIf
        
        ; display the shapes
        MovePathCursor(\x,\y)
        AddPathBox(\x+\finalx,\y+\finaly,\w,\h)
        VectorSourceColor(RGBA(\color\r,\color\g,\color\b,\color\a))
        FillPath()
        AddPathCircle(\x+\cx+\finalx,\y+\cy+\finaly,5)
        VectorSourceColor(RGBA(50,0,0,200))
        FillPath()
      EndWith
    Next
    rot+0.2
    StopVectorDrawing()
  EndIf
EndProcedure
w=1024
h=600
If OpenWindow(0, 0, 0, w, h, "VectorDrawing rotation heritage & parenting", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 0, 0, w, h)
  
  x = 450
  y = 300
  AddShape(x,y,100,80,0,RGBA(200,100,50,255),25,25) : x+100
  AddShape(x,y,150,60,0,RGBA(00,100,50,255),25,25,0) : x+100
  AddShape(x,y,120,50,0,RGBA(100,00,150,255),25,25,1): x+100
  AddShape(x,y,100,40,0,RGBA(255,255,0,255),25,25,2)
  updatecanvas()
  Repeat
    
    Repeat
      Event = WaitWindowEvent(1)
    Until event = 0 Or Event = #PB_Event_CloseWindow
    
    updatecanvas()
  Until Event = #PB_Event_CloseWindow
EndIf

merci :)