【问题标题】:How to find the control point of a quadratic curve using a parabola?如何使用抛物线找到二次曲线的控制点?
【发布时间】:2015-06-02 14:34:41
【问题描述】:

我不知道如何绘制抛物线,其方程为y^2 = 4ax

所以我有两个端点,即 P0、P2,但是我不知道如何找到控制点以放入 quadraticCurveTo() 函数。

【问题讨论】:

    标签: javascript math html5-canvas bezier quadratic-curve


    【解决方案1】:

    要将二次贝塞尔曲线与此抛物线公式相匹配并假设原点为 0,您可以使用将控制点从端点之一放置在 -y0-y1

    示例

    首先,让我们重新排列公式:

    y2 = 4ax

    到:

    x = y2 / 4a

    所以我们可以从下往下绘制。

    在这种情况下,我们可以简单地将所有内容归结并使用 y 和 mid x 的倒数作为控制点。

    不过,一般原则是找到端点的切线。然后应该放置这些线与控制点相交的位置。如果您想了解如何找到交叉点的数学 步骤,我建议您查看 Erik Man 的回答 here(恰好今天发布,但更详细地分解了数学)。

    所以,如果我们在画布的窗口内绘制它(黑色是抛物线,红色是二次曲线):

    var ctx = document.querySelector("canvas").getContext("2d"),
        w = ctx.canvas.width, h = ctx.canvas.height;
    ctx.strokeStyle = "red";
    ctx.lineWidth = 2;
    ctx.translate(0, 6);
    
    // formula
    function f(y, a) {return y * y / (a * 4)};
    
    var a = 80;
    
    plotWindow();
    
    function plotWindow() {
      
      ctx.clearRect(0, -6, w, h);
      ctx.fillStyle = "#000";
      
      // plot parabola using formula
      for(var i = 0; i < w; i++) {
        var y = f(i - w * 0.5, a);
        ctx.fillRect(i - 2, y - 2, 4, 4);
      }
    
      // plot parabola using quadratic curve:
      var x0 = 0;
      var y0 = f(-w * 0.5, a);
      var x1 = w;
      var y1 = f( w * 0.5, a);
      var cx = x1 * 0.5;  // control point is center for x
      var cy = -y0;       // control point is -y0 for y assuming top of parabola = 0
    
      ctx.beginPath();
      ctx.moveTo(x0, y0);
      ctx.quadraticCurveTo(cx, cy, x1, y1);
      ctx.stroke();
      
      // plot a
      ctx.fillStyle = "blue";
      ctx.fillRect(cx - 3, a - 3, 6, 6);
      ctx.fillText("a=" + a, cx + 6, a + 5)
    }
    
    // slider
    document.querySelector("input").onchange = function() {
      a = +this.value;
      plotWindow();
    };
    canvas {border:1px solid #777}
    <script src="https://cdn.rawgit.com/epistemex/slider-feedback/master/sliderfeedback.min.js"></script>
    <label>a: <input type="range" min=10 max=172 value=80></label><br>
    <canvas width=600 height=190></canvas>

    【讨论】:

      猜你喜欢
      • 2011-09-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-14
      • 2021-08-06
      • 1970-01-01
      • 1970-01-01
      • 2017-04-03
      • 1970-01-01
      相关资源
      最近更新 更多