我试图找到一种方法来使用核心图形以编程方式绘制iOS 7样式的图标“圆形”形状。 我不是问如何绘制一个圆角的矩形。方圆形是superelipse:以编程方式绘制iOS 7样式的圆形
其比常规的圆角矩形稍有不同:
这是确切的配方is readily available。但是,我无法弄清楚如何使用CGPath,更不用说填充它,并且能够轻松调整它的大小。所有这些都与公式完全一致。任何想法?
我试图找到一种方法来使用核心图形以编程方式绘制iOS 7样式的图标“圆形”形状。 我不是问如何绘制一个圆角的矩形。方圆形是superelipse:以编程方式绘制iOS 7样式的圆形
其比常规的圆角矩形稍有不同:
这是确切的配方is readily available。但是,我无法弄清楚如何使用CGPath,更不用说填充它,并且能够轻松调整它的大小。所有这些都与公式完全一致。任何想法?
引用:Superellipse
对于n = 1/2,特别地,四个弧是由两个限定的二次贝塞尔曲线轴;因此,每条弧线都是抛物线的一部分。
那么,为什么不尝试使用贝塞尔曲线近似Squircle?两条曲线(Bezier和Squircle)都由参数方程定义。
UIBezierPath Class有方法:addCurveToPoint:controlPoint1:controlPoint2:
追加三次贝塞尔曲线到接收器的路径。
注意:使用addQuadCurveToPoint:controlPoint:
方法会导致更糟的结果 - 测试。
我用这个方法,这就是所发生的事情的结果:
red line
- 圆角矩形,blue line
- 从四肢矩形贝塞尔曲线
如果这个结果是兴趣 - 绘制下面的代码。
注:要实现更精确匹配的贝塞尔曲线,可能需要更改四个corner points
(现在它们对应于其中刻有该图的矩形的角度)的坐标。
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
//set rect size for draw
float rectSize = 275.;
CGRect rectangle = CGRectMake(CGRectGetMidX(rect) - rectSize/2, CGRectGetMidY(rect) - rectSize/2, rectSize, rectSize);
//Rounded rectangle
CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);
UIBezierPath* roundedPath = [UIBezierPath bezierPathWithRoundedRect:rectangle cornerRadius:rectSize/4.7];
[roundedPath stroke];
//Rectangle from Fours Bezier Curves
CGContextSetStrokeColorWithColor(context, [UIColor blueColor].CGColor);
UIBezierPath *bezierCurvePath = [UIBezierPath bezierPath];
//set coner points
CGPoint topLPoint = CGPointMake(CGRectGetMinX(rectangle), CGRectGetMinY(rectangle));
CGPoint topRPoint = CGPointMake(CGRectGetMaxX(rectangle), CGRectGetMinY(rectangle));
CGPoint botLPoint = CGPointMake(CGRectGetMinX(rectangle), CGRectGetMaxY(rectangle));
CGPoint botRPoint = CGPointMake(CGRectGetMaxX(rectangle), CGRectGetMaxY(rectangle));
//set start-end points
CGPoint midRPoint = CGPointMake(CGRectGetMaxX(rectangle), CGRectGetMidY(rectangle));
CGPoint botMPoint = CGPointMake(CGRectGetMidX(rectangle), CGRectGetMaxY(rectangle));
CGPoint topMPoint = CGPointMake(CGRectGetMidX(rectangle), CGRectGetMinY(rectangle));
CGPoint midLPoint = CGPointMake(CGRectGetMinX(rectangle), CGRectGetMidY(rectangle));
//Four Bezier Curve
[bezierCurvePath moveToPoint:midLPoint];
[bezierCurvePath addCurveToPoint:topMPoint controlPoint1:topLPoint controlPoint2:topLPoint];
[bezierCurvePath moveToPoint:midLPoint];
[bezierCurvePath addCurveToPoint:botMPoint controlPoint1:botLPoint controlPoint2:botLPoint];
[bezierCurvePath moveToPoint:midRPoint];
[bezierCurvePath addCurveToPoint:topMPoint controlPoint1:topRPoint controlPoint2:topRPoint];
[bezierCurvePath moveToPoint:midRPoint];
[bezierCurvePath addCurveToPoint:botMPoint controlPoint1:botRPoint controlPoint2:botRPoint];
[bezierCurvePath stroke];
CGContextRestoreGState(context);
很棒的回答。谢谢! –
这是不是一个伟大的答案,因为它没有得到的是什么你问如何绘制超椭圆的心脏**编程,但你可以:
装入SVG,并将其转换为一个UIBezierPath,从那里你可以缩放和但是变换你喜欢:
PocketSVG *myVectorDrawing = [[PocketSVG alloc] initFromSVGFileNamed:@"iOS_7_icon_shape"];
UIBezierPath *myBezierPath = myVectorDrawing.bezier;
// Apply your transforms here:
[myBezierPath applyTransform:CGAffineTransformMakeScale(2.5, 2.5)];
[myBezierPath applyTransform:CGAffineTransformMakeTranslation(10, 50)];
CAShapeLayer *myShapeLayer = [CAShapeLayer layer];
myShapeLayer.path = myBezierPath.CGPath;
myShapeLayer.strokeColor = [[UIColor redColor] CGColor];
myShapeLayer.lineWidth = 2;
myShapeLayer.fillColor = [[UIColor clearColor] CGColor];
[self.view.layer addSublayer:myShapeLayer];
**这也许值得一提的是,形状可能不是一个确切的超椭圆反正:http://i.imgur.com/l0ljVRo.png
这将是很容易在OpenGL ES做的着色器。只需绘制一个四边形并将x和y作为顶点属性。在片段着色器中,将x和y插入等式中。如果结果< = 1,则片段在形状内。如果我可以得到一些空闲时间,我可以尝试这个并在这里发布。
如果你想使用CGPath,我认为关键是参数化x和y的t,从0到2π。然后定期评估x和y。我也会在空闲时间试图弄清楚这一点,但是我的数学有点生疏。
顺便说一句,我敢肯定,苹果是而不是使用这个公式。看到@millimoose发布的链接:维基百科http://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon
不,我知道如何制作一个圆角矩形;我真的是一种类型为圆形的超级圆滑,因为它们用于iOS 7上的跳板图标。 –
@RemyVanherweghem在iOS 7中修改了'bezierPathWithRoundedRect'方法以绘制更平滑的边角。此外,它似乎并不是一个圆形:http://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon – millimoose
(也就是说,'UIBezierPath'方法不会与图标模板产生完美匹配,它们比以前更接近。) – millimoose