6

I hope it is the right place to ask this. I wasn't sure if it belongs to Stack Overflow or Computer Science.
Eventually this seemed more suitable.

Anyway, some background first:
A closed curve, is a curve with no endpoints and which completely encloses an area.
A simple curve, is a curve that does not cross itself.

Example:

enter image description here

Now, given n ordered (x,y) coordinates that represents mouse movement, it is easy to determine if they form a closed curve (given an upper bound on the allowed distance between two points, of-course), but is there an algorithm that will determine whether or not the coordinates form a simple curve?

I tried to look online for an answer, but couldn't find relevant solutions.

3 Answers3

4

You could argue that a curve is simple if there are no two line segments between points such that the lines intersect, meaning you could check if a curve is simple by verifying the absence of this condition.

The algorithm would look something like:

for each p1, p2 in pointlist
  for each p3, p4 in pointlist
     if line_segment(p1, p2) intersects line_segment(p3, p4)
        return false
return true   

Note that p2 would be the successive point after p1 and similarly, p4 would be the successive point after p3. In order to avoid redundancy, points p3 and p4 could start after points p1 and p2. This should be easily done in O(n^2) time. Be careful in your check for intersection since at least once the lines will be the same (no dividing by zero).

If you have many such points, you could skip every other point and this algorithm will run 4 times faster at the small risk that a truly intersecting line may not be detected should the curve approach a tangent.

Neil
  • 22,848
3

You can check each point pair P[i],P[i+1] against each point pair P[j],P[j+1]

If any of the lines segments they create intersect then the curve is not simple.

Naively check each line:

for(int i = 0; i < n-3; i++)
    for(int j = i+2; j < n-1; j++)
        if(doIntersect(new Line(P[i],P[i+1]), new Line(P[j],P[j+1]));

I skip checking P[i],P[i+1] against P[i+1],P[i+2] because they always intersect on the endpoint P[i+1]

This algorithm can be sped up by sorting the list of segments by left most x and then only check lines that have an endpoint left of the rightmost x of the current segment.

ratchet freak
  • 25,986
1

The concept may be simple, but there are many devilish details.

To begin with, you have to stipulate that the numbers representing the points are exact, not approximations to some real curve, and that the outline consists of straight line segments, not an actual curve.

Second, boundary conditions are everywhere; if line AB touches line DEF only at point E, does that count as a cross or not? You need to consider the overall geometry of the figure. Consider a "C" shaped figure with a pseudopod extending from the back, around to enter the "mouth" of the C, and now gradually close the jaws of the C to meet at a single point.

ddyer
  • 4,078