Определить, находится ли CGPoint внутри полигона - PullRequest
18 голосов
/ 21 января 2012

У меня есть набор CGPoints, которые составляют многоугольник, как я могу определить, находится ли один CGPoint внутри или снаружи многоугольника?

Скажем, фигура была треугольником и CGPoint двигалсяПо горизонтали, как я могу определить, когда она пересекает линию треугольника?

Я могу использовать CGRectContainsPoint, когда фигура является правильной 4-сторонней, но я не вижу, как бы это сделать со странной формой..

Ответы [ 4 ]

27 голосов
/ 21 января 2012

Вы можете создать CG(Mutable)PathRef (или UIBezierPath, который включает CGPathRef) из ваших точек и использовать функцию CGPathContainsPoint, чтобы проверить, находится ли точка внутри этого пути.Если вы используете UIBezierPath, вы также можете использовать метод containsPoint:.

2 голосов
/ 21 января 2012

Для этого вам нужно написать один метод, который реализует точку внутри алгоритма многоугольника.

Этот метод будет принимать массив с N точками (многоугольник) в качестве аргумента и одну конкретную точку.Он должен возвращать true, если точка находится внутри многоугольника, и false, если нет.

См. Этот великолепный ответ на SO

0 голосов
/ 12 сентября 2017

Swift 3

Более простой способ с использованием Swift 3 - это метод UIBezierPath contains.

При создании экземпляра 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))
    }
}
0 голосов
/ 25 мая 2015

Вот реализация в 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
    }
}
...