/// <summary> /// Divide a sub polygon by a line segment. /// </summary> /// <param name="lineSegment">the line segment.</param> /// <param name="poly">the polygon to divide.</param> /// <returns>one of the sub polygon divided from the polygon.</returns> internal Polygon2D DividedBy(LineSegment2D lineSegment, Polygon2D poly) { if (poly.isDiagonal(lineSegment)) { int a = poly.HasVertex(lineSegment.FirstPoint); int b = poly.HasVertex(lineSegment.LastPoint); if (a > b) { int tmp = a; a = b; b = tmp; } Point2DCollection p2 = new Point2DCollection(b - a + 1); Point2DCollection p1 = new Point2DCollection(poly.VertexCount - p2.Size + 2); for (int i = 0; i < poly.VertexCount; i++) { if (i <= a || i >= b) { p1.Add(poly.GetPoint(i)); } if (i >= a && i <= b) { p2.Add(poly.GetPoint(i)); } } if (p1.Count > p2.Count) { SubDivision.Add(new Polygon2D(p1)); return new Polygon2D(p2); } else { SubDivision.Add(new Polygon2D(p2)); return new Polygon2D(p1); } } else if (lineSegment.Intersects(poly)) { Point2DCollection Points = new Point2DCollection(2); for (int i = 0; i < poly.VertexCount; i++) { LineSegment2D border = poly.GetEdge(i); Point2D p = lineSegment.GetIntersectPoint(border); if (p.isRegular) { Points.DistinctAdd(p); } } Debug.Assert(Points.Count == 2); if (poly.HasVertex(Points[0]) == Polygon2D.NoSuchPoint) { poly.Add(Points[0], poly.OnEdge(Points[0])); Parent.AddInner(Points[0]); this.InnerPoints.DistinctAdd(Points[0]); } if (poly.HasVertex(Points[1]) == Polygon2D.NoSuchPoint) { poly.Add(Points[1], poly.OnEdge(Points[1])); Parent.AddInner(Points[1]); this.InnerPoints.DistinctAdd(Points[1]); } LineSegment2D line = new LineSegment2D(Points[0], Points[1]); return DividedBy(line, poly); } else { return poly; } }
/// <summary> /// Divide the source polygon to compute link distance. /// </summary> public void Divide() { LineSegment2D entrance = this.LastDiviser; LineSegment2D path = new LineSegment2D(entrance.FirstPoint, this.LastPoint); if (this.CurrentPolygon.Contains(path)) { return; } path = new LineSegment2D(entrance.LastPoint, this.LastPoint); if (this.CurrentPolygon.Contains(path)) { return; } for (int i = 0; i < this.CurrentPolygon.VertexCount; i++) { if (this.CurrentPolygon.GetPoint(i) == entrance.FirstPoint) { continue; } LineSegment2D lineSegment = new LineSegment2D(entrance.FirstPoint, this.CurrentPolygon.GetPoint(i)); if (!this.CurrentPolygon.Contains(lineSegment) && !this.CurrentPolygon.isEdge(lineSegment)) { continue; } LineSegment2D lineDiviser = this.ChooseDiviser(lineSegment); if (lineDiviser == null) { continue; } Polygon2D testPoly = new Polygon2D(this.CurrentPolygon); if (!testPoly.isVertex(lineDiviser.LastPoint)) { testPoly.Add(lineDiviser.LastPoint, testPoly.OnEdge(lineDiviser.LastPoint)); } Polygon2D polygon = this.DividedBy(lineDiviser, testPoly); if (polygon.isVertex(this.LastPoint)) { testPoly = this.CurrentPolygon; this.SubDivision.Remove(this.SubDivision.Count - 1); } else { testPoly = polygon; polygon = this.CurrentPolygon; this.SubDivision.Remove(this.SubDivision.Count - 1); } if (entrance.FirstPoint == entrance.LastPoint) { this.SubDivision.Remove(this.SubDivision.Count - 1); this.SubDivision.Add(testPoly); this.SubDivision.Add(polygon); } else { LineSegment2D testLine = new LineSegment2D(entrance.LastPoint, lineDiviser.FirstPoint); if (!testLine.isRegular) { entrance = new LineSegment2D(entrance.LastPoint, entrance.LastPoint); continue; } if (this.CurrentPolygon.Contains(testLine)) { testLine = this.ChooseDiviser(testLine); if (testLine != null && !testPoly.Contains(testLine)) { lineDiviser = testLine; testPoly = new Polygon2D(this.CurrentPolygon); if (!testPoly.isVertex(lineDiviser.LastPoint)) { testPoly.Add(lineDiviser.LastPoint, testPoly.OnEdge(lineDiviser.LastPoint)); } polygon = this.DividedBy(lineDiviser, testPoly); testPoly = this.CurrentPolygon; this.SubDivision.Remove(this.SubDivision.Count - 1); } else if (testLine == null) { continue; } } if (!polygon.isVertex(this.LastPoint)) { this.SubDivision.Remove(this.SubDivision.Count - 1); this.SubDivision.Add(polygon); this.SubDivision.Add(testPoly); } else { this.SubDivision.Remove(this.SubDivision.Count - 1); this.SubDivision.Add(testPoly); this.SubDivision.Add(polygon); } } this.Divisers.Add(lineDiviser); this.Divide(); return; } }
/// <summary> /// Divide a sub polygon by a line segment. /// </summary> /// <param name="lineSegment">the line segment.</param> /// <param name="poly">the polygon to divide.</param> /// <returns>one of the sub polygon divided from the polygon.</returns> internal Polygon2D DividedBy(LineSegment2D lineSegment, Polygon2D poly) { if (poly.isDiagonal(lineSegment)) { int a = poly.HasVertex(lineSegment.FirstPoint); int b = poly.HasVertex(lineSegment.LastPoint); if (a > b) { int tmp = a; a = b; b = tmp; } Point2DCollection p2 = new Point2DCollection(b - a + 1); Point2DCollection p1 = new Point2DCollection(poly.VertexCount - p2.Size + 2); for (int i = 0; i < poly.VertexCount; i++) { if (i <= a || i >= b) { p1.Add(poly.GetPoint(i)); } if (i >= a && i <= b) { p2.Add(poly.GetPoint(i)); } } if (p1.Count > p2.Count) { SubDivision.Add(new Polygon2D(p1)); return(new Polygon2D(p2)); } else { SubDivision.Add(new Polygon2D(p2)); return(new Polygon2D(p1)); } } else if (lineSegment.Intersects(poly)) { Point2DCollection Points = new Point2DCollection(2); for (int i = 0; i < poly.VertexCount; i++) { LineSegment2D border = poly.GetEdge(i); Point2D p = lineSegment.GetIntersectPoint(border); if (p.isRegular) { Points.DistinctAdd(p); } } Debug.Assert(Points.Count == 2); if (poly.HasVertex(Points[0]) == Polygon2D.NoSuchPoint) { poly.Add(Points[0], poly.OnEdge(Points[0])); Parent.AddInner(Points[0]); this.InnerPoints.DistinctAdd(Points[0]); } if (poly.HasVertex(Points[1]) == Polygon2D.NoSuchPoint) { poly.Add(Points[1], poly.OnEdge(Points[1])); Parent.AddInner(Points[1]); this.InnerPoints.DistinctAdd(Points[1]); } LineSegment2D line = new LineSegment2D(Points[0], Points[1]); return(DividedBy(line, poly)); } else { return(poly); } }
/// <summary> /// Divide the source polygon to compute link distance. /// </summary> public void Divide() { LineSegment2D entrance = this.LastDiviser; LineSegment2D path = new LineSegment2D(entrance.FirstPoint, this.LastPoint); if (this.CurrentPolygon.Contains(path)) { return; } path = new LineSegment2D(entrance.LastPoint, this.LastPoint); if (this.CurrentPolygon.Contains(path)) { return; } for (int i = 0; i < this.CurrentPolygon.VertexCount; i++) { if (this.CurrentPolygon.GetPoint(i) == entrance.FirstPoint) { continue; } LineSegment2D lineSegment = new LineSegment2D(entrance.FirstPoint, this.CurrentPolygon.GetPoint(i)); if(!this.CurrentPolygon.Contains(lineSegment) && !this.CurrentPolygon.isEdge(lineSegment)) { continue; } LineSegment2D lineDiviser = this.ChooseDiviser(lineSegment); if (lineDiviser == null) { continue; } Polygon2D testPoly = new Polygon2D(this.CurrentPolygon); if (!testPoly.isVertex(lineDiviser.LastPoint)) { testPoly.Add(lineDiviser.LastPoint, testPoly.OnEdge(lineDiviser.LastPoint)); } Polygon2D polygon = this.DividedBy(lineDiviser, testPoly); if (polygon.isVertex(this.LastPoint)) { testPoly = this.CurrentPolygon; this.SubDivision.Remove(this.SubDivision.Count - 1); } else { testPoly = polygon; polygon = this.CurrentPolygon; this.SubDivision.Remove(this.SubDivision.Count - 1); } if (entrance.FirstPoint == entrance.LastPoint) { this.SubDivision.Remove(this.SubDivision.Count - 1); this.SubDivision.Add(testPoly); this.SubDivision.Add(polygon); } else { LineSegment2D testLine = new LineSegment2D(entrance.LastPoint, lineDiviser.FirstPoint); if (!testLine.isRegular) { entrance = new LineSegment2D(entrance.LastPoint, entrance.LastPoint); continue; } if (this.CurrentPolygon.Contains(testLine)) { testLine = this.ChooseDiviser(testLine); if (testLine != null && !testPoly.Contains(testLine)) { lineDiviser = testLine; testPoly = new Polygon2D(this.CurrentPolygon); if (!testPoly.isVertex(lineDiviser.LastPoint)) { testPoly.Add(lineDiviser.LastPoint, testPoly.OnEdge(lineDiviser.LastPoint)); } polygon = this.DividedBy(lineDiviser, testPoly); testPoly = this.CurrentPolygon; this.SubDivision.Remove(this.SubDivision.Count - 1); } else if (testLine == null) { continue; } } if (!polygon.isVertex(this.LastPoint)) { this.SubDivision.Remove(this.SubDivision.Count - 1); this.SubDivision.Add(polygon); this.SubDivision.Add(testPoly); } else { this.SubDivision.Remove(this.SubDivision.Count - 1); this.SubDivision.Add(testPoly); this.SubDivision.Add(polygon); } } this.Divisers.Add(lineDiviser); this.Divide(); return; } }
/// <summary> /// Add new point to the polygon. /// </summary> /// <param name="point">new point.</param> public void AddPoint(Point2D point) { Polygon.Add(point); }