private void testConvexHull(bool shouldIncludeLinearPoints, IList<Point<int>> pointsOrig, IList<Point<int>> hull) { Logger.LogTrace("\nTesting hull. Hull:\n{}\nPoints:\n{}", hull.ToCommaString(), pointsOrig.ToCommaString()); //First check convexness, hull should be in counter-clockwise order for(int i = 0; i < hull.Count; ++i) { int j = (i + 1) % hull.Count; int k = (i + 2) % hull.Count; if (shouldIncludeLinearPoints) Assert.IsTrue( PointExt.ccw( hull[i], hull[j], hull[k] ) >= 0 ); if (!shouldIncludeLinearPoints) Assert.IsTrue( PointExt.ccw( hull[i], hull[j], hull[k] ) > 0 ); } IList<Point<int>> interiorPoints = new List<Point<int>>(); foreach (var p in pointsOrig) { if (!hull.Contains(p)) interiorPoints.Add(p); } //Go through each side of the hull, checking that all interior points are on the same side for(int i = 0; i < hull.Count; ++i) { int j = (i + 1) % hull.Count; //All interior points should make a counter - clockwise turn if side ij for(int k = 0; k < interiorPoints.Count; ++k) { //OK to be co-linear since 'interior points' can be on hull if (!shouldIncludeLinearPoints) Assert.IsTrue( PointExt.ccw( hull[i], hull[j], interiorPoints[k]) <= 1, "{0} {1} {2} not counter clockwise".FormatThis( hull[i], hull[j], interiorPoints[k] ) ); if (shouldIncludeLinearPoints) Assert.IsTrue( PointExt.ccw( hull[i], hull[j], interiorPoints[k]) == 1, "{0} {1} {2} not counter clockwise".FormatThis( hull[i], hull[j], interiorPoints[k] ) ); } } }