4

我有一个用 Box2Dweb 模拟的身体和一个附在身体上的图像。我想获取身体变换矩阵并将变换应用于图像(使用变换绘制图像),使其在屏幕上的位置和方向(相对)与身体的位置和方向相匹配。我在 KineticJS 中找不到与转换矩阵一起使用的函数。有用于移动和旋转的单独函数,并且有一个Kinetic.Transform内部包含一些“矩阵”的类,但我不知道如何处理它。某处还有一个_setTransform函数,但同样不知道如何使用它(下划线是否表明我不能直接调用它或什么?)。

我用这段代码在纯 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 做同样的事情?

编辑:显然,我可以从 Box2d 获得的唯一转换是平移和旋转,我可以通过在 Box2d 主体上调用GetPosition()和来获得,然后使用和GetAngle()应用于 KineticJS 图像。所以我在这里并不需要矩阵形式的转换。不过,很好奇。setX(), setY()setRotation()

4

1 回答 1

0

该类Kinetic.Transform可用于计算给定变换矩阵的旋转、缩放和偏移。设置变换矩阵的m属性Kinetic.Transform,然后使用变换对象计算旋转、缩放和平移。然后可以将旋转、缩放和平移应用于任何Kinetic.Node

翻译由矩阵中的最后两项直接给出。

如果您从其他地方获得转换,则可以将其应用于Kinetic.Transform这样的:

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。还有一种获取方法。

var 翻译 = tf.getTranslation();

您可以从变换矩阵中获得比例:

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 轴上翻转,或两者兼而有之。计算行列式以考虑到这一点:

if(m[0]*m[3] - m[1]*m[2] < 0){
    scaleY = -scaleY;
}

调整刻度的符号以更轻松地获得旋转:

if(m[0] < 0){
    scaleX = -scaleX;
    scaleY = -scaleY;
}

现在是最后一个,轮换。您可以使用Math.asinor来获得它Math.acos,但您必须考虑旋转角度的象限。这是解决它的一种方法:

var angle = Math.acos(m[3] / scaleY);
if(m[2]/scaleY > 0){
    angle = -angle;
}

请注意,应用不同转换的顺序很重要。如果您使用上述方法,首先应用平移,然后旋转,然后缩放。

于 2013-02-23T21:22:19.603 回答