Core-Graphics (iPhone) -Can we know whether a CGPath is closed?

一曲冷凌霜 提交于 2019-12-11 03:54:40

问题


Is there any workaround to know where a CGpath (created using an array of co-ordinates) is closed.

I was not able to find any suitable method in the header CGPath.

I wish to track the path traced by user .If its a closed loop, then i wish to extract that part from the context. Something like masking or clipping the context but it should be user tracked clipping.

Thanks!


回答1:


Just in case you've been stuck on this for the last 4 1/2 years, here is how to do it in Swift 3. I have borrowed heavily from this answer. I really just added the isClosed() function.

extension CGPath {

func isClosed() -> Bool {
    var isClosed = false
    forEach { element in
        if element.type == .closeSubpath { isClosed = true }
    }
    return isClosed
}

func forEach( body: @convention(block) (CGPathElement) -> Void) {
    typealias Body = @convention(block) (CGPathElement) -> Void
    let callback: @convention(c) (UnsafeMutableRawPointer, UnsafePointer<CGPathElement>) -> Void = { (info, element) in
        let body = unsafeBitCast(info, to: Body.self)
        body(element.pointee)
    }
    print(MemoryLayout.size(ofValue: body))
    let unsafeBody = unsafeBitCast(body, to: UnsafeMutableRawPointer.self)
    self.apply(info: unsafeBody, function: unsafeBitCast(callback, to: CGPathApplierFunction.self))
}
}

And assuming path is a CGPath or CGMutablePath, here is how you use it:

path.isClosed()



回答2:


In fact, a path can consist of multiple subpaths. A new subpath is created when you move the path's current point without connecting the two points. For the path to be closed, all its subpaths must in fact be closed.

extension CGPath {

    /// Note that adding a line or curve to the start point of the current
    /// subpath does not close it. This can be visualized by stroking such a
    /// path with a line cap of `.butt`.
    public var isClosed: Bool {
        var completedSubpathsWereClosed = true
        var currentSubpathIsClosed = true

        self.applyWithBlock({ pointer in
            let element = pointer.pointee

            switch element.type {
            case .moveToPoint:
                if !currentSubpathIsClosed {
                    completedSubpathsWereClosed = false
                }

                currentSubpathIsClosed = true
            case .addLineToPoint, .addQuadCurveToPoint, .addCurveToPoint:
                currentSubpathIsClosed = false
            case .closeSubpath:
                currentSubpathIsClosed = true
            }
        })

        return completedSubpathsWereClosed && currentSubpathIsClosed
    }
}


来源:https://stackoverflow.com/questions/13743791/core-graphics-iphone-can-we-know-whether-a-cgpath-is-closed

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!