我设计了以下代码来生成UIBezierPath
。此路径用于CAShapeLayer
中以屏蔽UIView
。注意,视图的高度和宽度是可变的。
这段代码生成了一个三角形与尖锐的边缘,但我想使角落圆角。我已经尝试了addArcWithCenter...
,lineCapStyle
和lineJoinStyle
等,但似乎没有什么适合我。
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
CGPoint center = CGPointMake(rect.size.width / 2, 0);
CGPoint bottomLeft = CGPointMake(10, rect.size.height - 0);
CGPoint bottomRight = CGPointMake(rect.size.width - 0, rect.size.height - 0);
[bezierPath moveToPoint:center];
[bezierPath addLineToPoint:bottomLeft];
[bezierPath addLineToPoint:bottomRight];
[bezierPath closePath];
字符串
如何在UIBezierPath
中圆化三角形的所有边?我需要子层,多个路径等吗?
我没有绘制此BezierPath,因此drawRect
中的所有CGContext...
函数在此上下文中都没有用
8条答案
按热度按时间sigwle7e1#
编辑
**FWIW:**这个答案解释了
CGPathAddArcToPoint(...)
为你做了什么,起到了教育的作用。我强烈建议你通读它,因为它将帮助你理解和欣赏CGPath API。然后你应该继续使用它,就像在an0's answer中看到的那样,而不是在你的应用程序中圆边时使用这个代码。如果你想玩和学习这样的几何计算,这个代码只应该用作参考。原始答案
因为我觉得这样的问题很有趣,所以我必须回答它:)
这是一个很长的答案。没有简短的版本:D
这一切都是从一个三角形开始的,你想用某个半径,r 来圆化它的角:
x1c 0d1x的数据
圆角三角形应该包含在尖三角形中,所以第一步是找到尽可能靠近角的位置,在那里你可以用半径r拟合一个圆。
一个简单的方法是创建3条平行于三角形中3条边的新直线,并将每个距离 r 向内移动,与原始边的边正交。
要执行此操作,请计算每条线的斜率/Angular 以及要应用于两个新点的偏移:
字符串
然后将偏移量添加到每条线的起点和终点:
型
当你这样做的时候,你会看到这三条线在三个地方相交:
的
每个交点正好是距离 r 的两个边 (假设三角形足够大,如上所述)。
可以计算两条直线的交点:
型
其中,(x1,y1)至(x2,y2)是第一线,(x3,y3)至(x4,y 4)是第二线。
如果你在每个交点上放一个半径为 r 的圆,你可以看到它确实适用于圆角三角形(忽略三角形和圆的不同线宽):
的
现在要创建圆角三角形,您需要在原始三角形与交点正交的点上创建一条从直线到圆弧再到直线(等等)的路径。这也是圆与原始三角形相切的点。
已知三角形中所有三条边的斜率、圆角半径和圆心(交点),每个圆角的起始角和终止角都是该边的斜率- 90度。为了将这些东西组合在一起,我在代码中创建了一个结构体,但如果你不想这样做,可以不必这样做:
型
为了减少代码重复,我为自己创建了一个方法,该方法计算一个点的交点和Angular ,给定一条从一个点经过另一个点到最终点的直线(它不是闭合的,所以它不是三角形):
型
代码如下(实际上只是我上面展示的代码,放在一起):
型
然后,我使用该代码3次来计算3个角:
型
现在,有了所有必要的数据,开始我们创建实际路径的部分。我将依赖于CGPathAddArc将添加从当前点到起点的直线的事实,而不必自己绘制这些线(这是记录的行为)。
我唯一需要手动计算的点是路径的起点。我选择右下角的起点(没有具体原因)。从那里你只需添加一个弧,圆心在起点和终点的交点上:
型
看起来像这样:
x1c4d 1x的
没有所有支持线的最终结果,看起来像这样:
型
btqmn9zl2#
@大卫的几何很酷,也很有教育意义。但你真的不需要这样遍历整个几何。我将提供一个简单得多的代码:
字符串
bezierPath
是你需要的。关键是CGPathAddArcToPoint
为你做几何。ukdjmx9f3#
Swift 4中的圆角三角形
基于@an0的answer的Playground。
x1c 0d1x的数据
字符串
tsm1rwdh4#
@an0 -谢谢你!我是全新的,所以我没有声誉标记为有用或评论,但你今天为我节省了大量的时间。
我知道这超出了问题的范围,但同样的逻辑适用于
CGContextBeginPath()
,CGContextMoveToPoint()
,CGContextAddArcToPoint()
和CGContextClosePath()
,以防任何人需要使用它。如果有人感兴趣的话,这里是我写的一个指向右边的等边三角形的代码。
triangleFrame
是预定义的CGRect
,radius
是预定义的CGFloat
。字符串
当然,对于不规则三角形,每个点都可以更具体地定义。然后您可以根据需要
CGContextFillPath()
或CGContextStrokePath()
。vc6uscn95#
雨燕中的圆角三角
根据@invisible squirrel的回答,我写了一个UIView扩展。
字符串
aamkag616#
对于任何想要基于SwiftUI的解决方案的人,这里有一个根据@Anjali的答案改编的
Shape
。它可以在任何使用常规SwiftUI形状(如Circle
或Ellipse
)的地方使用。字符串
1l5u6lss7#
基于@大卫的answer,我写了一个
UIBezierPath
扩展,它添加了与CGPath相同的功能:字符串
因此,代码应该是这样的:
型
lbsnaicq8#
简单得多的方法就是添加两行代码:
字符串
编辑:
要看到角是圆的,你需要使三角形比矩形边界小一点:
型