Reputation: 819
I have a UIBezierPath that I need to get point y when I set point x
thanks
Upvotes: 2
Views: 1627
Reputation: 2180
@nullp01nter Thanks for your nice answer. Exactly what i needed! :) Here is my Swift version of it as Extension for Arrays with PointXYs:
protocol PointXY {
var x : CGFloat { get set }
var y : CGFloat { get set }
}
extension CGPoint: PointXY { }
extension Array where Element: PointXY {
func getYValue(forX x: CGFloat) -> CGFloat? {
for index in 0..<(self.count - 1) {
let p1 = self[index]
let p2 = self[index + 1]
// return p.y if a p.x matches x
if x == p1.x { return p1.y }
if x == p2.x { return p2.y }
// if x is between p1.x and p2.x calculate interpolated value
if x > p1.x && x < p2.x {
let x1 = p1.x
let x2 = p2.x
let y1 = p1.y
let y2 = p2.y
return (x - x1) / (x2 - x1) * (y2 - y1) + y1
}
}
return nil
}
}
Upvotes: 1
Reputation: 521
You will need to interpolate between the points. To access the points, it would be easiest to have them stored into an NSMutableArray
. Create this array and add all CGPoints while you add them to your UIBezierPath
in your drawing routine. If this is not possible, see here on how to extract points from a UIBezierPath
. See code below on how to achieve what you want:
-(float)getYValueFromArray:(NSArray*)a atXValue:(float)x
{
NSValue *v1, *v2;
float x1, x2, y1, y2;
// iterate through all points
for(int i=0; i<([a count]-1); i++)
{
// get current and next point
v1 = [a objectAtIndex:i];
v2 = [a objectAtIndex:i+1];
// return if value matches v1.x or v2.x
if(x==[v1 CGPointValue].x) return [v1 CGPointValue].y;
if(x==[v2 CGPointValue].x) return [v2 CGPointValue].y;
// if x is between v1.x and v2.x calculate interpolated value
if((x>[v1 CGPointValue].x) && (x<[v2 CGPointValue].x))
{
x1 = [v1 CGPointValue].x;
x2 = [v2 CGPointValue].x;
y1 = [v1 CGPointValue].y;
y2 = [v2 CGPointValue].y;
return (x-x1)/(x2-x1)*(y2-y1) + y1;
}
}
// should never reach this point
return -1;
}
-(void)test
{
NSMutableArray *a = [[NSMutableArray alloc] init];
[a addObject:[NSValue valueWithCGPoint:CGPointMake( 0, 10)]];
[a addObject:[NSValue valueWithCGPoint:CGPointMake(10, 5)]];
[a addObject:[NSValue valueWithCGPoint:CGPointMake(15, 20)]];
[a addObject:[NSValue valueWithCGPoint:CGPointMake(20, 30)]];
[a addObject:[NSValue valueWithCGPoint:CGPointMake(35, 50)]];
[a addObject:[NSValue valueWithCGPoint:CGPointMake(50, 0)]];
float y = [self getYValueFromArray:a atXValue:22.5];
NSLog(@"Y value at X=22.5 is %.2f", y);
}
Upvotes: 3