如何通过应用 UIBezierPath
来确定使用 CAShapeLayer
创建的形状是否为闭合轮廓?用哪个算法判断一样。
如下两张图片:一张表示它有闭合轮廓,另一张没有。
绘制第一张图片的代码如下:
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
}
}
关于ios - 在 iOS 中确定闭合轮廓的算法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37719312/