Transfer Transformation from Physics to Vector Graphic

287 Views Asked by At

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.

Graphics

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;" />
           </g>
      </svg>
   </g>
</svg>

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.

Physics

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.

»Glue«

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!

EDIT

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}$$

1

There are 1 best solutions below

3
On BEST ANSWER

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...