2013-08-22 9 views
16

コアグラフィックスを使用して、プログラム上でiOS 7スタイルのアイコン「squircle」を描く方法を見つけようとしています。 丸い四角形を描く方法を質問していません。定期的な丸みを帯びた長方形より若干異なるiOS 7スタイルスクエアールをプログラムで描画する

Squircle

Rounded rectangle vs squircle

Music icon in squircle

それは正確な式is readily availableだsquircleはsuperelipseあります。しかし、私はCGPathを使ってこれを描画する方法を理解することはできません。それを埋めることはできませんし、むしろ簡単にサイズを変更することができます。これはすべて式と完全に一致しています。何か案が?それはsuperellipseを描画する方法である何を求めているの心に取得していないので、

+0

いいえ丸い四角形の作り方は分かっていますが、私は実際にはタイプsquircleの超楕円体で、iOS 7の跳ね橋のアイコンとして使用しています。 –

+2

@RemyVanherweghem iOS 7では、 'bezierPathWithRoundedRect'メソッドが変更され、よりスムーズなコーナーが描かれました。また、それはsquircleではないようです:http://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon – millimoose

+0

(つまり、 'UIBezierPath'メソッドアイコンテンプレートと完全に一致するものはありません。以前よりももっと近づいています)。 – millimoose

答えて

12

引用:投稿@millimooseリンク参照Superellipse

についてN = 1/2、特に4つの弧の各々は、二次ベジエ曲線 2で定義されます軸;結果として、各円弧は放物線のセグメントです。

なぜ、Squircleをベジェ曲線で近似しようとしないのですか?両方の曲線(ベジェとスクエア)は、パラメトリック方程式によって定義されます。

UIBezierPath Classは方法があります:addCurveToPoint:controlPoint1:controlPoint2:

は、受信機のパス立方ベジェ曲線を追加します。

注:addQuadCurveToPoint:controlPoint:メソッドを使用すると、結果が悪化します。

私は、このメソッドを使用し、それが結果として何が起こったのです。

red line - 角丸矩形、blue line - 矩形を四つんばいベジェ曲線

Rounded rectangle vs cubic Bezier curve

から、この結果は関心がある場合 - 以下のコードを描画します。

注:より正確なマッチングを実現するには、4つの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アイコン形状のため:Xcodeプロジェクト
  2. からhttp://dribbble.com/shots/1127699-iOS-7-icon-shape-PSD
  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]; 
    

**これは、形状がとにかく正確superellipseではないかもしれないことは注目に値します多分:http://i.imgur.com/l0ljVRo.png

0

これは、シェーダでのOpenGL ESに行うのはかなり簡単だろう。クワッドを描き、頂点の属性としてxとyを渡します。フラグメントシェーダで、xとyを方程式に差し込みます。結果が< = 1の場合、フラグメントは形状の内側にあります。私はいくつかの自由な時間を得ることができる場合、私はこれを試して、ここに投稿するかもしれません。

CGPathを使いたいのであれば、xとyのパラメータを0から2πまでのtでパラメータ化することが重要だと思います。次に、xとyを一定の間隔で評価する。私は自由時間にこれを理解しようとしますが、私の数学は一種の錆びたものです。

私はAppleがではないことを確信しています。この式を使用しています。ウィキペディアからhttp://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon

関連する問題