【问题标题】:Core-Graphics (iPhone) -Can we know whether a CGPath is closed?Core-Graphics (iPhone) - 我们能知道 CGPath 是否关闭吗?
【发布时间】:2019-01-07 01:07:55
【问题描述】:

是否有任何解决方法可以知道CGpath(使用坐标数组创建)关闭的位置

我无法在标题 CGPath 中找到任何合适的方法。

我希望跟踪用户跟踪的路径。如果它是一个闭环,那么我希望从上下文中提取该部分。诸如屏蔽或剪辑上下文之类的东西,但它应该是用户跟踪剪辑。

谢谢!

【问题讨论】:

  • 亲爱的巴拉,我很欣赏你的想法,但这并不是我想要的。另外链接很有用,但它仍然没有达到目的。无论如何感谢您的宝贵时间。
  • 如果您更新并解释您的问题,更具体地了解您正在寻找的内容,这可能会更有帮助..?
  • @Bala :我希望跟踪用户跟踪的路径。如果它是一个闭环,那么我希望从上下文中提取该部分。类似于屏蔽或剪辑上下文,但它应该是用户跟踪的剪辑。

标签: core-graphics


【解决方案1】:

事实上,一个路径可以包含多个子路径。当您移动路径的当前点而不连接两个点时,将创建一个新的子路径。对于要关闭的路径,它的所有子路径实际上必须是关闭的。

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
    }
}

【讨论】:

    【解决方案2】:

    以防你在过去的 4 1/2 年里一直坚持这一点,这里是如何在 Swift 3 中做到这一点。我从 this answer 借用了 大量。我真的只是添加了isClosed() 函数。

    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))
    }
    }
    

    假设pathCGPathCGMutablePath,你可以这样使用它:

    path.isClosed()
    

    【讨论】:

    • 仅仅因为一个子路径是封闭的并不意味着整个路径是封闭的,当路径由多个子路径组成时,请参阅我的答案以获得正确的实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    • 2011-11-05
    • 2012-03-07
    相关资源
    最近更新 更多