Roi Mulia
Roi Mulia

Reputation: 5906

Cannot create two CGPathAddArc on the same CGMutablePathRef

I'm trying to understand why i'm seeing only one of mine CGPathAddArc.

Code :

  var r: CGRect = self.myView.bounds
 var lay: CAShapeLayer = CAShapeLayer()
        var path: CGMutablePathRef = CGPathCreateMutable()
        CGPathAddArc(path, nil, 30, 30, 30, 0, (360 * CGFloat(M_PI))/180, true    )
        CGPathAddArc(path, nil, 70, 30, 30, 0, (360 * CGFloat(M_PI))/180, true    )

        CGPathAddRect(path, nil, r2)
 CGPathAddRect(path, nil, r)
        lay.path = path
        lay.fillRule = kCAFillRuleEvenOdd
        self.myView.layer.mask = lay

result :

enter image description here

Any suggestions? Thanks!

Upvotes: 0

Views: 234

Answers (2)

gabbler
gabbler

Reputation: 13766

If you push down the command key and click on CGPathAddArc function, you will see documentation.

/* Note that using values very near 2π can be problematic. For example,
   setting `startAngle' to 0, `endAngle' to 2π, and `clockwise' to true will
   draw nothing. (It's easy to see this by considering, instead of 0 and 2π,
   the values ε and 2π - ε, where ε is very small.) Due to round-off error,
   however, it's possible that passing the value `2 * M_PI' to approximate
   2π will numerically equal to 2π + δ, for some small δ; this will cause a
   full circle to be drawn.

   If you want a full circle to be drawn clockwise, you should set
   `startAngle' to 2π, `endAngle' to 0, and `clockwise' to true. This avoids
   the instability problems discussed above. */

Setting startAngle to 0, endAngle to 2π, and clockwise to true will draw nothing. If you want a full circle to be drawn clockwise, you should set startAngle to 2π, endAngle to 0, and clockwise to true. So that you can see all circles.

Upvotes: 1

matt
matt

Reputation: 536027

What you need to do is debug. How? Well, when in doubt, your first step should be to simplify. In this case, you should start by testing your code outside the context of a mask and a fill rule. When you do, you'll see that the arcs are in fact both present. I ran this reduced version of your code:

    let lay = CAShapeLayer()
    lay.frame = CGRectMake(20,20,400,400)
    let path = CGPathCreateMutable()
    CGPathAddArc(path, nil, 30, 30, 30, 0, 
        (360 * CGFloat(M_PI))/180, true)
    CGPathAddArc(path, nil, 70, 30, 30, 0, 
        (360 * CGFloat(M_PI))/180, true)
    lay.path = path
    self.view.layer.addSublayer(lay)

And this is what I got:

enter image description here

As you can see, both arcs are present. So your results must be due to some complication beyond the drawing of the arcs.

If we add the fill rule...

    lay.fillRule = kCAFillRuleEvenOdd

...we get this:

enter image description here

And if we introduce the mask element...

    // self.view.layer.addSublayer(lay)
    self.view.layer.mask = lay

...we get this:

enter image description here

Thus, using basic tests, you should be able to convince yourself of what this part of your code does. You can now introduce more and more of your actual code until you start getting undesirable results, and then you'll know what's causing the problem.

Upvotes: 1

Related Questions