Re: Getting cartesian values from Bezier curve question
Re: Getting cartesian values from Bezier curve question
- Subject: Re: Getting cartesian values from Bezier curve question
- From: Charles PARNOT <email@hidden>
- Date: Tue, 15 Jun 2004 10:50:28 -0700
At 19:05 -0400 6/14/04, dan donaldson wrote:
>
I am considering adding a control to allow users to use a Bezier Path to edit a set of values that change over time. The essentials are a timeline with values determined by keyframes which will be represented by Bezier nodes.
>
My question is, is there a simple way to derive the y value of a bezier line segment given an x coordinate. Assume that there is no circumstance where more than one y value might exist for a given x value. I don't see anything in the NSBezierPath documentation that indicates that this is supported.
If I understand what you want to do is have a smooth function f (x,y) that the user can modify using some handles. Here are my thoughts.
SUMMARY
I would recommand that you limit the allowed bezier path accessible to the user. You apparently already do that. In my opinion, the easiest thing to do is to force the control points to be regularly spaced between the end points in terms of abcissa. Then you get nice smooth function easy to draw with NSBezierPath, and you have a very simple way to get y as a function of x. Read below for the details of the corresponding solution...
THEORY
A bezier section has 2 end points and 2 control points
P0(x0,y0) end point
P1(x1,y1) control point
P2(x2,y2) control point
P3(x3,y3) end point
I suggest that you force
x1=x0+1/3(x3-x0) (one third of the path)
x2=x3-1/3(x3-x0)) (two thirds of the path)
What will happen then is that the x will be linearly dependent on the parameter t that describes the bezier path between the end points. As a reminder, this is the bezier path where t is in [0,1]:
x= x0 ( 1 - t )^3 + 3 x1 * t * ( 1 - t )^2 + 3 x2 * t^2 * ( 1 - t ) + x3 * t^3
y= y0 ( 1 - t )^3 + 3 y1 * t * ( 1 - t )^2 + 3 y2 * t^2 * ( 1 - t ) + y3 * t^3
If you force the control points to have their xs at 1/3 and 2/3 of the x between the two endpoints (ie x1=x0+1/3(x3-x0) and x2=x0+2/3(x3-x0)), then
x= x0 * ( 1-t + t )^3 + t (x3-x0) ( (1-t)(1-t) + 2 t(1-t) + t^2) [ because x3=x0+(x3-x0) ! ]
x= x0 + t (x3-x0) ( (1 - t + t )^2
x= x0 + t (x3-x0)
So if you have x, then t = (x-x0)/(x3-x0), and y follows immediately:
y= y0 ( 1 - t )^3 + 3 y1 * t * ( 1 - t )^2 + 3 y2 * t^2 * ( 1 - t ) + y3 * t^3
SPECIFICS
Now, how do you put that in your code? How to force the control points to be at 1/3 and 2/3? One way is to let the user change only the end points, and the slopes at the end points:
*two end-points P0(x0,y0) and P3(x3,y3)
*two derivatives at P0 and P3, with slopes a0 and a3 (you just need little lines attached to the end points that the user can move up and down)
Then your control points will be obtained by prolonging the slopes at the end points until they reached the desired abcissa. Specifically, to draw the curve using the NSBezierPath, you would use the following control points:
P1(x1,y1)= ( x0 + 1/3 (x3-x0) , y0 + a0 * 1/3 (x3-x0) )
P2(x2,y2)= ( x3 - 1/3 (x3-x0) , y3 - a3 * 1/3 (x3-x0) )
To get the y values for any x value between x0 and x3, you would do:
t = (x-x0)/(x3-x0)
y= y0 ( 1 - t )^3 + 3 y1 * t * ( 1 - t )^2 + 3 y2 * t^2 * ( 1 - t ) + y3 * t^3
COMMENTS
All of this is due to the fact that a Bezier path has much more information than a polynome of degree 3. You can have several y for one x, and there is a notion of speed at which you go along the path. So to get a smooth line for a function, using a Bezier path, you cannot use all of the possible Bezier paths. If we want to use a polynome of degree 3 for the smoothing, then it is completely defined with two points and two derivatives, and there is a corresponding subsets of Bezier paths for all these possible polynomes. This is what we are doing here...
Hope all of this helps!! This is just one solution I thought of, among probably many other possibilities...
charles
--
Charles PARNOT
email@hidden
Help science go fast forward:
http://cmgm.stanford.edu/~cparnot/xgrid-stanford/
Room B157 in Beckman Center
279, Campus Drive
Stanford University
Stanford, CA 94305 (USA)
Tel +1 650 725 7754
Fax +1 650 725 8021
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.