【问题标题】:append arrowhead to UIBezierPath将箭头附加到 UIBezierPath
【发布时间】:2015-05-10 17:33:47
【问题描述】:

我需要你的帮助:

我正在尝试使用具有可变宽度的 UIBezierPaths 创建一个图形,该图形由具有两个控制点的贝塞尔曲线组成。现在我想在这些路径的末端(右侧)添加箭头。有没有办法做到这一点,即通过附加一个包含三角形的较小线宽的子路径? 这是我想添加箭头的一些路径的示例图片:

感谢您的帮助!

【问题讨论】:

    标签: objective-c uibezierpath quartz-core


    【解决方案1】:

    假设你画了这样一条弧线:

    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];
    

    您可以使用atan2计算从控制点到终点的角度:

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

    注意,使用四边形贝塞尔曲线或三次曲线并不重要,想法是一样的。计算最后一个控制点到终点的角度。

    然后您可以通过计算三角形的角来放置箭头,如下所示:

    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];
    

    我们使用sinfcosf 来计算角点,如下所示:

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

    这会产生如下所示的内容:

    显然,只需调整distance参数即可控制三角形的形状。

    【讨论】:

    • 谢谢,罗伯!这就是我一直在寻找的(实际上忘了提及关于控制点的部分——我会这样做——谢谢你指出这一点。)但是,我仍然不明白你的一段代码:[ self.arrowShape removeFromSuperlayer];这是做什么的?
    • 哦,忽略这个。那是一些不相关的代码。现在没了。
    • 多么棒的答案。我使用您的代码为箭头构造 Bezier 路径,然后填充它。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-03
    相关资源
    最近更新 更多