26

コア グラフィックスを使用して、iOS 7 スタイルのアイコン「リス」形状をプログラムで描画する方法を見つけようとしています。角丸四角形を描く方法を尋ねているのではありません。リスは超楕円です。

リス

これは、通常の角丸長方形とは少し異なります。 角丸長方形 vs リス

リスの音楽アイコン

その正確な式はすぐに入手できます。ただし、CGPath などを使用してこれを描画する方法を理解することはできません。塗りつぶすことはもちろん、サイズを簡単に変更することもできません。これはすべて、式に完全に正確である間です。

4

8 に答える 8

16

ウィキペディアからの引用: Superellipse

特に n = 1/2 の場合、4 つの円弧のそれぞれは、2 つの軸によって定義される 2次ベジエ曲線です。その結果、各円弧は放物線のセグメントになります。

それでは、ベジエ曲線を使用して Squircle を近似してみませんか? 両方の曲線 (Bezier と Squircle) は、パラメトリック方程式によって定義されます。

UIBezierPath クラスにはメソッドがあります:addCurveToPoint:controlPoint1:controlPoint2:

受信者のパスに 3 次ベジエ曲線を追加します。

注: このaddQuadCurveToPoint:controlPoint:方法を使用すると結果が悪化します - テスト済みです。

この方法を使用した結果、次のようになりました。

red line- 角丸四角形、blue line- 四角ベジエ曲線からの四角形

角丸長方形 vs 立方ベジエ曲線

この結果に興味がある場合は、以下のコードを描画してください。

注: より正確に一致させるには、ベジエ曲線で 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);
于 2013-12-19T16:47:27.913 に答える
2

プログラムで超楕円**を描画する方法を尋ねているものの核心に到達しないため、これは素晴らしい答えではありませんが、次のことができます。

  1. ここから iOS7 アイコン形状の SVG をダウンロードしてください: 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

于 2013-10-18T18:54:34.887 に答える
0

これは、シェーダーを使用して OpenGL ES で行うのは非常に簡単です。クワッドを描画し、x と y を頂点属性として渡すだけです。フラグメント シェーダーで、x と y を式に代入します。結果 <= 1 の場合、フラグメントは形状の内側にあります。自由な時間があれば、これを試してここに投稿するかもしれません。

CGPath を使用する場合、キーは x と y を t でパラメーター化することだと思います。t は 0 から 2π になります。次に、一定間隔で x と y を評価します。私も自由な時間にこれを理解しようとしますが、私の数学はちょっと錆びています.

ところで、Apple がこの式を使用していないことは確かです。@millimoose が投稿したリンクを参照してください: http://blog.mikeswanson.com/post/62341902567/unleashing-genetic-algorithms-on-the-ios-7-icon

于 2013-12-18T17:12:49.287 に答える