如何计算两个UIBezierpath的交集

问题描述 投票:0回答:1

我需要计算两个不规则 UIBezierpath 的交集,例如表示不规则形状的闭合路径。问题是我什至不知道如何开始。我已经搜索了可以提供帮助的库,但我发现的唯一的东西是 git 存储库缺少文件,因此它无法编译。

ios swift uibezierpath
1个回答
0
投票

我们可以在

CGPath
上使用实例方法——可以从
UIBezierPath
检索,或者更简单一点,直接使用
CGMutablePath

请参阅实例方法此处下的 Apple 文档。

但是,根据您真正想要做什么,您可能根本不需要操纵您的路径。您可以将其用作遮罩...您可以使用路径

contains(_ point: CGPoint)
...等等。

但是 - 这是一个使用

CGPath
intersection(_:using:)

的快速示例

我将做出一些假设,例如您将图像视图添加到视图子类中;跟踪触摸的开始、移动、结束;使用

CAShapeLayer
“绘制”路径轮廓;等等

看起来有点像这样(点击灰色框外的任何地方都会“剪切”路径并用绿色填充):

enter image description here


简单

UIView
子类

  • 有一个居中的图像视图,两侧有一些填充(这样我们就可以在图像外部“绘制”)
  • 绘制 2 点宽度的路径轮廓
  • 触摸结束时关闭路径
  • 有一个公共函数可以用图像视图的框架“剪辑”绘制的路径

class MyCanvasView: UIView {
    
    let imgView = UIImageView()
    
    private var myPath: CGMutablePath!
    private var shapeLayer: CAShapeLayer = CAShapeLayer()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    private func commonInit() {
        imgView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(imgView)
        
        NSLayoutConstraint.activate([
            imgView.topAnchor.constraint(equalTo: topAnchor, constant: 60.0),
            imgView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 60.0),
            imgView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -60.0),
            imgView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -60.0),
        ])
        
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.strokeColor = UIColor.systemRed.cgColor
        shapeLayer.lineWidth = 2
        self.layer.addSublayer(shapeLayer)
        
        // in case there is no image set
        imgView.backgroundColor = .systemYellow
        self.backgroundColor = UIColor(white: 0.95, alpha: 1.0)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let t = touches.first else { return }
        let pt = t.location(in: self)
        myPath = CGMutablePath()
        myPath.move(to: pt)
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.path = myPath
    }
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let t = touches.first else { return }
        let pt = t.location(in: self)
        myPath.addLine(to: pt)
        shapeLayer.path = myPath
    }
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let t = touches.first else { return }
        let pt = t.location(in: self)
        myPath.closeSubpath()
        shapeLayer.path = myPath
    }

    public func clipPath() {
        let imgPath = CGMutablePath(rect: imgView.frame, transform: nil)
        let clippedPath = imgPath.intersection(myPath)
        shapeLayer.path = clippedPath
        shapeLayer.fillColor = UIColor.green.cgColor
    }
}

测试视图控制器类

class TestPathsVC: UIViewController {
    
    let canvasView = MyCanvasView()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        canvasView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(canvasView)
        let g = view.safeAreaLayoutGuide
        NSLayoutConstraint.activate([
            canvasView.topAnchor.constraint(equalTo: g.topAnchor, constant: 40.0),
            canvasView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
            canvasView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
            canvasView.heightAnchor.constraint(equalTo: canvasView.widthAnchor),
        ])
        
        if let img = UIImage(named: "testPic") {
            canvasView.imgView.image = img
        }
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        canvasView.clipPath()
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.