在Javascript中计算二次曲线上任意点切线的斜率

在Javascript中计算二次曲线上任意点切线的斜率,javascript,html,canvas,trigonometry,Javascript,Html,Canvas,Trigonometry,我从来都不是三角游戏冠军,经过大约4个小时的搜索,我决定在这里问: 我使用Javascript在HTML5画布上绘制二次曲线而不是三次贝塞尔曲线,如下所示: this.shape.moveTo(50,80).curveTo(100,120,40,190); 其中,moveTo指定第一个点的x和y,curveTo的前两个参数指定控制点的x和y,curveTo的第三个和第四个参数指定终点的x和y 我需要制作一个函数,让我得到曲线上任意点t的斜率,比如: function getTangentSlo

我从来都不是三角游戏冠军,经过大约4个小时的搜索,我决定在这里问:

我使用Javascript在HTML5画布上绘制二次曲线而不是三次贝塞尔曲线,如下所示:

this.shape.moveTo(50,80).curveTo(100,120,40,190);
其中,moveTo指定第一个点的x和y,curveTo的前两个参数指定控制点的x和y,curveTo的第三个和第四个参数指定终点的x和y

我需要制作一个函数,让我得到曲线上任意点t的斜率,比如:

function getTangentSlope(P0,P1,P2,t) {
   blah blah blah
   return slope;
}
到目前为止,我找到的唯一解决方案要么是有两个控制点的三次曲线,要么是我不理解符号,要么是断开的链接意味着我无法回顾整个解决方案

最好还是用度来表示坡度


兄弟可以帮我吗?

嗯,我不知道这个函数会是什么样子,但我知道在哪里可以找到有用的示例:

不久前,我用图书馆画图表。在这个库中,我找到了许多在折线图中绘制线条的函数。这个库被称为D3。挖掘代码后,我发现了一个有趣的文件:

https://github.com/d3/d3-shape/tree/master/src/curve
在这里,您可以看到可以获得的效果:

https://github.com/d3/d3-shape#curves

祝您好运:

这将返回二阶和三阶曲线的单位位置处的归一化切线

有关下面对象的更详细用法,请参见

const geom = (()=>{

    function Vec(x,y){ 
        this.x = x;
        this.y = y;
    };
    function Bezier(p1,p2,cp1,cp2){  
        this.p1 =  p1;
        this.p2 =  p2;
        this.cp1 = cp1;
        this.cp2 = cp2;
    }    
    Bezier.prototype = {
        //======================================================================================
        // single dimension polynomials for 2nd (a,b,c) and 3rd (a,b,c,d) order bezier 
        //======================================================================================
        // for quadratic   f(t) = a(1-t)^2+2b(1-t)t+ct^2 
        //                      = a+2(-a+b)t+(a-2b+c)t^2
        // The derivative f'(t) =  2(1-t)(b-a)+2(c-b)t
        //======================================================================================
        // for cubic           f(t) = a(1-t)^3 + 3bt(1-t)^2 + 3c(1-t)t^2 + dt^3 
        //                          = a+(-2a+3b)t+(2a-6b+3c)t^2+(-a+3b-3c+d)t^3
        // The derivative     f'(t) = -3a(1-t)^2+b(3(1-t)^2-6(1-t)t)+c(6(1-t)t-3t^2) +3dt^2
        // The 2nd derivative f"(t) = 6(1-t)(c-2b+a)+6t(d-2c+b)
        //======================================================================================        
        p1 : undefined,
        p2 : undefined,
        cp1 : undefined,
        cp2 : undefined,
        tangentAsVec (position, vec ) { 
            var a, b, c, u;
            if (vec === undefined) { vec = new Vec(); }

            if (this.cp2 === undefined) {
                a = (1-position) * 2;
                b = position * 2;
                vec.x = a * (this.cp1.x - this.p1.x) + b * (this.p2.x - this.cp1.x);
                vec.y = a * (this.cp1.y - this.p1.y) + b * (this.p2.y - this.cp1.y);
            }else{
                a  = (1-position)
                b  = 6 * a * position;        // (6*(1-t)*t)
                a *= 3 * a;                   // 3 * ( 1 - t) ^ 2
                c  = 3 * position * position; // 3 * t ^ 2
                vec.x  = -this.p1.x * a + this.cp1.x * (a - b) + this.cp2.x * (b - c) + this.p2.x * c;
                vec.y  = -this.p1.y * a + this.cp1.y * (a - b) + this.cp2.y * (b - c) + this.p2.y * c;
            }   
            u = Math.sqrt(vec.x * vec.x + vec.y * vec.y);
            vec.x /= u;
            vec.y /= u;
            return vec;                 
        },      
    }
    return { Vec, Bezier,}
})()
二阶贝塞尔函数的用法

   // ? represents any value 
   var p1 = new geom.Vec(?,?);  // start point
   var p2 = new geom.Vec(?,?);  // end point
   var cp1 = new geom.Vec(?,?); //control point

   var bez2 = new geom.Bezier(p1,p2,cp1); // create 2nd order bezier
   var t = ?;
   var tangent = bez2.tangentAsVec(t);
   // ? represents any value 
   var p1 = new geom.Vec(?,?);  // start point
   var p2 = new geom.Vec(?,?);  // end point
   var cp1 = new geom.Vec(?,?); // 1st control point
   var cp2 = new geom.Vec(?,?); // 2nd control point

   var bez3 = new geom.Bezier(p1,p2,cp1,cp2); // create 3rd order bezier
   var t = ?;
   var tangent = bez2.tangentAsVec(t);
三阶贝塞尔函数的用法

   // ? represents any value 
   var p1 = new geom.Vec(?,?);  // start point
   var p2 = new geom.Vec(?,?);  // end point
   var cp1 = new geom.Vec(?,?); //control point

   var bez2 = new geom.Bezier(p1,p2,cp1); // create 2nd order bezier
   var t = ?;
   var tangent = bez2.tangentAsVec(t);
   // ? represents any value 
   var p1 = new geom.Vec(?,?);  // start point
   var p2 = new geom.Vec(?,?);  // end point
   var cp1 = new geom.Vec(?,?); // 1st control point
   var cp2 = new geom.Vec(?,?); // 2nd control point

   var bez3 = new geom.Bezier(p1,p2,cp1,cp2); // create 3rd order bezier
   var t = ?;
   var tangent = bez2.tangentAsVec(t);