1

如何获得 Kinetic.Spline 的样条点的切线。我正在使用 KineticJS 4.7.2。

到目前为止,还没有找到任何方法为我提供这个。

非常感谢,曼努埃尔

4

1 回答 1

1

动力学样条是二次/贝塞尔曲线的组合(除非张力==0)

因此,您可以至少以两种方式逼近每个样条点的切线。

粗略的近似是一个 4 步过程:

  1. 使用 mySpline.getPoints() 获取样条曲线中的所有连接点。
  2. 使用 Math.atan2 计算连接点处输入/输出线的弧度角。
  3. 取这两个角度的差(给出该连接点的弧度角)。
  4. 取那个弧度角的切线。

更好的近似涉及更多:

  1. 使用内部 spline.allPoints 获取组成样条的所有曲线的控制点。提示:第一条和最后一条曲线是二次曲线,所有其他曲线都是三次贝塞尔曲线。
  2. 在连接 2 条曲线的每个点处,找到一个非常靠近传入曲线末端的点。
  3. 在连接 2 条曲线的每个点上,找到一个非常靠近输出曲线起点的点。
  4. 使用 Math.atan2 计算连接这 2 个点的线段的角度。
  5. 取那个弧度角的切线。

沿曲线获取 XY 点

这些函数将帮助您获得沿二次或三次贝塞尔曲线的 XY。

如果 T=0.00,该点将位于曲线的最开始。

如果 T==1.00,则该点将位于曲线的最末端。

// quadratic bezier: T is 0-1
function getQuadraticBezierXYatT(startPt,controlPt,endPt,T) {
    var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x; 
    var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y; 
    return( {x:x,y:y} );
}

// cubic bezier T is 0-1
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(pct, a,b,c,d) {
    var t2 = pct * pct;
    var t3 = t2 * pct;
    return a + (-a * 3 + pct * (3 * a - a * pct)) * pct
    + (3 * b + pct * (-6 * b + b * 3 * pct)) * pct
    + (c * 3 - c * 3 * pct) * t2
    + d * t3;
}

如果您需要参考 KineticJS 源代码的样条曲线,这里是:

https://github.com/ericdrowell/KineticJS/blob/a2a4c6df2b231e9c133e67a80f49a9ac420e2f33/src/shapes/Spline.js

于 2013-10-11T17:16:57.047 回答