4

I'm looking for an algorithm to test whether or not a polygon is 'strictly' simple. Usually the test involves checking for intersection between any of the polygon segments. But here, since I want to check for cases that don't always fall under edge-edge intersection, I'm not too sure what to look for.enter image description here

In the above image, B C and D aren't simple polygons, but only D would fail the intersection test. My terminology (in terms of strictly simple) may be a little off as well, but I think the picture illustrates what I mean.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Prismatic
  • 3,338
  • 5
  • 36
  • 59
  • 2
    Just check for vertex-edge intersections, as well as edge-edge intersections. – Beta Apr 01 '12 at 19:52
  • 1
    B and C should also fail the edge intersection check if there's an actual intersection. A corner being "really close" to an edge doesn't count as an intersection, right? @Beta: A point cannot intersect with anything. What do you mean? – Matti Virkkunen Apr 01 '12 at 19:53
  • Are you runnning C++ in the .Net/CLR Framework? – Erik Philips Apr 01 '12 at 19:54
  • Matti: If the intersection check includes the segment endpoints, wouldn't all polygons fail the test? If I ignore the immediately adjacent segments, then it'd work, but I'm not sure if there are any cases that I haven't thought of where doing that would cause an issue. Erik: No, c++ with gcc – Prismatic Apr 01 '12 at 20:03
  • Not really a programming question, is it? IMO it belongs on [math.SE](http://math.stackexchange.com). – leftaroundabout Apr 01 '12 at 20:28
  • Better answers here: https://math.stackexchange.com/q/80798/414894 – Cris Luengo Feb 18 '22 at 17:00

3 Answers3

1

Say two lines do intersect if they have at least a common point.

Take one edge and count the intersections with any other edges. If it has

  • 2 intersections, then it has one edge left and one edge right and everything is good.
  • more than 2 intersections, then it has either more than two edges starting at the end points (case B), an endpoint of an edge in the middle (case C) or an intersection with another line (case D).

So in my opinion, your worries are ill-founded:

But here, since I want to check for cases that don't always fall under edge-edge intersection [...]

This approach works here too.

ipc
  • 8,045
  • 29
  • 33
0

Case F: The vertices form a closed loop, and are given in CCW order. This can be done by looping through all the vertices, and summing up the joint angles. I choose revolutions as my angular units: (pseudocode)

vertex_n_minus1 = [ x, y ]
vertex_n = ..
vertex_n_plus1 = ..
DirectionVector incomingDir = new DirectionVector(vertex_n_minus1, vertex_n)
DirectionVector outgoingDir = new DirectionVector(vertex_n, vertex_n_plus1)
DirectionVector dirChange = [ outgoingDir • incomingDir, outgoingDir • rot90CW(incomingDir) ]
double jointTurnAmountRevs = dirChange.toAngle() / (2*PI) (convert dirVec --> angle_radians -> revs)

If you sum up the variable jointTurnAmountRevs, a CCW, fully closed polygon path will equal 1.0 (+- epsilon). If it's fully closed but CW, you'll get -1.0.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
pbierre
  • 276
  • 1
  • 8
  • I don't think this says anything about whether the polygon has self-intersections or not. The sum of vertex angles is also 1 for non-simple polygons. – Cris Luengo Feb 18 '22 at 16:59
  • The vertex-angle sum should not be relied upon, except after all the other tests for "simple polygon" have been passed. It is used to verify that the vertex list is ordered for a CCW traversal (if that is the spec). For example, a triangulation algorithm (which cleaves a simple polygon into convex-sub-polygons) might depend upon being given a CCW vertex list, so this needs to be validated in advance. – pbierre Feb 19 '22 at 18:11
0

These three classes of invalid polygons would have to be checked for independently.

Case B:

Check to make sure there are no duplicate vertices in your polygon.

Case C:

Check to make sure no vertices land on any edges. Assuming you're using floating point numbers this could get tricky because the floating point numbers would have to evaluate to exactly equal. This can be circumvented by saying they can not be within some EPS of each other, but that could invalidate some other polygons that are only almost invalid. I would personally use the EPS myself unless I really needed utmost precision (at which point I don't know what I would do).

Case D:

As you said, this can be found by checking if any edges intersect.

Case E:

Two edges overlap (intersect at infinitely many points) and their vertices don't.

I'm not sure if this needs to be a separate case, but this situation might not be caught by the check for case D (I think you end up dividing by zero). Therefore you would also have to check that the two edges don't correspond to exactly the same line.

I can't think of any other cases for the moment

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
SirGuy
  • 10,660
  • 2
  • 36
  • 66