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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With