在没有猜测或暴力的情况下在贝松曲线上获得一个点

问题描述 投票:1回答:3

我最初想要使用四个点(因为bezier曲线是用4个点定义的),但是这迫使我蛮力推动这个位置,所以我尝试了一种不同的方法,我现在需要帮助:

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

使用HTML5Canvas我可以绘制贝塞尔曲线没问题并使用此功能

enter image description here

这允许我计算给定点的百分比,我可以得到曲线的中心点。但我不需要它取决于t,而是y取决于x,所以不是曲线的一半,而是P0和P1之间的x距离的一半。

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

我一直在尝试计算给定两个点P0,P1以及斜率m0,m1的三次函数,这导致四个方程式,我似乎只能通过可变输入来解决这些方程式。我也尝试使用上面的函数来计算使用x值(已知)的t,但也没有骰子。

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

任何帮助表示赞赏。

javascript html5-canvas bezier
3个回答
1
投票

我在我正在进行的项目中遇到了同样的问题。我不知道从y获得x坐标的公式,我怀疑你在这条路线上会遇到麻烦,因为贝塞尔曲线最多可以有3个点,它们都具有相同的x值。

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


1
投票

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

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)

并解决cubic equation未知的问题

a*t^3 + b*t^2 + c*t + d = 0

JS code here

然后将计算出的t参数(最多可能有三个解)应用于Y分量并获得点坐标。请注意,公式很接近(没有循环)并且应该足够快


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;
}
© www.soinside.com 2019 - 2024. All rights reserved.