Is there an easy way to draw shapes in Swift (preferrably with Sprite-Kit) and then detect if and where they intersect? Like here's an intersecting shape:
Asked
Active
Viewed 3,409 times
8
-
and for drawing use skshapenode to which you assign the updated cgmutablepath every time it changed – CodeSmile Nov 15 '14 at 08:51
1 Answers
15
If this consists of a series of line segments, one can adapt Martin R’s answer to UIBezierPath intersect to not only detect intersections, but to also identify where the intersections are:
func intersectionBetweenSegments(_ p0: CGPoint, _ p1: CGPoint, _ p2: CGPoint, _ p3: CGPoint) -> CGPoint? {
var denominator = (p3.y - p2.y) * (p1.x - p0.x) - (p3.x - p2.x) * (p1.y - p0.y)
var ua = (p3.x - p2.x) * (p0.y - p2.y) - (p3.y - p2.y) * (p0.x - p2.x)
var ub = (p1.x - p0.x) * (p0.y - p2.y) - (p1.y - p0.y) * (p0.x - p2.x)
if (denominator < 0) {
ua = -ua; ub = -ub; denominator = -denominator
}
guard ua >= 0 && ua <= denominator && ub >= 0 && ub <= denominator && denominator != 0 else {
return nil
}
return CGPoint(x: p0.x + ua / denominator * (p1.x - p0.x), y: p0.y + ua / denominator * (p1.y - p0.y))
}
Thus, if you have an array of CGPoint
values and you want to identify all of the intersections, you could do something like:
let n = points.count - 1
for i in 1 ..< n {
for j in 0 ..< i-1 {
if let intersection = intersectionBetweenSegments(points[i], points[i+1], points[j], points[j+1]) {
// do whatever you want with `intersection`
}
}
}
For example, you can add a dot to the screen where the segments intersect:
If, however, your curve consists of cubic bezier curves, it is more complicated. You might consider, though, Checking if two cubic Bézier curves intersect.

Rob
- 415,655
- 72
- 787
- 1,044