如何使用抛物线找到二次曲线的控制点?
How to find the control point of a quadratic curve using a parabola?
我不知道如何画出方程式为 y^2 = 4ax
的抛物线
所以我有两个端点,即 P0、P2,但是我不知道如何找到控制点以放入 quadraticCurveTo()
函数。
要将二次贝塞尔曲线与此抛物线公式相匹配并假设原点为 0,您可以将控制点放置在距端点之一的 -y0
或 -y1
处。
例子
首先,让我们重新排列一下公式:
y2 = 4ax
至:
x = y2 / 4a
所以我们可以从下往上画图。
在这种情况下,我们可以简单地归结所有内容,并使用 y 和 mid x 的倒数作为控制点。
不过,总的原则是找到端点的切线。然后在那些线相交的地方应该放置控制点。如果你想要 mathematical 如何找到交叉点的步骤,我建议你看看 Erik Man 的回答 (今天碰巧发布了,但分解了数学更多细节)。
因此,如果我们将其绘制在 canvas 的 window 内(黑色为抛物线,红色为二次曲线):
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>
我不知道如何画出方程式为 y^2 = 4ax
所以我有两个端点,即 P0、P2,但是我不知道如何找到控制点以放入 quadraticCurveTo()
函数。
要将二次贝塞尔曲线与此抛物线公式相匹配并假设原点为 0,您可以将控制点放置在距端点之一的 -y0
或 -y1
处。
例子
首先,让我们重新排列一下公式:
y2 = 4ax
至:
x = y2 / 4a
所以我们可以从下往上画图。
在这种情况下,我们可以简单地归结所有内容,并使用 y 和 mid x 的倒数作为控制点。
不过,总的原则是找到端点的切线。然后在那些线相交的地方应该放置控制点。如果你想要 mathematical 如何找到交叉点的步骤,我建议你看看 Erik Man 的回答
因此,如果我们将其绘制在 canvas 的 window 内(黑色为抛物线,红色为二次曲线):
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>