2013-08-22 46 views
16

我试图找到一种方法来使用核心图形以编程方式绘制iOS 7样式的图标“圆形”形状。 我不是问如何绘制一个圆角的矩形。方圆形是superelipse:以编程方式绘制iOS 7样式的圆形

Squircle

其比常规的圆角矩形稍有不同: Rounded rectangle vs squircle

Music icon in squircle

这是确切的配方is readily available。但是,我无法弄清楚如何使用CGPath,更不用说填充它,并且能够轻松调整它的大小。所有这些都与公式完全一致。任何想法?

+0

不,我知道如何制作一个圆角矩形;我真的是一种类型为圆形的超级圆滑,因为它们用于iOS 7上的跳板图标。 –

+2

@RemyVanherweghem在iOS 7中修改了'bezierPathWithRoundedRect'方法以绘制更平滑的边角。此外,它似乎并不是一个圆形:http://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon – millimoose

+0

(也就是说,'UIBezierPath'方法不会与图标模板产生完美匹配,它们比以前更接近。) – millimoose

回答

12

引用:Superellipse

对于n = 1/2,特别地,四个弧是由两个限定的二次贝塞尔曲线轴;因此,每条弧线都是抛物线的一部分。

那么,为什么不尝试使用贝塞尔曲线近似Squircle?两条曲线(Bezier和Squircle)都由参数方程定义。

UIBezierPath Class有方法:addCurveToPoint:controlPoint1:controlPoint2:

追加三次贝塞尔曲线到接收器的路径。

注意:使用addQuadCurveToPoint:controlPoint:方法会导致更糟的结果 - 测试。

我用这个方法,这就是所发生的事情的结果:

red line - 圆角矩形,blue line - 从四肢矩形贝塞尔曲线

Rounded rectangle vs cubic Bezier curve

如果这个结果是兴趣 - 绘制下面的代码。

注:要实现更精确匹配的贝塞尔曲线,可能需要更改四个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); 
+0

很棒的回答。谢谢! –

2

这是不是一个伟大的答案,因为它没有得到的是什么你问如何绘制超椭圆的心脏**编程,但你可以:

  1. 下载SVG为iOS7图标形状在这里:http://dribbble.com/shots/1127699-iOS-7-icon-shape-PSD
  2. 它导入到您的Xcode项目
  3. 添加PocketSVG到您的项目:https://github.com/arielelkin/PocketSVG
  4. 装入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

0

这将是很容易在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

相关问题