/// <summary> /// For each set of three adjacent points A, B, C, /// find the dot product AB · BC. If the sign of /// all the dot products is the same, the angles /// are all positive or negative (depending on the /// order in which we visit them) so the polygon /// is convex. /// </summary> /// <returns> /// Return true if the polygon is convex. /// </returns> /// <acknowledgment> /// http://csharphelper.com/blog/2014/07/determine-whether-a-polygon-is-convex-in-c/ /// </acknowledgment> public static bool IsConvex(PolygonContour2D polygon) { var got_negative = false; var got_positive = false; var num_points = polygon.Points.Count; int B, C; for (var A = 0; A < num_points; A++) { B = (A + 1) % num_points; C = (B + 1) % num_points; var cross_product = CrossProduct3Vector2DTests.CrossProductVector2D( polygon.Points[A].X, polygon.Points[A].Y, polygon.Points[B].X, polygon.Points[B].Y, polygon.Points[C].X, polygon.Points[C].Y); if (cross_product < 0) { got_negative = true; } else { got_positive |= cross_product > 0; } if (got_negative && got_positive) { return(false); } } // If we got this far, the polygon is convex. return(true); }
/// <summary> /// The forms ear. /// </summary> /// <param name="polygon">The polygon.</param> /// <param name="a">The a.</param> /// <param name="b">The b.</param> /// <param name="c">The c.</param> /// <returns>The <see cref="bool"/>. Return true if the three points form an ear.</returns> /// <acknowledgment> /// http://csharphelper.com/blog/2014/07/triangulate-a-polygon-in-c/ /// </acknowledgment> public static bool FormsEar(PolygonContour2D polygon, int a, int b, int c) { // See if the angle ABC is concave. if (Angle3Vector2DTests.AngleVector( polygon.Points[a].X, polygon.Points[a].Y, polygon.Points[b].X, polygon.Points[b].Y, polygon.Points[c].X, polygon.Points[c].Y) > 0) { // This is a concave corner so the triangle // cannot be an ear. return(false); } // Make the triangle A, B, C. var triangle = new Triangle2D(polygon.Points[a], polygon.Points[b], polygon.Points[c]); // Check the other points to see // if they lie in triangle A, B, C. for (var i = 0; i < polygon.Points.Count; i++) { if ((i != a) && (i != b) && (i != c) && triangle.Contains(polygon.Points[i])) { // This point is in the triangle // do this is not an ear. return(false); } } // This is an ear. return(true); }
/// <summary> /// Find the indexes of three points that form an "ear." /// </summary> /// <param name="polygon"></param> /// <param name="a"></param> /// <param name="b"></param> /// <param name="c"></param> /// <returns></returns> /// <acknowledgment> /// http://csharphelper.com/blog/2014/07/triangulate-a-polygon-in-c/ /// </acknowledgment> public static Triangle2D FindEar(PolygonContour2D polygon, ref int a, ref int b, ref int c) { var num_points = polygon.Points.Count; for (a = 0; a < num_points; a++) { b = (a + 1) % num_points; c = (b + 1) % num_points; if (FormsEar(polygon, a, b, c)) { return(new Triangle2D(polygon.Points[a], polygon.Points[b], polygon.Points[c])); } } //// We should never get here because there should //// always be at least two ears. //Debug.Assert(false); return(new Triangle2D()); }