在KineticJS中使用转换矩阵 [英] Using transformation matrix in KineticJS
问题描述
我有一个用Box2Dweb模拟的身体,并将图像附加到该身体上.我想获取身体变形矩阵,并将该变形应用于图像(通过转换绘制图像),以使其在屏幕上的位置和方向(相对)与身体的位置和方向匹配.我在KineticJS中找不到用于转换矩阵的函数.有用于移动和旋转的单独函数,并且有一个Kinetic.Transform
类,该类内部包含一些矩阵",但是我不知道该如何处理.还是有一个_setTransform
函数,但是同样,不知道如何使用它(下划线是否暗示我不能直接调用它?什么?).
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?).
我使用以下代码以纯Javascript在身体上绘制图像:
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();
}
如何使用KineticJS进行相同操作?
How do I do the same with KineticJS?
显然,我可以从Box2d获得的唯一转换是平移和旋转,这可以通过在Box2d主体上调用GetPosition()
和GetAngle()
来获得,然后应用于具有setX(), setY()
和setRotation()
.因此,我在这里实际上不需要矩阵形式的转换.还是很好奇.
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.
推荐答案
Kinetic.Transform
类可用于计算给定变换矩阵的旋转,缩放和偏移.将Kinetic.Transform
的m
属性设置为变换矩阵,然后使用变换对象计算旋转,缩放和平移.然后可以将旋转,缩放和平移应用于任何Kinetic.Node
The Kinetic.Transform
class can be used to calculate rotation, scale and offset from a given transformation matrix. Set the m
attribute of Kinetic.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 any Kinetic.Node
翻译由矩阵的最后两项直接给出.
Translation is given directly by the last two items in the matrix.
如果您从其他地方获取了转换,则可以将其应用于Kinetic.Transform
,如下所示:
If you acquire a transformation from elsewhere, you can apply it to a Kinetic.Transform
like this:
var tf = new Kinetic.Transform();
tf.m = [Math.sqrt(2), Math.sqrt(2), -3/2*Math.sqrt(2), 3/2*Math.sqrt(2), 4, 5];
翻译是最简单的.它由最后两个元素给出: X方向为4,Y方向为5.还有一种获取方法.
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.
var translation = tf.getTranslation();
您可以从转换矩阵中获取比例尺:
You can get the scale from the transformation matrix:
var m = tf.getMatrix(); // or tf.m
var scaleX = Math.sqrt(m[0]*m[0] + m[1]*m[1]);
var scaleY = Math.sqrt(m[2]*m[2] + m[3]*m[3]);
别忘了图像可以在X轴或Y轴或两者上翻转.计算行列式时要考虑到这一点:
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:
if(m[0]*m[3] - m[1]*m[2] < 0){
scaleY = -scaleY;
}
调整刻度的符号以更轻松地旋转:
Adjust the sign of the scales to get the rotation more easily:
if(m[0] < 0){
scaleX = -scaleX;
scaleY = -scaleY;
}
现在是最后一个,旋转.您可以使用Math.asin
或Math.acos
来获得该值,但是必须考虑旋转角度的象限.这是解决它的一种方法:
Now the last one, rotation. You can get that by using Math.asin
or Math.acos
, but you must take the quadrant of the rotation angle into account. This is one way to solve it:
var angle = Math.acos(m[3] / scaleY);
if(m[2]/scaleY > 0){
angle = -angle;
}
请注意,应用不同转换的顺序很重要.如果您使用上述方法,请首先应用平移,然后旋转,然后缩放.
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.
这篇关于在KineticJS中使用转换矩阵的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!