【发布时间】:2012-03-30 12:09:56
【问题描述】:
是否有某种方法(代码或伪代码算法)可以利用 UIBezierPath 实例方法(如 appendPath)将任意数量的连接的、不同的 UIBezierPaths“合并”到一条大路径中?在具有许多路径的文档中,我试图通过减少路径数量来减小编码文件的大小,因为那里肯定有一些冗余信息。如果我找错树了,请告诉我。
【问题讨论】:
标签: objective-c ios core-graphics uibezierpath
是否有某种方法(代码或伪代码算法)可以利用 UIBezierPath 实例方法(如 appendPath)将任意数量的连接的、不同的 UIBezierPaths“合并”到一条大路径中?在具有许多路径的文档中,我试图通过减少路径数量来减小编码文件的大小,因为那里肯定有一些冗余信息。如果我找错树了,请告诉我。
【问题讨论】:
标签: objective-c ios core-graphics uibezierpath
在我的例子中,我几乎没有逻辑连接的路径,它们一起形成一个封闭的形状,我想填充这个封闭的形状。如果您只是将它们append(_:) 放在一起,则无法做到这一点,因为填充只会应用于每个路径。我查看了类似的问题,但没有一个能解决问题。所以我写了这个扩展来将逻辑连接的路径合并在一起形成一个单一的路径。
如果你有path1,path2 和path3 逻辑上形成一个封闭的形状。按相同顺序调用它们
let mergedPath = UIBezierPath()
mergedPath.merge(with: path1)
mergedPath.merge(with: path2)
mergedPath.merge(with: path3)
import UIKit
extension UIBezierPath {
func merge(with path: UIBezierPath) {
let currentPath = self.cgPath.mutableCopy()!
let lastPoint = self.lastPoint()
let firstPoint = path.firstPoint()
var index = -1
path.cgPath.applyWithBlock { block in
index += 1
let element = block.pointee
switch (element.type) {
case .moveToPoint:
if index != 0 && lastPoint != firstPoint || lastPoint == nil {
currentPath.move(to: element.points[0])
}
case .addLineToPoint:
currentPath.addLine(to: element.points[0])
case .addQuadCurveToPoint:
currentPath.addQuadCurve(to: element.points[1], control: element.points[0])
case .addCurveToPoint:
currentPath.addCurve(to: element.points[2], control1: element.points[0], control2: element.points[1])
case .closeSubpath:
currentPath.closeSubpath()
@unknown default:
fatalError()
}
}
self.cgPath = currentPath
}
func firstPoint() -> CGPoint? {
var firstPoint: CGPoint? = nil
var index = -1
self.cgPath.applyWithBlock { block in
index += 1
let element = block.pointee
if index == 0 {
if element.type == .moveToPoint || element.type == .addLineToPoint {
firstPoint = element.points[0]
} else if element.type == .addQuadCurveToPoint {
firstPoint = element.points[1]
} else if element.type == .addCurveToPoint {
firstPoint = element.points[2]
}
}
}
return firstPoint
}
func lastPoint() -> CGPoint? {
var lastPoint: CGPoint? = nil
var index = -1
self.reversing().cgPath.applyWithBlock { block in
index += 1
let element = block.pointee
if index == 0 {
if element.type == .moveToPoint || element.type == .addLineToPoint {
lastPoint = element.points[0]
} else if element.type == .addQuadCurveToPoint {
lastPoint = element.points[1]
} else if element.type == .addCurveToPoint {
lastPoint = element.points[2]
}
}
}
return lastPoint
}
}
【讨论】:
好吧,如果它只是一个美学问题...只需将第二个贝塞尔曲线的第一个点设置为第一个的最后一个点..等等..
如果不是,我认为没有办法合并 2 个或更多贝塞尔路径,因为......嗯..它们是贝塞尔,如果你这样做,它看起来不会正确
阅读有关贝塞尔曲线的更多信息 bezier curves 看看为什么它不起作用
【讨论】: