在贝塞尔曲线上获得一个点,而无需猜测或蛮力

时间:2019-04-03 18:14:36

标签: javascript html5-canvas bezier

我本来想使用四个点(因为贝塞尔曲线定义为四个点),但是这迫使我蛮横地使用该位置,所以我尝试了另一种方法,现在我需要帮助:

我有一个起点P0,一个终点P1以及斜率m0和m1,这些斜率应该给了我开始/结束斜率,以计算它们之间的贝塞尔曲线。
因为我需要获得给定点x的高度y,所以该曲线应该是函数(第3度)的形式。

使用 HTML5Canvas ,我可以毫无问题地绘制贝塞尔曲线,并使用此功能

enter image description here

这使我能够计算出给定点的任意给定点,以某种方式获得曲线的中心点。但是我不需要依赖于t,而是依赖于y,取决于x,因此不是曲线的一半,而是P0和P1之间x距离的一半。

要可视化的图像:
enter image description here
左是我可以计算的,右是我需要的。

在给定两个点P0,P1以及斜率m0,m1的情况下,我一直在尝试计算三次函数,结果得出四个方程,我似乎只能用可变输入来求解。我还尝试使用上述函数通过x值(已知)来计算t,但那里也没有骰子。

我需要避免对这些计算使用近似值或昂贵的循环,因为它们对许多对象每秒执行多次,因此this answer对我来说不可行。

感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

我正在研究的项目中遇到了相同的问题。我不知道从y获取x坐标的公式,而且我怀疑您会遇到这种麻烦,因为贝塞尔曲线最多可以包含3个点,而所有点都具有相同的x值。

我建议使用BezierEasing库,该库是为此用例设计的,并使用各种性能增强技术来尽可能快地进行查找:https://github.com/gre/bezier-easing

答案 1 :(得分:1)

要解决此问题,您需要以幂多项式形式重写Bezier方程

``  <h2>EMAIL ::: {{ userDatafromDB.email }}</h2>``

求解cubic equation来计算未知的t

X(t) = t^3 * (P3.X-3*P2.X+3*P1.X-P0.X) + 
       t^2 * (3*P0.X + 6*P1.X+3*P2.X) + 
       t * (3*P1.X - 3P2.X) +
       P0.X 

if X(t) = P0.X*(1-ratio) + P3.X*ratio 
then
let d = ratio * (P0.X - P3.X)

JS code here

然后将计算出的a*t^3 + b*t^2 + c*t + d = 0 参数(最多可能有三个解)应用于Y分量并获取点坐标。请注意,公式是封闭的(无循环),并且应该足够快地运行

答案 2 :(得分:0)

感谢所有之前回答过的人,这些通常是很好的解决方案。

就我而言,我可以100%确保可以将曲线转换为三次函数,该函数可以使用the result of this calculation近似贝塞尔曲线。

由于我可以控制自己的点,因此我可以强制将P0设置为x = 0,这简化了线性系统的计算,从而使我可以更容易地计算三次函数,如下所示:

let startPoint: Utils.Vector2 = new Utils.Vector2(0, 100);
let endPoint: Utils.Vector2 = new Utils.Vector2(100, 100);


let a: number, b: number, c: number, d: number;

function calculateFunction() {
    let m0: number = 0;
    let m1: number = 0;

    a = (-endPoint.x * (m0 + m1) - 2 * startPoint.y + 2 * endPoint.y) / -Math.pow(endPoint.x, 3);
    b = (m1 - m0 - 3 * a * Math.pow(endPoint.x, 2)) / (2 * endPoint.x);
    c = m0;
    d = startPoint.y;
}