Upfront, I am not a professional in Maths and hope that the formulation of my question describes the problem well enough.

I am creating a jump'n'run game, which uses a physics engine (Box2D) and SVG Vector Graphics for rendering.

I have two things to glue together, the graphic element and its physical representation.


The whole graphic for the »world« and the character are within one single SVG File, wherein the elements are structured by groups. So there is a group for the player, therein a group for the left arm, the right arm and so forth. This sets up a hierarchical structure.

below is a simple SVG file that illustrates the basic setup:

<svg id="setup" width="428" height="428" viewBox="0 0 428 428">

   <!-- matrix A -->
   <g transform="matrix(5, 0, 0, 8, 10, 15)">
       <svg width="300" height="300">

           <!-- matrix B -->
           <g transform="matrix(1, 0, 0, 1, 2, 2)">

               <!-- matrix C -->
               <rect transform="matrix(2, 0, 0, 2, 3, 3)" id="rect"
                  x="10" y="10" width="10" height="10" 
                  style="fill:#00ff00;stroke-width:0;" />

As noted in the comments of the svg above, each element in the document tree applies a certain transformation to all its children. At rendering time the overall transformation of each element is calculated, by multiplying the matrices, beginning at the root, down to the »leave«.

In case of the <rect /> element, the resulting transformation would be: A*B*C, which is applied to all its vertices (the edges in this case).

The coordinate system for the svg has its origin at the top left, where the y-axis pointing downwards in positive direction and the units are pixels.


The physical representation of the <rect /> (which should be animated) is a rigid body and one can get its transformation in global coordinates, where the y-axis is pointing upwards in positive direction and the units are meters.


Each time (frame), after the physics engine has updated the transformation of the body, that transformation needs to be transferred to the <rect />, so that it moves analogous with the body.

In terms of matrices, there are:

G, the transform of the body, with respect to the coordinate system of the physics engine,

A, B and C, the already applied transformations of the <rect />, with respect to the coordinate system of the SVG, which should not be altered.

And there is S, what is Matrix for the coordinate transformation from the »physics world« to the »svg world«

Last but not least, there is X, the matrix I am looking for, so that I can append X to the list of transformations of the <rect />.

The solution I have for now, which is not working is this:

$$G = S * A * B * C * X$$, resolved for X yields:

$$X = C^{-1} * B^{-1} * A^{-1} * S^{-1} * G$$

I would appreciate any kind of help, since I am running out of ideas for now!

Thanks in ahead!


What is S:

Firstly: the physics engine works in meters and properly use them for pixels, what svg requires, these units need to be scaled, that is normally a value around 30 in x and y direction, but for now i will call it $s$.

Secondly: The editor I use to create the physics world (rube) places all the objects so that the center of the scene becomes the origin of the coordinate system, so the whole view needs to translated by half of its width in x-direction, and half of its height in y-direction. Let me just call them $tx$ and $ty$.

That gives this:

$$S= \begin{pmatrix} s & 0 & tx\\ 0 & -s & ty\\ 0 & 0 & 1 \end{pmatrix}$$

What is $G$:

The values are obtained by calling body.GetTransform(), what returns a b2Transform Object t , with a rotation r object member ($cosine$ and $sin$ of the actual rotation) and a translation vector p.

That gives:

$$S= \begin{pmatrix} t.r.c & -t.r.s & t.p.x\\ t.r.s & t.r.c & t.p.y\\ 0 & 0 & 1 \end{pmatrix}$$

  • $\begingroup$ Well... there are always little technicalities in situations like this. For instance, you haven't described very thoroughly to us what EXACTLY $G$ and $S$ are. Your general approach looks right, but it's hard to verify that you got it exactly right without those thorough descriptions. For all we know, you just need to replace $S^{-1}$ by $S$ in your formula, and/or $G$ by $G^{-1}$. $\endgroup$ – Dan Shved Mar 24 '14 at 12:01

To transform a vector $x$ in "rect coordinates" according to the transform $G$ which is stated in "physics coordinates", you need to first convert $x$ into "physics coordinates", then apply $G$, and finally convert back to "rect coordinates". Thus, if $T$ is the transform that converts $x$ from "rect coordinates" to "physics coordinates", you'd transform a vector $x$ by computing $T^{-1}GTx$. The matrix correspoding to $G$ in "rect coordinates" is therefore $$ G_R = T^{-1}GT $$

From your description, it seems that $$ T = S^{-1}ABC $$ But that depends on which "direction" the transforms at each level are specified - I know nothing about SVG, so I cannot tell. Also, this assumes that vectors are column vectors, i.e. that you apply transform $Z$ to $x$ by computing $Zx$. If you're using row vectors instead (which is common in computer graphics - IIRC OpenGL "thinks" in terms of row vectors), then apply $Z$ to $x$ means computing $xZ$, and thus the order of operations is different - you'd then have $$ G_R = TGT^{-1} $$ and $$ T = CBAS^{-1} $$

There are, unfortunately, quite a few possibilities, so your best course of action would be to start with a much simpler example. I'd first get rid of all the intermediate SVG transforms, and just use a single transform that gets you from SVG to physics coordinates. Then, slowly extends things...

  • $\begingroup$ BTW, your question also doesn't really explain if the $G$ you get from the physics engine include just the changes of the last time step, or all accumulated changes. If it includes all transforms, then the resulting $T$ in my answer shouldn't be added to the rects transforms, but rather replace it. And in the following time step, be carefull to use the updated $C$ $\endgroup$ – fgp Mar 24 '14 at 12:09
  • $\begingroup$ Your right, I do not mention this, but the transformation is always absolute and complete. It is not the difference to the frame before. $\endgroup$ – philipp Mar 24 '14 at 12:37
  • $\begingroup$ I accept the answer since it is right in principle. I was my first guess too, but I missed one thing: The initial Transformation of the SVG Elements needs to set so that they are transformed accordingly to the physics body. This initial transformation needs to be applied to new transformation each time. $\endgroup$ – philipp Mar 30 '14 at 14:40

Your Answer

