在KineticJS中使用转换矩阵 [英] Using transformation matrix in KineticJS

查看:90
本文介绍了在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.Transformm属性设置为变换矩阵,然后使用变换对象计算旋转,缩放和平移.然后可以将旋转,缩放和平移应用于任何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.asinMath.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆