RayChen
RayChen

Reputation: 1468

How to draw two arc path without connect line?

I'm using CGMutablePath to draw a wifi logo. When I draw the second arc by addArc(center:radius:startAngle:endAngle:clockwise:transform:), it will automatically draw a line like the document specified If the path already contains a subpath, this method adds a line connecting the current point to the starting point of the arc.. How can I draw without this line? Thanks

Upvotes: 2

Views: 3330

Answers (3)

David Rönnqvist
David Rönnqvist

Reputation: 56625

If you want to draw an arc without the line from the previous point you need to move the path to the start of the arc—using move(to:)— before adding the arc. The start of the arc can be calculated as:

center.x + radius * cos(startAngle)
center.y + radius * sin(startAngle)

Rather than calculating the points to create the outline of each arc yourself, you can leverage CGPath's ability to create a stroke copy. Doing this, you only need to create the base path with one arc for each "bar" of the icon:

let basePath = CGMutablePath()

let center     = CGPoint.zero
let startAngle = CGFloat.pi * 0.75 // 135 degrees
let endAngle   = CGFloat.pi * 0.25 //  45 degrees

let radii: [CGFloat] = [10, 20, 30, 40]

for radius in radii {
    // Move to the start point of the arc
    basePath.move(to: CGPoint(x: center.x + radius * cos(startAngle),
                              y: center.y + radius * sin(startAngle)))
    // Add the arc, starting at that same point
    basePath.addArc(center: center, radius: radius,
                    startAngle: startAngle, endAngle: endAngle,
                    clockwise: true)
}

This creates a base shape like this, without any thickness:

Base path

Next, you create a copy of the base path by stroking it. Here you can configure the thickness of the icon's bars and the style of their ends (square or rounded):

let stroked = basePath.copy(strokingWithWidth: 5, // The width/thickness of each stroked arc
                            lineCap: .square,     // Make square corners for the ends of each arc
                            lineJoin: .miter, miterLimit: 0)

Resulting in a shape like this:

Stroked path

Upvotes: 9

Duncan C
Duncan C

Reputation: 131418

Yes, El Tomato told you what you need to do. Since addArc(center:radius:startAngle:endAngle:clockwise:transform:) draws a line from the last point in your path to the start of the arc, you need to use move(to:transform:) to first move to the new arc's beginning point before adding it.

It would be nice if addArc(center:radius:startAngle:endAngle:clockwise:transform:) took a flag that controlled whether it drew a line to it's starting point or not, but it doesn't seem to.

Calculating the starting point will involve a little trig.

Upvotes: 1

Mihai Fratu
Mihai Fratu

Reputation: 7663

Just use move(to:transform:) before adding the second arc. See more details here.

Upvotes: 0

Related Questions