Is there a way to get the x,y co-ordinates of all

2020-06-22 00:28发布

问题:

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.

回答1:

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));
    }
}


回答2:

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.