我有一组构成多边形形状的CGPoints,如何检测单个CGPoint是在多边形的内部还是外部?
说,形状是一个三角形,CGPoint正在向右移动,我怎么能检测到它何时越过三角线?
当形状是常规的4面形状时,我可以使用CGRectContainsPoint
,但我看不出我会用奇怪的形状做到这一点。
答案 0 :(得分:27)
您可以从积分中创建CG(Mutable)PathRef
(或UIBezierPath
包裹CGPathRef
)并使用CGPathContainsPoint
函数检查点是否在该路径内。如果您使用UIBezierPath
,则还可以使用containsPoint:
方法。
答案 1 :(得分:2)
为此,您需要编写一个在多边形算法中实现点的方法。
此方法将采用具有N个点(多边形)作为参数和一个特定点的数组。如果该点在多边形内部,则应返回true,否则返回false。
答案 2 :(得分:0)
以下是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
}
}
答案 3 :(得分:0)
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))
}
}