
I drew the above BezierPath by doing: // location is where the user touches screen. // location will be the maximum of the graph CGPoint origin = CGPointMake(xStart, 620.0); CGPoint endpt = CGPointMake(xEnd, 620.0); CGPoint midpt1 = midPointForPoints(origin, location); CGPoint midpt2 = midPointForPoints(location, endpt);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:origin];
[path addQuadCurveToPoint:location controlPoint:CGPointMake(midpt1.x, midpt1.y+50)];
[path addQuadCurveToPoint:endpt controlPoint:CGPointMake(midpt2.x, midpt2.y+50)];
[shapeLayer setPath:path.CGPath];
Now, I want to retrieve y-coordinates for certain x-coordinates that lie on the path. For example, given x = 0.0, I want to get y = 0.0, or given x = 300.0, y = 50.0.
I looked at some references like this question and sample code I am still not sure.
Update: basically, I want to do something like this.

Update: Following @Fang's advice:
Given the equation
X = (1-t)^2*X0 + 2*t*(1-t)*X1 + t^2 *X2
I solve for t
t = ((2.0 * x0 - x1) + sqrt(((-2.0 * x0 + x1) ** 2.0)
- ((4 * (x0 - 2.0 * x1 + x2)) * (x0 - x)))) / (2.0 * (x0 - 2.0 * x1 + x2))
or
t = ((2.0 * x0 - x1) - sqrt(((-2.0 * x0 + x1) ** 2.0)
- ((4 * (x0 - 2.0 * x1 + x2)) * (x0 - x)))) / (2.0 * (x0 - 2.0 * x1 + x2))
Using this value, find Y that corresponds to X (we used X to find the above t value)
Y = (1-t)^2*Y0 + 2*t*(1-t)*Y1 + t^2 *Y2
Following the above equation, I am supposed to get the y-value of the point that lies on the Bezier curve but I get a point that's far from the right one. Any further help will be very much appreciated..
Concern: I think one possible problem is that I am calling addQuadCurveToPoint() twice with two control points instead of once with two control points. Does it mean I draw two Bezier paths and combine them? I am also looking at this to see what's wrong with my computation and the only difference seems to be that he uses two control points when calling addQuadCurveToPoint().
Update after Fang's intense consulting:
- (float)getYFromBezierPath:(float)x location:(CGPoint)location ctrlpt1:(CGPoint)ctrlpt1 ctrlpt2:(CGPoint)ctrlpt2 endpt:(CGPoint)endpt {
float yVal;
float tVal;
if (x <= location.x) {
tVal = [self getTvalFromBezierPath:x x0Val:0.0 x1Val:ctrlpt1.x x2Val:location.x];
yVal = [self getCoordFromBezierPath:tVal origin:0.0 p1Val:ctrlpt1.y p2Val:location.y];
} else {
// THIS PART IS THE PROBLEM //
tVal = [self getTvalFromBezierPath:x x0Val:location.x x1Val:ctrlpt2.x x2Val:endpt.x];
yVal = [self getCoordFromBezierPath:tVal origin:location.y p1Val:ctrlpt2.y p2Val:endpt.y];
}
return yVal;
}
- (float)getTvalFromBezierPath:(float)x x0Val:(float)x0 x1Val:(float)x1 x2Val:(float)x2 {
float tVal = (x-x0)/(2*(x1-x0));
return tVal;
}
- (float)getCoordFromBezierPath:(float)t origin: (float)origin p1Val: (float)p1 p2Val: (float)p2 {
// tVal = (sqrt((-2.0 * x * x1) + (x * x0) + (x * x2) + pow(x1, 2) - (x0 * x2)) + x0 - x1) / (x0 - (2.0 * x1) + x2);
return (pow((1-t),2) * origin) + (2 * t * (1-t) * p1) + (pow(t,2) * p2);
}
Last question: for the second Bezeir path, y-value should decrease as t-value increases. Right now, y-value keeps increasing. How should I fix this? After intensive debugging I haven't found why this is happening because everything conforms to the document.