private static OutputPoint ExcludeOutputPoint(OutputPoint outputPoint) { var result = outputPoint.Prev; result.Next = outputPoint.Next; outputPoint.Next.Prev = result; result.Index = 0; return(result); }
/// <summary> /// Determines if the point is one of the vertices of the output polygon. /// </summary> internal static bool PointIsVertex(IntPoint point, OutputPoint polygon) { var polygonPoint = polygon; do { if (polygonPoint.Point == point) { return(true); } polygonPoint = polygonPoint.Next; }while (polygonPoint != polygon); return(false); }
/// <summary> /// Determines if the point lies on the polygon boundary. /// </summary> internal static bool PointOnPolygon(IntPoint point, OutputPoint polygon, bool useFullRange) { var polygonPoint = polygon; while (true) { if (PointOnLineSegment(point, polygonPoint.Point, polygonPoint.Next.Point, useFullRange)) { return(true); } polygonPoint = polygonPoint.Next; if (polygonPoint == polygon) { break; } } return(false); }
public Polygon Cleaned(double distance = 1.415) { // distance = proximity in units/pixels below which vertices will be stripped. // Default ~= sqrt(2) so when adjacent vertices or semi-adjacent vertices have // both x & y coords within 1 unit, then the second vertex will be stripped. var pointCount = Count; if (pointCount == 0) { return(new Polygon()); } var outputPoints = new OutputPoint[pointCount]; for (var i = 0; i < pointCount; ++i) { outputPoints[i] = new OutputPoint(); } for (var i = 0; i < pointCount; ++i) { outputPoints[i].Point = this[i]; outputPoints[i].Next = outputPoints[(i + 1) % pointCount]; outputPoints[i].Next.Prev = outputPoints[i]; outputPoints[i].Index = 0; } var distSqrd = distance * distance; var op = outputPoints[0]; while (op.Index == 0 && op.Next != op.Prev) { if (GeometryHelper.PointsAreClose(op.Point, op.Prev.Point, distSqrd)) { op = ExcludeOutputPoint(op); pointCount--; } else if (GeometryHelper.PointsAreClose(op.Prev.Point, op.Next.Point, distSqrd)) { ExcludeOutputPoint(op.Next); op = ExcludeOutputPoint(op); pointCount -= 2; } else if (GeometryHelper.SlopesNearCollinear(op.Prev.Point, op.Point, op.Next.Point, distSqrd)) { op = ExcludeOutputPoint(op); pointCount--; } else { op.Index = 1; op = op.Next; } } if (pointCount < 3) { pointCount = 0; } var result = new Polygon(pointCount); for (var i = 0; i < pointCount; ++i) { result.Add(op.Point); op = op.Next; } return(result); }