检测 CGPoint 是不是在多边形内
Posted
技术标签:
【中文标题】检测 CGPoint 是不是在多边形内【英文标题】:Detect if CGPoint within polygon检测 CGPoint 是否在多边形内 【发布时间】:2012-01-21 11:05:40 【问题描述】:我有一组组成多边形的 CGPoint,我如何检测单个 CGPoint 是在多边形内部还是外部?
说,形状是三角形,而 CGPoint 是水平移动的,我如何检测它何时越过三角形线?
当形状是常规的 4 面形状时,我可以使用 CGRectContainsPoint
,但我不知道如何处理奇怪的形状。
【问题讨论】:
【参考方案1】:您可以从您的点创建一个CG(Mutable)PathRef
(或一个包装CGPathRef
的UIBezierPath
),并使用CGPathContainsPoint
函数来检查一个点是否在该路径内。如果你使用UIBezierPath
,你也可以使用containsPoint:
方法。
【讨论】:
谢谢!这正是我想要的!【参考方案2】:为此,您需要编写一种方法来实现多边形内的点算法。
此方法将使用一个包含 N 个点(多边形)的数组作为参数和一个特定点。如果点在多边形内,则返回 true,否则返回 false。
See this great answer on S.O.
【讨论】:
【参考方案3】:这是 Swift 中的实现:
extension CGPoint
func isInsidePolygon(vertices: [CGPoint]) -> Bool
guard vertices.count > 0 else return false
var i = 0, j = vertices.count - 1, c = false, vi: CGPoint, vj: CGPoint
while true
guard i < vertices.count else break
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
j = i
i += 1
return c
【讨论】:
【参考方案4】:斯威夫特 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))
【讨论】:
以上是关于检测 CGPoint 是不是在多边形内的主要内容,如果未能解决你的问题,请参考以下文章