在 Swift 中使用 Core Graphics 填充多边形
Fill a polygon using Core Graphics in Swift
目标是在 Swift 中使用 Core Graphics 填充多边形。
如果所有端点都是已知的,则以下代码将执行此操作。
func drawPolySegment() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 512, height: 512))
let img = renderer.image { ctx in
let endpoints = [
CGPoint(x: 200, y: 175),
CGPoint(x: 270, y: 170),
CGPoint(x: 300, y: 100)
]
ctx.cgContext.addLines(between: endpoints)
UIColor.yellow.setFill()
ctx.cgContext.drawPath(using: .fillStroke)
}
imageView.image = img
}
但是,所需形状的端点不容易获得,因此选择了一种更通用的方法,即使用 rotate(by:)、move(to:)、addline(to:)、translate(by:)方法如下:
func drawPolygon() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 512, height: 512))
let img = renderer.image { ctx in
let apexes: CGFloat = 3 //5 //6
let length: CGFloat = 500 //190 //140
let angle: CGFloat = 2 * π / apexes
let zero: CGFloat = 0
UIColor.brown.setStroke()
UIColor.yellow.setFill()
ctx.cgContext.setLineWidth(10)
ctx.cgContext.setLineCap(.round)
ctx.cgContext.translateBy(x: 256, y: 5)
for segment in 0..<Int(apexes * 2) {
if segment == 0 {
ctx.cgContext.rotate(by: angle)
} else if segment % 2 == 0 {
ctx.cgContext.rotate(by: 2 * angle)
} else {
ctx.cgContext.rotate(by: -angle)
}
ctx.cgContext.move(to: CGPoint(x: zero, y: zero))
ctx.cgContext.addLine(to: CGPoint(x: length, y: zero))
ctx.cgContext.translateBy(x: length, y: zero)
}
ctx.cgContext.drawPath(using: .fillStroke)
}
imageView.image = img
}
上面的代码生成了一个漂亮的轮廓形状,但不会填充颜色。 "apexes" 和 "length" 注释掉的值对创建的 512 x 512 渲染有效 space。为什么形状填充第一个代码示例而不是第二个?第二个代码示例缺少什么来填充形状?
您不是在绘制多边形,而是在绘制 3 条独立的未连接线。每个 move(to:)
开始一个新的多边形。
您可以通过仅对第一段执行 move(to:)
来解决此问题:
for segment in 0..<Int(apexes * 2) {
if segment == 0 {
ctx.cgContext.rotate(by: angle)
ctx.cgContext.move(to: CGPoint(x: zero, y: zero))
} else if segment % 2 == 0 {
ctx.cgContext.rotate(by: 2 * angle)
} else {
ctx.cgContext.rotate(by: -angle)
}
ctx.cgContext.addLine(to: CGPoint(x: length, y: zero))
ctx.cgContext.translateBy(x: length, y: zero)
}
结果:
apexes: 3, length: 500
apexes: 5, length: 190
apexes: 6, length: 140
目标是在 Swift 中使用 Core Graphics 填充多边形。
如果所有端点都是已知的,则以下代码将执行此操作。
func drawPolySegment() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 512, height: 512))
let img = renderer.image { ctx in
let endpoints = [
CGPoint(x: 200, y: 175),
CGPoint(x: 270, y: 170),
CGPoint(x: 300, y: 100)
]
ctx.cgContext.addLines(between: endpoints)
UIColor.yellow.setFill()
ctx.cgContext.drawPath(using: .fillStroke)
}
imageView.image = img
}
但是,所需形状的端点不容易获得,因此选择了一种更通用的方法,即使用 rotate(by:)、move(to:)、addline(to:)、translate(by:)方法如下:
func drawPolygon() {
let renderer = UIGraphicsImageRenderer(size: CGSize(width: 512, height: 512))
let img = renderer.image { ctx in
let apexes: CGFloat = 3 //5 //6
let length: CGFloat = 500 //190 //140
let angle: CGFloat = 2 * π / apexes
let zero: CGFloat = 0
UIColor.brown.setStroke()
UIColor.yellow.setFill()
ctx.cgContext.setLineWidth(10)
ctx.cgContext.setLineCap(.round)
ctx.cgContext.translateBy(x: 256, y: 5)
for segment in 0..<Int(apexes * 2) {
if segment == 0 {
ctx.cgContext.rotate(by: angle)
} else if segment % 2 == 0 {
ctx.cgContext.rotate(by: 2 * angle)
} else {
ctx.cgContext.rotate(by: -angle)
}
ctx.cgContext.move(to: CGPoint(x: zero, y: zero))
ctx.cgContext.addLine(to: CGPoint(x: length, y: zero))
ctx.cgContext.translateBy(x: length, y: zero)
}
ctx.cgContext.drawPath(using: .fillStroke)
}
imageView.image = img
}
上面的代码生成了一个漂亮的轮廓形状,但不会填充颜色。 "apexes" 和 "length" 注释掉的值对创建的 512 x 512 渲染有效 space。为什么形状填充第一个代码示例而不是第二个?第二个代码示例缺少什么来填充形状?
您不是在绘制多边形,而是在绘制 3 条独立的未连接线。每个 move(to:)
开始一个新的多边形。
您可以通过仅对第一段执行 move(to:)
来解决此问题:
for segment in 0..<Int(apexes * 2) {
if segment == 0 {
ctx.cgContext.rotate(by: angle)
ctx.cgContext.move(to: CGPoint(x: zero, y: zero))
} else if segment % 2 == 0 {
ctx.cgContext.rotate(by: 2 * angle)
} else {
ctx.cgContext.rotate(by: -angle)
}
ctx.cgContext.addLine(to: CGPoint(x: length, y: zero))
ctx.cgContext.translateBy(x: length, y: zero)
}
结果:
apexes: 3, length: 500
apexes: 5, length: 190
apexes: 6, length: 140