## Vector drawing : rotation and parenting

Just starting out? Need help? Post your questions and find answers here.
[blendman]
Enthusiast Posts: 292
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

### Vector drawing : rotation and parenting

Hi

I would like to create a "bones system" for animation, in my software Cartoon (Which use the 2D vector drawing).

So, I would like that a shape (box, circle, curve, line...) get some parameters from its "parent" and give some parameters to its children :
- position (x,y)
- rotation
- scale

For Position it's enough simple, and it's ok, even with animation.
But for rotation, I have made some tests, but it doesn't work like I want.

In my code, I would like that the yellow box rotate over the purple box (like the purple rotate over the green box...).
but I don't know how to do that.

I have though to use cos and sin, like with sprite, but I don't know how too.
So any help would be apprecied Thanks

My test :

Code: Select all

``````; 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

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
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)
VectorSourceColor(RGBA(\color\r,\color\g,\color\b,\color\a))
FillPath()
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)

x = 450
y = 300
updatecanvas()
Repeat

Repeat
Event = WaitWindowEvent(1)
Until event = 0 Or Event = #PB_Event_CloseWindow

updatecanvas()
Until Event = #PB_Event_CloseWindow
EndIf

``````
#NULL Posts: 1364
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

### Re: Vector drawing : rotation and parenting

Here is a little demo how it could work. Not sure how the object definition might be different from yours, but just something you can experiment with.
You could also replace some MoveCursor() with TranslateCoordinates() i think, that would be more in line with how the rotation is done.

Code: Select all

``````EnableExplicit
Define ww, wh, style, win, canvas, event, quit

ww=800
wh=600
style | #PB_Window_ScreenCentered

win = OpenWindow(#PB_Any, 50, 100, ww, wh, "", style)
canvas = CanvasGadget(#PB_Any, 0, 0, ww, wh)

Structure object
p.i
x.i
y.i
w.i
h.i
cx.i
cy.i
a.f
EndStructure

Dim o.object(2)
With o(0)
\p= -1 : \x = 200 : \y = 200 : \w = 100 : \h = 10 : \cx = 0 : \cy = 0 : \a = 0
EndWith
With o(1)
; for convenience in this setup we first set the rotation position relative to the parent,
; then how much the rotation position is offset from the actuall position and then the
; actual position from that..
\p=  0 : \x = 100-5 : \y = 5 : \w = 80 : \h = 40 : \cx = 20 : \cy = 20 : \a = 0
\x - \cx
\y - \cy
EndWith
With o(2)
\p=  1 : \x = 80 : \y = 40 : \w = 10 : \h = 100 : \cx = 5 : \cy = 5 : \a = 0
\x - \cx
\y - \cy
EndWith

Repeat
Repeat
event = WindowEvent()
Select event
Case #PB_Event_CloseWindow
quit = #True
Case 10
quit = #True
EndSelect
Case #PB_Event_Timer
Select EventTimer()
Case 1
Define anim
anim = ElapsedMilliseconds() / 2000

If StartVectorDrawing(CanvasVectorOutput(canvas))
VectorSourceColor(\$ffffffff)
FillVectorOutput()
Define i, currX, currY
currX = 100
currY = 100
For i=0 To ArraySize(o())
With o(i)
If i = anim
MovePathCursor(currX, currY)
AddPathCircle(0, 0, 2, 0, 360, #PB_Path_Relative)
VectorSourceColor(\$aa0000ff) ; red, parent origin
StrokePath(2)

MovePathCursor(currX, currY)
MovePathCursor(\x, \y, #PB_Path_Relative)
AddPathCircle(0, 0, 2, 0, 360, #PB_Path_Relative)
VectorSourceColor(\$aa00ff00) ; green, x/y
StrokePath(2)

MovePathCursor(currX, currY)
MovePathCursor(\x + \cx, \y + \cy, #PB_Path_Relative)
AddPathCircle(0, 0, 2, 0, 360, #PB_Path_Relative)
VectorSourceColor(\$aaff0000) ; blue, x/y + cx/cy
StrokePath(2)
EndIf

MovePathCursor(currX, currY)
MovePathCursor(\x + \cx, \y + \cy, #PB_Path_Relative)
RotateCoordinates(0, 0, \a)
MovePathCursor(-\cx, -\cy, #PB_Path_Relative)
currX = PathCursorX()
currY = PathCursorY()
Define gray
gray = 100+ i*50
VectorSourceColor(RGBA(gray, gray, gray, \$aa))
StrokePath(2)

If anim > ArraySize(o())
\a + (0.1 * (i+1))
ElseIf i = anim
Break
EndIf
EndWith
Next
StopVectorDrawing()
EndIf
EndSelect
EndSelect
Until Not event
Until quit``````
#NULL Posts: 1364
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

### Re: Vector drawing : rotation and parenting

When doing the rotation, the trick is to move to the center of rotation first, then rotate the coordinate system, and then move backwards as per the rotation center position to get the rotated origin and then draw the box.
I used a similar trick in the object setup where i basically set the rotation position first and then calculate the origin position from that (or something to that effect).
#NULL Posts: 1364
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

### Re: Vector drawing : rotation and parenting

Well, when I think about it, for a bone system it is probably more intuitive use the x/y relative-to-parent position as an anchor, that already is the center of rotation, and only move backward by the cx/cy from there to get box drawing position. For this you would leave out the x - cx (and y - cy) part in the setup and then instead of

Code: Select all

``MovePathCursor(\x + \cx, \y + \cy, #PB_Path_Relative)``
use just

Code: Select all

``MovePathCursor(\x, \y, #PB_Path_Relative)``
and the backward move stays the same. I don't know if you already had it thought out like that in your on code.
[blendman]
Enthusiast Posts: 292
Joined: Thu Apr 07, 2011 1:14 pm
Location: 3 arks
Contact:

### Re: Vector drawing : rotation and parenting

Hi

Thank you very much !!
I have tried your code and it works fine !
Now, I have to try to understand how to adapt it in my code Thanks very much again.