finding a point on a path

前端 未结 2 1476
无人及你
无人及你 2020-12-17 01:05

I have an app that draws a bezier curve in a UIView and I need to find the X intersect when I set a value for Y. First, as I understand, there isn’t a way to fi

2条回答
  •  星月不相逢
    2020-12-17 01:35

    A cubic Bézier curve is defined by 4 points

    P0 = (x0, y0) = start point,
    P1 = (x1, y1) = first control point,
    P2 = (x2, y2) = second control point,
    P3 = (x3, y3) = end point,
    

    and consists of all points

    x(t) = (1-t)^3 * x0 + 3*t*(1-t)^2 * x1 + 3*t^2*(1-t) * x2 + t^3 * x3
    y(t) = (1-t)^3 * y0 + 3*t*(1-t)^2 * y1 + 3*t^2*(1-t) * y2 + t^3 * y3
    

    where t runs from 0 to 1.

    Therefore, to calculate X for a given value of Y, you first have to calculate a parameter value T such that 0 <= T <= 1 and

     Y = (1-T)^3 * y0 + 3*T*(1-T)^2 * y1 + 3*T^2*(1-T) * y2 + T^3 * y3      (1)
    

    and then compute the X coordinate with

     X = (1-T)^3 * x0 + 3*T*(1-T)^2 * x1 + 3*T^2*(1-T) * x2 + T^3 * x3      (2)
    

    So you have to solve the cubic equation (1) for T and substitute the value into (2).

    Cubic equations can be solved explicitly (see e.g. http://en.wikipedia.org/wiki/Cubic_function) or iteratively (for example using the http://en.wikipedia.org/wiki/Bisection_method).

    In general, a cubic equation can have up to three different solutions. In your concrete case we have

    P0 = (0, 280), P1 = (adjust, 280), P3 = (adjust, 0), P4 = (280, 0)
    

    so that the equation (1) becomes

    Y = (1-T)^3 * 280 + 3*T*(1-T)^2 * 280
    

    which simplifies to

    Y/280 = 1 - 3*T^2 + 2*T^3    (3)
    

    The right hand side of (3) is a strictly decreasing function of T in the interval [0, 1], so it is not difficult to see that (3) has exactly one solution if 0 <= Y <= 280. Substituting this solution into (2) gives the desired X value.

提交回复
热议问题