39. Convexity testing

A convex polygon is one where each of its internal angles is less than 180°. Another way to think of it is that you can pass a line through any two adjacent polygon vertices and the line will not cut into the polygon's body.

The GetAngle method described in the preceding solution calculates an angle. Unfortunately, it doesn't return angles greater than 180°. Instead, if an angle is greater than 180°, the method returns 360 minus the angle so the result is always between –180° and 180°.

The method has one other issue that complicates the situation: the sign of the angles depends on the orientation of the points. If A, B, and C are points, then GetAngle(A, B, C) = -GetAngle(C, B, A).

The solution to these problems is to look at the signs of the angles. The GetAngle method returns positive or negative values depending on whether an angle bends to the left or right. If GetAngle returns all positive or all negative values for a polygon's angles, then the polygon is convex. If GetAngle returns some positive values and some negative values, then the polygon is not convex.

The following PolygonIsConvex method returns true if a polygon is convex:

// Return true if the polygon is convex.
private bool PolygonIsConvex(List<Point> points)
{
int numPoints = points.Count;
if (numPoints < 3)
throw new Exception(
"The polygon must have at least three vertices");

// Duplicate the first two points.
points.Add(points[0]);
points.Add(points[1]);

// Get the sign of the first angle.
int sign = Math.Sign(GetAngle(points[0], points[1], points[2]));

// Loop through the angles.
bool isConvex = true;
for (int i = 1; i < numPoints; i++)
{
if (Math.Sign(GetAngle(points[i], points[i + 1], points[i +
2]))
!= sign)
{
isConvex = false;
break;
}
}

// Remove the duplicates that we added.
points.RemoveAt(numPoints);
points.RemoveAt(numPoints);

return isConvex;
}

The method first verifies that the polygon contains at least three points. It then adds copies of the first two points to the end of the point list to make it easier to loop through the polygon's angles.

The code then gets the sign of the first angle and saves it in the sign variable. Next, the code sets the isConvex variable to true and loops through the polygon's remaining angles. If any angle's sign doesn't agree with the value stored in the sign variable, the method sets isConvex to false and breaks out of the loop.

After it finishes the loop, the method removes the duplicate points that it added to the point list and returns the value stored in isConvex.

Download the IsConvex example solution to see additional details.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset