If I have an NSBezierPath
object, is there a way to get coordinates(x,y) of all the points drawn? I want to move an NSRect
along the path.

- 3,370
- 2
- 23
- 41
-
NSRect doesn't exist in `cocoa-touch`. Did you mean `CGRect`? – Richard J. Ross III Jun 30 '12 at 21:03
2 Answers
An NSBezierPath doesn't define exactly which points it draws in, but it does contain the points needed to define its pieces. You can use the elementAtIndex:associatedPoints:
method to get the points for each vector element in the path. To get each point in the path you would have to iterate over all of the elements and get the associated points. For straight lines, this method will give you the endpoint, but if you keep track of the previous point you can use as many points as you want between them.
For curves, you would need to implement the code to determine the curve's path to find points along the curve. It would be much simpler to flatten the path, using bezierPathByFlatteningPath
, which returns a new path with all curves converted into straight lines.
Here's an example which flattens a path and prints the endpoints of all lines in the result. If your path contains long straight lines, you will want to add points along lines depending on the length.
NSBezierPath *originalPath;
NSBezierPath *flatPath = [originalPath bezierPathByFlatteningPath];
NSInteger count = [flatPath elementCount];
NSPoint prev, curr;
NSInteger i;
for(i = 0; i < count; ++i) {
// Since we are using a flattened path, no element will contain more than one point
NSBezierPathElement type = [flatPath elementAtIndex:i associatedPoints:&curr];
if(type == NSLineToBezierPathElement) {
NSLog(@"Line from %@ to %@",NSStringFromPoint(prev),NSStringFromPoint(curr));
} else if(type == NSClosePathBezierPathElement) {
// Get the first point in the path as the line's end. The first element in a path is a move to operation
[flatPath elementAtIndex:0 associatedPoints:&curr];
NSLog(@"Close line from %@ to %@",NSStringFromPoint(prev),NSStringFromPoint(curr));
}
}

- 39,734
- 6
- 101
- 123
-
Thanks. was not aware of the elementAtIndex:associatedPoints: method. I have a doubt though. When i tried element count after flattening path on a bezierpath created by bezierpathWithOvalInRect. I got a number 17. How is it possible if each element can only contain one point that i'm able to create a complete oval with only 17 points. – Rakesh Jul 01 '12 at 10:30
-
It depends on the size of the oval and flatness used. If you decrease the flatness value, the lines will create a more accurate representation, which means it will need more points. – ughoavgfhw Jul 02 '12 at 22:53
No, because a path is vector based, not pixel based. You would have to render the path in a CGContextRef
, and then check which pixels got set from that. But there is no built in method for this.
If you need to move a rectangle along the path, however, you could probably use a CALayer
to do this, although I'm not entirely sure how.

- 55,009
- 24
- 135
- 201