简体   繁体   English

如何使用Cocoa Touch(iOS)图形上下文绘图正确地处理角落?

[英]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. 我只是在尝试,习惯于在iOS上使用Quartz 2D绘图。 I drew three offset squares (perimeter lines only) using Graphics Context move(to:) and addLine(_:CGPoint) functions. 我使用Graphics Context move(to :)和addLine(_:CGPoint)函数绘制了三个偏移正方形(仅边界线)。 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). 因此,我添加这些行(宽度设置为3.0)的起始位置是使用Graphics Context move(to:CGPoiint)定位的左上角。 Each subsequent corner is arrived by merely calling the addLine(_:CGPoint) method. 只需调用addLine(_:CGPoint)方法即可到达每个后续角。

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. 由于您给定的线宽为3,因此每条线将填充中心线每侧1.5个点。

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. 更好的解决方案是使用closePath()而不是添加最后一行。

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. closePath()将从路径的最后一个点到第一个点绘制一条直线。 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. 最简单的解决方案是使用UIBezierPath绘制矩形,但是手动完成所有操作是学习的好方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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