代码之家  ›  专栏  ›  技术社区  ›  Paul Butcher

在HTML52D画布上下文中查找曲线上的点

  •  6
  • Paul Butcher  · 技术社区  · 14 年前

    由二维画布上下文函数绘制的给定线条 bezierCurveTo , quadraticCurveTo arcTo ,如何沿这些线找到点?

    我的目的是在曲线的中点画一个物体。使用svg dom,我可以用方法做到这一点 getPointAtLength 和; getTotalLength 但是在HTML画布中我看不到等价的。

    2 回复  |  直到 5 年前
        1
  •  11
  •   Simon Sarris    14 年前

    你很难找到他们:(

    在HTML画布中没有等价的。你必须用简单的老数学找到你自己的中点。

    我为你做了一个如何找到贝塞尔曲线中点的例子。在JSfiddle现场观看 here . 下面粘贴了一个javascript副本。

    实际曲线是红色的,中点是绿色的小矩形。其他一切只是视觉辅助。

    var ctx = $("#test")[0].getContext("2d")
    function mid(a,b) {
     return (a+b) / 2;
    }
    
    
    var cp1x = 100;
    var cp1y = 150;
    var cp2x = 175;
    var cp2y = 175;
    var x = 200;
    var y = 0;
    
    ctx.lineWidth = 4;
    ctx.strokeStyle = "red";
    ctx.fillStyle = "rgba(0,0,0,0.6)";
    
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
    ctx.stroke();
    
    //line goes from start to control point 1
    ctx.strokeStyle = "rgba(0,0,200,0.4)";
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(cp1x , cp1y);
    ctx.stroke();
    
    //line goes from end to control point 2
    ctx.beginPath();
    ctx.moveTo(x, y);
    ctx.lineTo(cp2x , cp2y);
    ctx.stroke();
    
    //line goes from control point to control point
    ctx.strokeStyle = "rgba(200,0,200,0.4)";
    ctx.beginPath();
    ctx.moveTo(cp1x, cp1y);
    ctx.lineTo(cp2x , cp2y);
    ctx.stroke();
    
    // now find the midpoint of each of those 3 lines
    var ax = mid(cp1x,0);
    var bx = mid(cp2x,x)
    var cx = mid(cp1x,cp2x)
    
    var ay = mid(cp1y,0)    
    var by = mid(cp2y,y)    
    var cy = mid(cp1y,cp2y)
    
    
    // draw midpoints for visual aid 
    // not gonna look exact 'cause square
    // will be drawn from top-right instead of center
    ctx.fillRect(ax, ay, 4, 4);
    ctx.fillRect(bx, by, 4, 4);
    ctx.fillRect(cx, cy, 4, 4);
    
    
    //now draw lines between those three points. These are green
    ctx.strokeStyle = "rgba(0,200,0,0.4)";
    ctx.beginPath();
    ctx.moveTo(ax, ay);
    ctx.lineTo(cx , cy);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.moveTo(bx, by);
    ctx.lineTo(cx , cy);
    ctx.stroke();
    
    //now the midpoint of the green lines:
    // so g1 and g2 are the green line midpoints
    var g1x = mid(ax,cx);
    var g2x = mid(bx,cx);
    
    var g1y = mid(ay,cy); 
    var g2y = mid(by,cy);  
    
    //draw them to make sure:
    ctx.fillRect(g1x , g1y, 4, 4);
    ctx.fillRect(g2x , g2y, 4, 4);
    
    //now one final line, in gray
    ctx.strokeStyle = "rgba(20,20,20,0.4)";
    ctx.beginPath();
    ctx.moveTo(g1x , g1y);
    ctx.lineTo(g2x , g2y);
    ctx.stroke();
    
    //whew! We made it!
    var FinallyTheMidpointx = mid(g1x,g2x); 
    var FinallyTheMidpointy = mid(g1y,g2y); 
    
    //draw something at the midpoint to celebrate
    ctx.fillStyle = "rgba(0,255,0,1)";
    ctx.fillRect(FinallyTheMidpointx, FinallyTheMidpointy, 4, 4);
    

    艾斯

        2
  •  0
  •   Plagiatus    5 年前

    贝塞尔曲线用此公式进行数学计算
    .
    其中p0是起点,p1和p2是控制点,p3是终点。

    要计算半路点,您只需使用 t=0.5

    类似于二次曲线:

    source and further information


    其中p0为起点,p1和p2为控制点,p3为终点。

    要计算半航路点,只需使用 t = 0.5 .

    类似于二次曲线:
    Quadratic Curve Mathematically

    Source and further Information

    推荐文章