如何在旋转和使用kinecticjs缩放后确定blob的x和y

时间:2014-01-28 19:50:36

标签: kineticjs

我正在使用Kinecticjs v5.0.1“kinect.line”(blobs),有没有办法确定该组缩放和旋转后组中新的x,y点?

我需要将文本与旋转的blob对齐 - 但是如果我将文本作为组的一部分,它也将被旋转。

我想要做的是确定旋转斑点的新x,y点并将文本移动到该位置,而不旋转。

1 个答案:

答案 0 :(得分:1)

缩放和旋转的斑点的边界框没有Kinetic.Blob属性。

查找缩放的旋转Kinetic.Blob的边界框很复杂。

以下是步骤......

首先:获取构成斑点的三次贝塞尔曲线的控制点

  • blob实际上是一组封闭的三次Bezier曲线。

  • blob的起点是blob.getPoints()中的前2个元素。

  • 每条贝塞尔曲线的控制点都在blob.getTensionPoints();

  • 这些曲线是未转换的blob(无缩放,无旋转)

第二:获取未转换blob的边界框:

  • 使用Cubic Bezier曲线的公式沿着每条曲线走。

  • 确定曲线集的最小X / Y和最大X / Y.

  • 如果斑点未缩放且未旋转,则这些最小/最大X,Y是斑点边界框。

第三:缩放并旋转X / Y点

  • Kinetic使用变换矩阵来跟踪任何形状的缩放和旋转方式。

  • 变换矩阵是一种在旋转和缩放后确定点的X / Y的数学方法。

  • 使用var matrix = blob.getAbsoluteTransform()获取blob的变换矩阵。

  • 使用blob.getTransform()获取边界框角的缩放/旋转XY。getMatrix()其中X,Y是您在第二步中计算的未转换XY。

以下是一些有用的代码供您拼凑以实现结果

此代码将获取Kinetic.Blob的控制点并在画布上绘制

var points=blob.getPoints();
var tensionPoints=blob.getTensionPoints();
var ctx=layer.getContext()._context;
var x=blob.getX();
var y=blob.getY();

ctx.save();
ctx.beginPath();
ctx.moveTo(points[0]+x,points[1]+y);
for(var i=0;i<tensionPoints.length-2;i+=6){
    ctx.bezierCurveTo(
        tensionPoints[i+0]+x,tensionPoints[i+1]+y,
        tensionPoints[i+2]+x,tensionPoints[i+3]+y,
        tensionPoints[i+4]+x,tensionPoints[i+5]+y
    );
}
ctx.lineWidth=5;
ctx.strokeStyle="red";
ctx.stroke();
ctx.restore();

此实用程序将走一条三次贝塞尔曲线并沿该曲线返回XY点

在此实用程序中:

  • T = 0.00将返回曲线起点的XY,
  • T = 1.00将返回曲线终点的XY,
  • 通过.01增加T通常会在曲线上产生足够的XY样本

沿着立方贝塞尔曲线获取XY:

function getCubicBezierXYatT(startPt,controlPt1,controlPt2,endPt,T){
    var x=CubicN(T,startPt.x,controlPt1.x,controlPt2.x,endPt.x);
    var y=CubicN(T,startPt.y,controlPt1.y,controlPt2.y,endPt.y);
    return({x:x,y:y});
}

// cubic helper formula at T distance
function CubicN(T, a,b,c,d) {
    var t2 = T * T;
    var t3 = t2 * T;
    return a + (-a * 3 + T * (3 * a - a * T)) * T
    + (3 * b + T * (-6 * b + b * 3 * T)) * T
    + (c * 3 - c * 3 * T) * t2
    + d * t3;
}

此实用程序将使用转换矩阵将原始XY转换为缩放/旋转XY

// usage: var XY=tmPoint(trx.getMatrix(),oldX,oldY);

var trx=blob.getTransform();
var XY=tmPoint(trx.getMatrix(),oldX,oldY);

function tmPoint(m, x, y){
  return({
    x:x*m[0] + y*m[2] + m[4],
    y:x*m[1] + y*m[3] + m[5]
  });
}