I have a body simulated with Box2Dweb and an image attached to the body. I want to take the body transformation matrix and apply the transformation to the image (draw the image with the transformation), so that its position and orientation (relative) on the screen matches that of the body. I can't find a function for using with a transformation matrix in KineticJS. There are separate functions for moving and rotating, and there's a Kinetic.Transform
class which holds some 'matrix' inside, but I have no idea what to do with it then. There's also a _setTransform
function somewhere, but again, no idea how to use it (and does the underscore suggest that I must not call it directly or what?).
I used this code to draw images over bodies in plain Javascript:
function drawImageOverBody(context, body, image, scale)
{
context.save();
var pos = body.GetPosition();
var center = [scale*pos.x, scale*pos.y];
var R = body.GetTransform().R;
context.translate(center[0], center[1]);
context.transform(R.col1.x, R.col1.y, R.col2.x, R.col2.y, 0, 0);
context.translate(-center[0], -center[1]);
context.drawImage(image, center[0] - image.width/2.0, center[1] - image.height/2.0);
context.restore();
}
How do I do the same with KineticJS?
EDIT: apparently, the only transformations I can get from Box2d are translation and rotation, which I can get by calling GetPosition()
and GetAngle()
on the Box2d body, then apply to a KineticJS image with setX(), setY()
and setRotation()
. So I don't really need the transformation in matrix form here. Still, curious.
The
Kinetic.Transform
class can be used to calculate rotation, scale and offset from a given transformation matrix. Set them
attribute ofKinetic.Transform
to the transformation matrix, then use the transform object to calculate rotation, scale and translation. Rotation, scale and translation can then be applied to anyKinetic.Node
Translation is given directly by the last two items in the matrix.
If you acquire a transformation from elsewhere, you can apply it to a
Kinetic.Transform
like this:Translation is the easiest. it is given by the last two elements: 4 in X direction, 5 in Y direction. There is also a method to get it.
You can get the scale from the transformation matrix:
Don't forget that the image can be flipped over the X or Y axis, or both. Calculate the determinant to take that into account:
Adjust the sign of the scales to get the rotation more easily:
Now the last one, rotation. You can get that by using
Math.asin
orMath.acos
, but you must take the quadrant of the rotation angle into account. This is one way to solve it:Note that the order in which to apply the different transformations is important. If you use the method explained above, first apply translation, then rotation, then scale.