Cubic Bezier curve: given X,Y, solve for t

In summary, the conversation discusses a cubic bezier function and its use in finding a point on a curve given a time value. The conversation also mentions the possibility of self-intersecting curves and the difficulty in solving for the time value using the formula presented on Wikipedia. A possible solution using Mathematica 6.0 is also provided.
  • #1
abeall
21
0
I'm programming some commands in a graphic application, and once again my extremely limited mathematical knowledge has found me rather stumped.

Here is my cubic bezier function, written in JavaScript syntax(this is not actually JavaScript, though):

function getBezier(percent,p1,cp1,cp2,p2) {
function b1(t) { return t*t*t }
function b2(t) { return 3*t*t*(1-t) }
function b3(t) { return 3*t*(1-t)*(1-t) }
function b4(t) { return (1-t)*(1-t)*(1-t) }
var pos = {x:0,y:0};
pos.x = p1.x*b1(percent) + cp1.x*b2(percent) + cp2.x*b3(percent) + p2.x*b4(percent);
pos.y = p1.y*b1(percent) + cp1.y*b2(percent) + cp2.y*b3(percent) + p2.y*b4(percent);
return pos;
}

You give it a cubic bezier curve defined by four points (two "anchors" which intersect the curve, and two "control points" which affect the curvature), and a time value(written as "percent" above) from 0 to 1, and it returns a point(x,y) at that time.

I'm now in a situation where I need just the opposite. I have a point which I know is on the bezier curve, and I need to find the time value.

Cubic bezier curves can self intersect, in which case I suppose there's a rare possibility that a point actually has two valid time values, but I'm not worried about that, I don't think it can occur in my environment.

After being completely befuddled by the formula for cubic beziers presented on wikipedia (http://upload.wikimedia.org/math/e/2/9/e29b31672536b36c91cb7be0ce8c2ff7.png) I'm left unable to solve for t. Any help in that direction, if it's even possible, would be appreciated.

Thanks!
- aaron
 
Last edited:
Mathematics news on Phys.org
  • #2
In Mathematica 6.0, I define:

pos[t_] = p1*b1[t] + cp1*b2[t] + cp2*b3[t] + p2*b4[t];

where b1[t_] = t*t*t, etc.,

then solve pos[t] = a for t:

Solve[pos[t] == a, t];

which returns 2 complex roots and one real root.

The real root =
-((cp1 - 2 cp2 + p2)/(-3 cp1 + 3 cp2 + p1 -
p2)) - (2^(
1/3) (-9 cp1^2 + 9 cp1 cp2 - 9 cp2^2 + 9 cp2 p1 + 9 cp1 p2 -
9 p1 p2))/(3 (-3 cp1 + 3 cp2 + p1 - p2) (243 a cp1^2 -
54 cp1^3 - 486 a cp1 cp2 + 81 cp1^2 cp2 + 243 a cp2^2 +
81 cp1 cp2^2 - 54 cp2^3 - 162 a cp1 p1 + 162 a cp2 p1 +
81 cp1 cp2 p1 - 162 cp2^2 p1 + 27 a p1^2 + 162 a cp1 p2 -
162 cp1^2 p2 - 162 a cp2 p2 + 81 cp1 cp2 p2 - 54 a p1 p2 +
81 cp1 p1 p2 + 81 cp2 p1 p2 - 27 p1^2 p2 + 27 a p2^2 -
27 p1 p2^2 + Sqrt(4 (-9 cp1^2 + 9 cp1 cp2 - 9 cp2^2 +
9 cp2 p1 + 9 cp1 p2 - 9 p1 p2)^3 + (243 a cp1^2 -
54 cp1^3 - 486 a cp1 cp2 + 81 cp1^2 cp2 + 243 a cp2^2 +
81 cp1 cp2^2 - 54 cp2^3 - 162 a cp1 p1 + 162 a cp2 p1 +
81 cp1 cp2 p1 - 162 cp2^2 p1 + 27 a p1^2 + 162 a cp1 p2 -
162 cp1^2 p2 - 162 a cp2 p2 + 81 cp1 cp2 p2 -
54 a p1 p2 + 81 cp1 p1 p2 + 81 cp2 p1 p2 - 27 p1^2 p2 +
27 a p2^2 - 27 p1 p2^2)^2))^(1/3)) + (243 a cp1^2 -
54 cp1^3 - 486 a cp1 cp2 + 81 cp1^2 cp2 + 243 a cp2^2 +
81 cp1 cp2^2 - 54 cp2^3 - 162 a cp1 p1 + 162 a cp2 p1 +
81 cp1 cp2 p1 - 162 cp2^2 p1 + 27 a p1^2 + 162 a cp1 p2 -
162 cp1^2 p2 - 162 a cp2 p2 + 81 cp1 cp2 p2 - 54 a p1 p2 +
81 cp1 p1 p2 + 81 cp2 p1 p2 - 27 p1^2 p2 + 27 a p2^2 -
27 p1 p2^2 + Sqrt(4 (-9 cp1^2 + 9 cp1 cp2 - 9 cp2^2 +
9 cp2 p1 + 9 cp1 p2 - 9 p1 p2)^3 + (243 a cp1^2 -
54 cp1^3 - 486 a cp1 cp2 + 81 cp1^2 cp2 + 243 a cp2^2 +
81 cp1 cp2^2 - 54 cp2^3 - 162 a cp1 p1 + 162 a cp2 p1 +
81 cp1 cp2 p1 - 162 cp2^2 p1 + 27 a p1^2 + 162 a cp1 p2 -
162 cp1^2 p2 - 162 a cp2 p2 + 81 cp1 cp2 p2 - 54 a p1 p2 +
81 cp1 p1 p2 + 81 cp2 p1 p2 - 27 p1^2 p2 + 27 a p2^2 -
27 p1 p2^2)^2))^(1/3)/(3 2^(1/3) (-3 cp1 + 3 cp2 + p1 - p2))

I hope this is useful. If I misunderstood the question let me know.
 
  • #3
abeall said:
... the formula for cubic beziers presented on wikipedia (http://upload.wikimedia.org/math/e/2/9/e29b31672536b36c91cb7be0ce8c2ff7.png ...

This formula should be familiar to you, since it is exactly what you have implemented. The B and P in bold typeface are (fixed) vectors with x and y components, so that you actually have two (non-linear) equations on the single unknown t. The same two lines on your code that calculate pos.x and pos.y.

I would try the following:
A) On each of the two equations, distribute all the products and group similar powers of t together, until you finish with a 3-degree polynomial: an expression of the form [tex]a t^3 + b t^2 + c t + d[/tex], where each of a, b, c and d will probably be a big expression in parenthesis but, nevertheless, a constant (given an input point, and anchor and control points, all fixed).
B) Then you should be able to multiply each equation by some constant (actually, multiply each equation by the a coefficient of the other), and subtract one equation from the other, to eliminate the [tex]t^3[/tex] term, ending with one polynomial of degree 2, [tex]a' t^2 + b' t + c'[/tex], which you probably know how to solve.
 
  • #4
Thank-you both!

Sorry, I should have mentioned I did not create the original getBezier function. After staring it and comparing to the wiki cubic bezier formula for awhile, I somewhat see the translation, though I don't think I could have come up with it on my own.

Enuma,

What is the "real root" and how will it help me find t? Does the expression evaluate to t? It's an immense expression, I've never seen anything like it!

Dodo,

Thanks for the advice. Unfortunately I don't follow. What do you mean by:
A) "all the products" - you mean all the points along the curve, as calculated by getBezier? "group similar powers of t" - what is a power of t? what would constitute 'similar' and in what way are they grouped? "until you finish" - finish what? The grouping, presumably, but I don't really know what grouping means, what exactly is being done at this step. "with a 3-degree polynomial" - meaning something cubed? what should be cubed?
B) "each equation" - at this point, what is each equation? You mean the two equation in the original getBezier function which calculate x,y respectively? "coefficient of the other" - what are the coefficients, or how do I find them? "which you probably know how to solve" - I'm afraid I don't have a clue. I'm not even sure what a and b represent at this point, much less what the little line above them represents.
 
  • #5
Dodo said:
A) On each of the two equations, distribute all the products and group similar powers of t together, until you finish with a 3-degree polynomial: an expression of the form [tex]a t^3 + b t^2 + c t + d[/tex], where each of a, b, c and d will probably be a big expression in parenthesis but, nevertheless, a constant (given an input point, and anchor and control points, all fixed).

abeall, what dodo means is to rewrite the bezier equation as:
(3*cp2-p2-3*cp1+p1) * t^3 + (3*p2+3*cp1-6*cp2) * t^2 + (-3*p2+3*cp2) * t + p2 = chosen point
 
Last edited:
  • #6
mda said:
abeall, what dodo means is to rewrite the bezier equation as:
(3*cp2-p2-3*cp1+p1) * t^3 + (3*p2+3*cp1-6*cp2) * t^2 + (-3*p2+3*cp2) * t + p2 = chosen point

Wow, I have no idea how you did that, but I can see how that is the expression Dodo described. Thank-you very much.

Now for step B... I'm a little lost because t is an unknown, it is what I'm trying to solve, and x and y are known. So I would have thought the equation would need to written somehow as t = ... so that I can find t. Is that not where this is going?
 
  • #7
For a general cubic,

[tex]at^3 + bt^2 + ct + d = 0[/tex]

the solution is

[tex]\begin{array}{rcl}t &=& -\frac{b}{3a} + \frac{1}{3a} \left[ K \frac{ \sqrt[3]{36abc -108a^2d-8b^3+12\sqrt{12ac^3-3b^2c^2-54 bcd+81a^2d^2+12ab^3d}}}{2}\right \\ && \left \quad - \bar{K} (3ac-b^2)\frac{2}{\sqrt[3]{36abc-108a^2d-8b^3+12\sqrt{12ac^3 3b^2c^2-54abcd+81a^2d^2+12ab^3d}}} \right] \end{array}[/tex]

where K is given by anyone of the following (where [itex]i = \sqrt{-1}[/itex]):

[tex]K \in \left\{1, \quad -\frac12+i\frac{\sqrt3}2, \quad -\frac12-i\frac{\sqrt3}2 \right\}[/tex]

and [itex]\bar{K}[/itex] is the complex conjugate of K.

As you can see, this is a bit of a pain to try to implement. Usually solutions are found by approximate means instead.
 
Last edited:
  • #8
As you can see, this is a bit of a pain to try to implement. Usually solutions are found by approximate means instead.
Wow. Yeah. An approximation would be good. Are there any well known approximation methods I could research? The only thing I can think of is to walk the bezier at a small time interval, say 0.01, then sort the points by distance to target point, and refine the closest or closest two until I'm within desired range of error to the target point. Unfortunately, I'm a little hesitant to walk the bezier curve because this command was going to be essentially a faster alternative to another method I'm using that basically does what I just described.

But here's another problem I need to solve in a related situation of this same subject: is it possible to find an X value given a Y value and no time value? Or must should an approximation again be used instead?
 
  • #9
As stated in previous posts, it really boils down to solving a cubic equation. If you really think there aren't multiple t's for the x you are looking for, then Newton Raphson should work. I've used it with cubic beziers for the exact same purpose you state and it works well. Assume you are using the Bezier formulation where t=0,1. For the starting point, one possibility is to calculate x for t=0 and t=1, then by simple ratio estimate the t for the desired x, then iterate from there. There are more elaborate methods. Of course, this may or may not be faster than the method you currently use.

The method of walking through the curve can work, but you don't need such a fine increment. Just using a few points (e.g. 4 or 5) should bracket the interval such that you can converge on the solution with very few Newton Raphson iterations (3 or 4 perhaps).

Even better would be to use Halley's method:

http://mathworld.wolfram.com/HalleysMethod.html
 
Last edited:
  • #10
abeall said:
What is the "real root" and how will it help me find t? Does the expression evaluate to t? It's an immense expression, I've never seen anything like it!
A cubic equation has 3 roots (t's that solve it). In general the roots may be real (a number that does not include the imaginary Sqrt[-1]) or complex (a number that includes the imaginary Sqrt[-1]).

In your case, two roots (t's) are complex, one is real.

Mathematica is pretty good with this type of a problem.
 
  • #11
Thanks for the explanation, Enuma. That made sense. And thank you hotvette, I am now working on a Newton Raphson approximation.
 
Last edited:
  • #12
Ben Niehoff said:
For a general cubic,

[tex]at^3 + bt^2 + ct + d = 0[/tex]

the solution is

[tex]\begin{array}{rcl}t &=& -\frac{b}{3a} + \frac{1}{3a} \left[ K \frac{ \sqrt[3]{36abc -108a^2d-8b^3+12\sqrt{12ac^3-3b^2c^2-54 bcd+81a^2d^2+12ab^3d}}}{2}\right \\ && \left \quad - \bar{K} (3ac-b^2)\frac{2}{\sqrt[3]{36abc-108a^2d-8b^3+12\sqrt{12ac^3 3b^2c^2-54abcd+81a^2d^2+12ab^3d}}} \right] \end{array}[/tex]

where K is given by anyone of the following (where [itex]i = \sqrt{-1}[/itex]):

[tex]K \in \left\{1, \quad -\frac12+i\frac{\sqrt3}2, \quad -\frac12-i\frac{\sqrt3}2 \right\}[/tex]

and [itex]\bar{K}[/itex] is the complex conjugate of K.

As you can see, this is a bit of a pain to try to implement. Usually solutions are found by approximate means instead.

Can somebody verify this equation? I notice that the terms in the square root are very similar but not identical. I wonder if this is correct or a mistake.

The first term is:
12ac^3-3b^2c^2-54 bcd+81a^2d^2+12ab^3d
The second is:
12ac^3 3b^2c^2-54abcd+81a^2d^2+12ab^3d

Notice the second lacks a '-' in front of the 3b (making it a multiplier) and there is an 'a' in 54abcd where the a is missing from the first.


Also, I'm currently using Newton-Raphson. I have cases that seem to be sensitive to the 'initial guess' and get very bad values if the initial guess is wrong. Is Halley's method less sensitive to this problem?

Thank you
 

1. What is a Cubic Bezier curve?

A Cubic Bezier curve is a type of mathematical curve used in computer graphics and animation. It is defined by four control points, with the first and last points being the start and end points of the curve, and the middle two points influencing the shape and direction of the curve.

2. What is the purpose of using a Cubic Bezier curve?

Cubic Bezier curves are commonly used in computer graphics and animation to create smooth and natural-looking curves. They are also used in design software for creating and editing vector graphics, as well as in web development for creating animations and transitions.

3. How do you find the value of t given X and Y coordinates on a Cubic Bezier curve?

To find the value of t, you can use a mathematical formula or an online calculator specifically designed for solving Cubic Bezier curves. The formula involves solving a system of equations using the given X and Y coordinates and the control points of the curve.

4. What is the significance of the value of t in a Cubic Bezier curve?

The value of t represents the position of a point on the curve, ranging from 0 to 1. This value can be used to calculate the coordinates of any point on the curve. It also determines the direction and shape of the curve, as well as the speed of an animation along the curve.

5. Are there any limitations to using Cubic Bezier curves?

While Cubic Bezier curves are useful for creating smooth and natural curves, they have limitations in representing more complex shapes and curves. They also require advanced mathematical calculations, which may be challenging for some users. Other curve types, such as quadratic and higher-order Bezier curves, may be better suited for certain applications.

Similar threads

  • General Math
Replies
2
Views
2K
Replies
4
Views
2K
  • General Math
Replies
2
Views
6K
  • General Math
Replies
5
Views
3K
Replies
5
Views
6K
  • General Math
Replies
1
Views
4K
  • General Math
Replies
5
Views
4K
Replies
4
Views
4K
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
3K
Back
Top