ios - 在 iOS 中确定闭合轮廓的算法

标签 ios objective-c algorithm uibezierpath cashapelayer

如何通过应用 UIBezierPath 来确定使用 CAShapeLayer 创建的形状是否为闭合轮廓?用哪个算法判断一样。

如下两张图片:一张表示它有闭合轮廓,另一张没有。

具有闭合轮廓的图像: enter image description here

没有闭合轮廓的图像: enter image description here

绘制第一张图片的代码如下:

UIBezierPath *mainPath =[UIBezierPath bezierPath];

[mainPath addArcWithCenter:CGPointMake(120, 120) radius:50 startAngle:DEGREES_TO_RADIANS(0) endAngle:DEGREES_TO_RADIANS(90) clockwise:YES];
[mainPath addArcWithCenter:CGPointMake(120,120) radius:50 startAngle:DEGREES_TO_RADIANS(90) endAngle:DEGREES_TO_RADIANS(180) clockwise:YES];
[mainPath addLineToPoint:CGPointMake(170, 120)];

CAShapeLayer *sLayer = [CAShapeLayer layer];
sLayer.strokeColor = [UIColor blueColor].CGColor;
sLayer.path = mainPath.CGPath;
sLayer.fillColor = [UIColor clearColor].CGColor;
[[self.view layer] addSublayer:sLayer];

对于其他有删除线:

[mainPath addLineToPoint:CGPointMake(170, 120)];

最佳答案

import Foundation
import UIKit

class DetectClosedCurve :UIView  {

    override init(frame: CGRect){
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func draw(_ rect: CGRect) {
        super.draw(rect)
        self.backgroundColor = UIColor.brown
        UIColor.white.setStroke()
        UIColor.red.setFill()
        let currentContext = UIGraphicsGetCurrentContext()
        currentContext?.saveGState()

        let closePath = drawClosedPath()
        closePath.lineWidth = 2
        closePath.fill()
        closePath.stroke()


        let openPath = drawOpenPath()
        openPath.lineWidth = 2
        openPath.fill()
        openPath.stroke()

        currentContext?.restoreGState()

         let status = openPath.isClosedCurve()
         print("  closePath status  == \(status)")

         let statusClose = closePath.isClosedCurve()
         print("  closePath status == \(statusClose)")

    }

    func drawClosedPath() -> UIBezierPath {

        let path = UIBezierPath()
        path.addArc(withCenter: CGPoint(x:120,y:120), radius: 50, startAngle: CGFloat(0.degreesToRadians), endAngle: CGFloat(90.degreesToRadians) , clockwise: true)
        path.addArc(withCenter: CGPoint(x:120,y:120), radius: 50, startAngle: CGFloat(90.degreesToRadians), endAngle: CGFloat(180.degreesToRadians), clockwise: true)
        path.addLine(to: CGPoint(x:170,y:120))
        //        mainPath addLineToPoint:CGPointMake(170, 120
        path.close()
        return path

    }


    func drawOpenPath() -> UIBezierPath {
        let path = UIBezierPath()
        path.addArc(withCenter: CGPoint(x:200,y:200), radius: 50, startAngle: CGFloat(0.degreesToRadians), endAngle: CGFloat(90.degreesToRadians) , clockwise: true)
        path.addArc(withCenter: CGPoint(x:200,y:200), radius: 50, startAngle: CGFloat(90.degreesToRadians), endAngle: CGFloat(180.degreesToRadians), clockwise: true)
        return path
    }


}

extension Int {
    var degreesToRadian: Double { return Double(self) * .pi / 180 }
    var radiansToDegree: Double { return Double(self) * 180 / .pi }
}

extension FloatingPoint {
    var degreesToRadian: Self { return self * .pi / 180 }
    var radiansToDegree: Self { return self * 180 / .pi }
}


extension CGPath {
    func forEachs( body: @convention(block) (CGPathElement) -> Void) {
        typealias Body = @convention(block) (CGPathElement) -> Void
        func callback(info: UnsafeMutableRawPointer?, element: UnsafePointer<CGPathElement>) {
            let body = unsafeBitCast(info, to: Body.self)
            body(element.pointee)
        }
        let unsafeBody = unsafeBitCast(body, to: UnsafeMutableRawPointer.self)
        apply(info: unsafeBody, function: callback)
    }
}
extension UIBezierPath {
    func isClosedCurve() -> Bool {
        var isClosedCurve: Bool = false

        cgPath.forEach { element in

            if(element.type == .closeSubpath){
                isClosedCurve = true

            }
        }
        return isClosedCurve
    }
}

enter image description here

enter image description here

Demo App to check closed Contour

关于ios - 在 iOS 中确定闭合轮廓的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37719312/

相关文章:

algorithm - 反向多重索引

java - 额外字符串比较与 HashMap 查找的性能

iphone - UITableViewCell 具有背景图像和动态高度

ios - 将标题分配给 UIViewController 时发生了一些奇怪的事情

java - 这个Java算法如何更快

objective-c - 按下按钮后更新 Cocoa/Objective C 中的屏幕

iphone 开发 : when I analyze my app I have potential leak issue

Xcode 6.4 中的 iOS 模拟器显示多个版本并且名称中有长 "id"

ios - 从服务器获取 JSON 数据后,UICollectionViewCell 不可点击

ios - 无法从 GET 请求将数据附加到数组