Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm trying to detect if a line drawn by the user intersects itself. I'm using a line intersection detection algorithm that goes through each waypoint of the line and checks if intersects with any other point in the line.

This is a costly method and has started to produce performance problems. What would be the recommended algorithm for this problem? Is there a code example of it?

The line is represented with wayPoints which are coordinates that have been gathered by users movement on screen.

Thanks a lot for just reading this far! All help Appreciated!

    for i in 1 ..<(wayPoints.count-1) {
            for j in 0 ..< i-1 {
                   if let intersection = intersectionBetweenSegments(wayPoints[i], wayPoints[i+1], wayPoints[j], wayPoints[j+1]){
  ...}
   }
  }

    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
        }

        if ua >= 0.0 && ua <= denominator && ub >= 0.0 && ub <= denominator && denominator != 0 {
            return CGPoint(x: p0.x + ua / denominator * (p1.x - p0.x), y: p0.y + ua / denominator * (p1.y - p0.y))
        }

        return nil
    }
share|improve this question
    
Post an outline of what you are doing now –  kevin cline Mar 6 at 5:09

1 Answer 1

This is a costly method and has started to produce performance problems. What would be the recommended algorithm for this problem? Is there a code example of it?

It depends very much on how you represent the line itself. It seems that you use a broken line, that is a juxtaposition of straight lines.

The first idea that jumps to my mind is to do a simple region check. You can pack each line in a small rectangle (its bounding box) and it is very easy to check if two bounding boxes overlap or not – you can do this by doing a few subtractions, which is much cheaper than computing a determinant! If the region check fails, then the lines certainly do not intersect so you do not need to compute the determinant.

With this you should jump from complexity (nˆ4) to (nˆ2) where n is the number of tiny straight lines in your line.

If this is not enough, a second common technique is to divide the canvas in regions and represent this region as a binary tree. You start with the full canvas, then cut in halves, and then subdivide each half in two, again and again, until you reach a number of splitting you choose in advance. (You can do empirical tests to determine a value suitable for your data.) Then you can attach each line segment to a region where its bounding box fits – Typically a leaf, but it can be a higher level node if a line segment cuts a region border. Once you packed each line segment in the region tree, it is easy to retrieve neighbours of a segment line, where the intersection can take place.

share|improve this answer
    
The line is represented with wayPoints which are coordinates that have been gathered by users movement on screen. I only have one line and I'm trying to figure out whether it intersects itself so I suppose boxing approach could turn out to be difficult. –  user594883 Mar 6 at 8:06
1  
Simple region test may eliminate the number of values to check, though that simple region test you still must perform on every combination of two lines. And, if they pass the test, you will have to perform the more complicated calculation anyway. It may surprise you to know that this is not optimal –  Neil Mar 6 at 11:40
    
@user594883 Boxing is intended to be applied to the small straight lines constituting your line. –  Michael Grünewald Mar 6 at 21:33
    
@Neil I am not very surprised to know that it is not optimal. Actually, I hid in the third paragraph an improvement of the simple region test I describe in the first paragraph. –  Michael Grünewald Mar 6 at 21:47

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.