如何找出Ÿ具体点的贝塞尔曲线在画布坐标?(How to find out Y coordinate

2019-08-05 17:46发布

我需要找出在画布贝塞尔曲线的特定点的Y坐标。 你知道,如何找到它呢? 谢谢

Answer 1:

使用德卡斯特里奥算法,你可以找到一个贝塞尔曲线的坐标x和y的任意t,百分比或插值步骤。 因此,在.1会给你的X和Y在从一开始曲线的10%。 .9一件T是90%从一开始,依此类推。

在我们的三次Bezier我们P0(0点),CP0(控制点0),CP1(控制点1),和P1(点1)。

在算法的第一步,我们绘制连接P0和CP0,另一条线连接CP0和CP1,另外还连接CP1和P1线。 那么对于这些​​线路,我们会发现他们的点的所有3是T%从他们​​开始。

我会打电话的要点如下:

  • P0 - > CP0 = A
  • CP0 - > CP1 = B
  • CP1 - > P1 = C

     Ax = ( (1 - t) * p0x ) + (t * cp0x); Ay = ( (1 - t) * p0y ) + (t * cp0y); Bx = ( (1 - t) * cp0x ) + (t * cp1x); By = ( (1 - t) * cp0y ) + (t * cp1y); Cx = ( (1 - t) * cp1x ) + (t * p1x); Cy = ( (1 - t) * cp1y ) + (t * p1y); 

第二个步骤是非常喜欢第一。 在第一个,我们连接这四个点与线,然后发现他们3个新点。 在这一步用线找到他们2分新,我们将连接这些3分。 我会打电话给这两个新的点d和E.

    Dx = ( (1 - t) * Ax ) + (t * Bx);
    Dy = ( (1 - t) * Ay ) + (t * By);

    Ex = ( (1 - t) * Bx ) + (t * Cx);
    Ey = ( (1 - t) * By ) + (t * Cy);

最后,我们可以用另一条线最后两个点的连线,并且在它身上找到的最后一个点,这将给我们是t的贝塞尔曲线上的点。 我会打电话给这点P.

    Px = ( (1 - t) * Dx ) + (t * Ex);
    Py = ( (1 - t) * Dy ) + (t * Ey);

在那里,我们走了,我们现在有X和贝塞尔一个点,从一开始就为t%的y坐标。 我很快就会添加一些图片。



Answer 2:

剪切和粘贴现成的答案:

// Points are objects with x and y properties
// p0: start point
// p1: handle of start point
// p2: handle of end point
// p3: end point
// t: progression along curve 0..1
// returns an object containing x and y values for the given t
BezierCubicXY = function(p0, p1, p2, p3, t) {
    var ret = {};
    var coords = ['x', 'y'];
    var i, k;

    for (i in coords) {
        k = coords[i];
        ret[k] = Math.pow(1 - t, 3) * p0[k] + 3 * Math.pow(1 - t, 2) * t * p1[k] + 3 * (1 - t) * Math.pow(t, 2) * p2[k] + Math.pow(t, 3) * p3[k];
    }

    return ret;
}


Answer 3:

我一直在试图找出同样的事情,我想我解决了这个问题至少在方贝塞尔曲线,这是只有一个单一的控制点贝塞尔曲线。

数学解释

对于正方形贝塞尔曲线的数学式为:

其中“X”是结果,“A”是起点,“B”的控制点和“C”的结束点的位置。

“T”是0和1之间的数字,指示在要计算线路哪个点。 0表示开始点,1终点和0.5将参考曲线的中心。

该函数被用于计算两个X和上线的点的Y坐标。 如果要计算X只需填写X的A,B和C点的坐标。

现在,为了确定属于我们需要确定的“T”为表示X坐标X与Y。

我们可以写在二次型相同贝塞尔方程( ):

这使我们能够使用二次公式导出的“T”即解方程的值。 二次公式实际上是2个公式。

将得到的公式为:

代码解决方案

我们可以在代码中的描述如下:

GetYValues(StartPoint, ControlPoint, EndPoint, X)
{
    Ax = StartPoint.X
    Bx = ControlPoint.X
    Cx = EndPoint.X

    q1 = 2*Ax - 2*Bx;
    q2 = Sqrt(5*Ax*Ax - 10*Ax*Bx + Ax*Cx - Ax*X + 2*Bx*X + 4*Bx*Bx)
    q3 = 2*Ax - 4*Bx + 2*Cx

    t1 = (q1 + q2) / q3
    t2 = (q1 - q2) / q3

    Ay = StartPoint.Y
    By = ControlPoint.Y
    Cy = EndPoint.Y

    Y1 = Ay*(1-t1)*(1-t1) + By*2*(1-t1)*t1 + Cy*t1
    Y2 = Ay*(1-t2)*(1-t2) + By*2*(1-t2)*t2 + Cy*t2

    return [Y1,Y2]
}

现在,我没有测试此,并且功能不检查是否其实有任何有效的点,所以有一定值,它会抛出异常。 确保“0分”检查和“低于0的数字的平方根”。

这种解决方案的问题

这个方程的一个大问题是,它仅适用于多的贝塞尔曲线,而大多数Bezier曲线实际上立方米。 我一直试图找到一种类似的方式来解决这个问题的立方版本,可惜这是幅度比较难的顺序。 我已经能够找到解决三次方程的唯一公式可以在这里找到三次函数 。 这个配方中含有虚数,我不知道该怎么做这些。

另一个问题是,对于具有4个控制点或多个贝塞尔曲线,也没有办法来解决方程在所有。

结论

最后,你最好的选择是简单地将贝塞尔曲线转换为直线,这是无限更容易计算。



Answer 4:

对于圆形的公式为:(XH)^ 2 +(YK)^ 2 = R ^ 2其中,h,k分别是x,y坐标为中心。 所以y的方程将是Y = SQRT(R ^ 2 - (XH)^ 2)+ K。 大多数语言都配有数学包,所以我想你可以做某种Math.sqrt(..)Math.pow(..)

有人纠正我,如果我的数学是关闭的。



Answer 5:

@DerekR:虽然你在这里提出的是明确的,可能是很多有用的,我想答案和全部由自己和IMMO以下意见都没有解决的问题。

(我的数学太臭,我一直在试图解决同样的问题,所以我可能不明白的后续评论。)

我认为这个问题是:知道了X,Y坐标的两个端点和两个控制点,并假设范围是0到1,再给予Y,什么为Y?

我是新的,还不能发表图片,但你可以看到在duck.cc/images/beziercurve_findY.png曲线



文章来源: How to find out Y coordinate of specific point in bezier curve in canvas?