2012-01-21 20 views
16

Tengo un conjunto de CGPoints que conforman una forma de polígono, ¿cómo puedo detectar si un solo CGPoint está dentro o fuera del polígono?Detectar si CGPoint dentro del polígono

Digamos que la forma era un triángulo y el CGPoint se movía horizontalmente, ¿cómo podía detectar cuándo cruzaba la línea del triángulo?

Puedo usar CGRectContainsPoint cuando la forma es una forma normal de 4 lados, pero no puedo ver cómo lo haría con una forma extraña.

Respuesta

27

Se puede crear un CG(Mutable)PathRef (o una UIBezierPath que envuelve un CGPathRef) de sus puntos y utilizar la función CGPathContainsPoint para comprobar si un punto está dentro de ese camino. Si usa UIBezierPath, también puede usar el método containsPoint:.

+0

¡Gracias! ¡Eso era exactamente lo que estaba buscando! – JWood

2

Para eso necesita escribir un método que implemente un punto dentro del algoritmo de polígono.

Este método tomará una matriz con N puntos (el polígono) como un argumento y un punto específico. Debería devolver verdadero si el punto está dentro del polígono y falso si no.

See this great answer on S.O.

0

Aquí es la implementación en Swift:

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

Swift 3

Una forma más sencilla utilizando Swift 3, está utilizando UIBezierPathcontains método.

Al crear una instancia de CAShapeLayer, asegúrese de establecer la accessibilityPath

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

Verificando ruta contiene la ubicación táctil.

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