简体   繁体   中英

How to do corners right with Cocoa Touch (iOS) Graphics Context Drawing?

I am just experimenting, getting used to drawing with Quartz 2D on iOS. I drew three offset squares (perimeter lines only) using Graphics Context move(to:) and addLine(_:CGPoint) functions. Consider the following image of the result: 在此处输入图片说明

I am only showing the top part but it is enough to document my question. You can see that the upper left corner of each square is incomplete (sharp square corners) where as the upper right looks OK. The two bottom corners are like the upper right in being exactly what I expected.

So, my starting position for adding these lines (width set to 3.0) is the upper left corner which is located using Graphics Context move(to: CGPoiint). Each subsequent corner is arrived by merely calling the addLine(_:CGPoint) method.

So, what am I doing wrong that results in the "broken" corner as shown. How do I get that upper left corner to look like all others?

Code generating diagram

override func draw(_ rect: CGRect) {
    let colors: [(CGFloat,CGFloat,CGFloat)] = 
          [(1.0,0.0,0.0),(0.25,1.0,0.5),(0.5,0.5,1.0)]
    let c = UIGraphicsGetCurrentContext()!
    c.setLineWidth(3.0)
    var dx = 0
    var dy = 0
    for q in 1...3 {
        c.move(to:CGPoint(x:dx+50, y:dy+50))
        c.addLine(to:CGPoint(x: dx+200, y: dy+50))
        c.addLine(to:CGPoint(x: dx+200, y: dy+200))
        c.addLine(to:CGPoint(x: dx+50,y: dy+200))
        c.addLine(to:CGPoint(x: dx+50,y: dy+50))
        c.setStrokeColor(
             red:colors[q-1].0
            ,green:colors[q-1].1
            ,blue:colors[q-1].2,alpha:1.0)
        c.strokePath()
        dx += 20
        dy += 20
    }
}

The artifact is caused by the thicker line width. All of the dimensions you give are for the center of each line. Since you give a line width of 3, each line is filled 1.5 points each side of the center line.

You could account for this in the first and last coordinate but that's error prone and depends on the line width.

The better solution is to use closePath() instead of adding the last line.

c.move(to:CGPoint(x:dx+50, y:dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+50))
c.addLine(to:CGPoint(x: dx+200, y: dy+200))
c.addLine(to:CGPoint(x: dx+50,y: dy+200))
//c.addLine(to:CGPoint(x: dx+50,y: dy+50)) // not needed any more
c.closePath()

closePath() will draw a straight line from the last point to the first point of the path. This also deals with properly filling in that little artifact at the join at the location of the first point.

The simplest solution is to use UIBezierPath to draw the rectangle but doing it all manually is a good way to learn.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM