获得kineticjs中样条点的切线

时间:2013-10-11 09:45:06

标签: kineticjs

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

迄今为止还没有找到任何方法为我提供这个。

非常感谢,Manuel

1 个答案:

答案 0 :(得分:1)

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

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

粗略近似分为4个步骤:

  1. 使用mySpline.getPoints()获取样条曲线中的所有连接点。
  2. 使用Math.atan2计算连接点处传入/传出线的弧度角。
  3. 取这两个角度的差值(给出该连接点的弧度角)。
  4. 取该弧度角的切线。
  5. 更好的近似值涉及更多:

    1. 使用内部spline.allPoints来获取构成样条曲线的所有曲线的控制点。提示:第一个&最后的曲线是二次曲线,所有其他曲线都是立方贝塞尔曲线。
    2. 在连接2条曲线的每个点上,找到一条非常接近输入曲线末端的点。
    3. 在连接2条曲线的每个点上,找到非常接近输出曲线起点的点。
    4. 使用Math.atan2计算连接这两个点的线段的角度。
    5. 取该弧度角的切线。
    6. 沿曲线获取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