2012-01-21 55 views
16

我有一組CGPoints從而彌補了多邊形的檢測,如何檢測,如果一個CGPoint是內部或外部多邊形的?如果CGPoint內多邊形

說,表面形狀爲三角形和CGPoint在動hoizontally,我怎麼能檢測何時越過三角線?

我可以使用CGRectContainsPoint當形狀是正4邊形,但我看不到我如何與一個奇怪的形狀做。

回答

27

您可以創建一個CG(Mutable)PathRef(或包含CGPathRefUIBezierPath),並使用CGPathContainsPoint函數檢查點是否在該路徑內。如果您使用UIBezierPath,則還可以使用containsPoint:方法。

+0

謝謝!那正是我期待的! – JWood

2

對於您需要編寫一個實現多邊形內部的算法的一個點一個方法。

此方法將採取與N個點(多邊形)作爲參數,並一個特定點的陣列。如果點在多邊形內,它應該返回true,否則返回false。

See this great answer on S.O.

0

這裏是夫特實現:

extension CGPoint { 
    func isInsidePolygon(vertices:[CGPoint]) -> Bool { 
     var i = 0, j = 0, c = false, vi:CGPoint, vj:CGPoint 
     for (i = 0, j = vertices.count-1; i < vertices.count; j = i++) { 
      vi = vertices[i] 
      vj = vertices[j] 
      if (((vi.y > y) != (vj.y > y)) && 
       (x < (vj.x - vi.x) * (y - vi.y)/(vj.y - vi.y) + vi.x)) { 
        c = !c; 
      } 
     } 
     return c 
    } 
} 
0

夫特3

使用夫特3中,使用UIBezierPathcontains方法更簡單的方法。

當創建的CAShapeLayer一個實例,請務必將accessibilityPath

shapeLayer.path = bazierPath.cgPath 
shapeLayer.accessibilityPath = bazierPath 

檢查,如果路徑中包含觸摸位置。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    guard let point = touches.first?.location(in: self) else { return } 

    for shape in layer.sublayers ?? [] where shape is CAShapeLayer { 
     guard let layer = shape as? CAShapeLayer, 
      let bazier = layer.accessibilityPath else { continue } 

     // Handle touch 
     print(bazier.contains(point)) 
    } 
}