I am working on a project involving bezier curves and I am having trouble finding a value t which is in the range [0, 1] that corresponds to a particular position on a bezier curve. I set up a test where I put incremental values of t (specifically at increments of 0.001 to 1) and subbed them in the x and y parametric equations of a bezier curve, I then subtract that value with the true value and if it is within a small threshold for both x and y I found an appropriate t. Unfortunately, there does not seem to be a single value for t that corresponds to the required coordinates. This means the loop actually finishes without ever succeeding the conditional in the for loop.
The coordinate that should be on the curve is (75, -2.26384401). I put my code below that shows the coordinates of the control points and the true x and y coordinates. Any help would be greatly appreciated. Thanks!
int _tmain(int argc, _TCHAR* argv[])
{
float P0[2] = { 55, -11.105 };
float P1[2] = { 72.569, -11.105 };
float P2[2] = { 50.217, 1.396 };
float P3[2] = { 100, 1.396 };
float t = 1.0F;
float int_t = t / 1000; // intervals
float x;
float y;
float tx = 75.0000000F; // where it should be in x
float ty = -2.26384401F; // where it should be in y
float epsilon = 0.01;
float final_t;
for (float i = 0; i < t; i += int_t)
{
final_t = i;
x = powf(1.0F - i, 3.0F)*P0[0] + 3.0F*powf(1.0F - i, 2.0F)*i*P1[0] +
3.0F*(1.0F - i)*powf(i, 2.0F)*P2[0] + powf(i, 3.0F)*P3[0]; // x(t)
y = powf(1.0F - i, 3.0F)*P0[1] + 3.0F*powf(1.0F - i, 2.0F)*i*P1[1] +
3.0F*(1.0F - i)*powf(i, 2.0F)*P2[1] + powf(i, 3.0F)*P3[1]; // y(t)
// for my testing
cout << "---------------------------------" << endl;
cout << "i = " << i << endl;
cout << "x = " << x << endl;
cout << "y = " << y << endl;
cout << "---------------------------------" << endl;
if ((fabsf(x - tx) <= epsilon) && (fabsf(y - ty) <= epsilon))
break;
}
cout << endl;
cout << "x = " << x << endl;
cout << "y = " << y << endl;
cout << "t = " << final_t << endl;
return 0;
}
Your problem is that the input point
Pt(tx,ty)
does not lie on the BEZIER(P0,P1,P2,P3)
curve at all. So the distance to the curve is always much bigger then your small epsilon no matter how close match oft
you find ....Here how it looks like:
The BEZIER curve is in gray. Green
X
is the input(tx,ty)
point and Red+
is found closest point on curvet=0.753
Here C++/VCL code I did this with:
As I am too lazy to debug your code I used for the BEZIER cubic solver my
approx
class from this related QA:in the search itself I set search parameters for
t=<0.0,1.0>
with step0.1
and3
recursions leading to0.1/10^(3-1)
final precision oft
which is0.001
as yourint_t
step but the solution is found in30
steps instead of yours1000
To remedy your code just remember
x,y,t
wih smallest distance totx,ty
instead of just the one wheredistance<=epsilon