append arrowhead to UIBezierPath

帅比萌擦擦* 提交于 2019-12-12 13:28:09

问题


I need your help:

I am trying to create a graph using UIBezierPaths with variable widths and consisting of a bezier curve with two control points. Now I'd like to add arrow heads to the end (right hand side) of these paths. Is there a way to do this i.e. by appending a subpath with a smaller lineWidth which contains a triangle? here is a sample picture of some paths to which I'd like to add arrowheads:

Thanks for your help!


回答1:


Let's assume you drew one of arcs like so:

UIBezierPath *path = [UIBezierPath bezierPath];

[path moveToPoint:point1];
[path addQuadCurveToPoint:point3 controlPoint:point2];

CAShapeLayer *shape = [CAShapeLayer layer];
shape.path = path.CGPath;
shape.lineWidth = 10;
shape.strokeColor = [UIColor blueColor].CGColor;
shape.fillColor = [UIColor clearColor].CGColor;
shape.frame = self.view.bounds;
[self.view.layer addSublayer:shape];

You can use atan2 to calculate the angle from the control point to the final point:

CGFloat angle = atan2f(point3.y - point2.y, point3.x - point2.x);

Note, it doesn't really matter if you use quad bezier or cubic, the idea is the same. Calculate the angle from the last control point to the end point.

You could then put an arrow head by calculating the corners of the triangle like so:

CGFloat distance = 15.0;
path = [UIBezierPath bezierPath];
[path moveToPoint:point3];
[path addLineToPoint:[self calculatePointFromPoint:point3 angle:angle + M_PI_2 distance:distance]]; // to the right
[path addLineToPoint:[self calculatePointFromPoint:point3 angle:angle          distance:distance]]; // straight ahead
[path addLineToPoint:[self calculatePointFromPoint:point3 angle:angle - M_PI_2 distance:distance]]; // to the left
[path closePath];

shape = [CAShapeLayer layer];
shape.path = path.CGPath;
shape.lineWidth = 2;
shape.strokeColor = [UIColor blueColor].CGColor;
shape.fillColor = [UIColor blueColor].CGColor;
shape.frame = self.view.bounds;
[self.view.layer addSublayer:shape];

Where we use sinf and cosf to calculate the corners like so:

- (CGPoint)calculatePointFromPoint:(CGPoint)point angle:(CGFloat)angle distance:(CGFloat)distance {
    return CGPointMake(point.x + cosf(angle) * distance, point.y + sinf(angle) * distance);
}

That yields something looking like:

Clearly, just adjust the distance parameters to control the shape of the triangle.



来源:https://stackoverflow.com/questions/30154485/append-arrowhead-to-uibezierpath

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!