/// <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> /// Construct a minimum link path of a polygon. /// </summary> public void BuildPath() { this.LinkDivisers.Clear(); Point2D CurrentPoint = this.LastPoint; Point2D IntersectPoint = null; LineSegment2D CurrentLine = null; LineSegment2D IntersectLine = null; for (int i = this.Divisers.Count - 1; i >= 0; i--) { double position = -1.0; Polygon2D currentPolygon = this.SubDivision[i + 1]; CurrentLine = this.Divisers[i]; if (CurrentLine.Contains(CurrentPoint)) { this.LinkDivisers.Add(CurrentPoint); Vector2D vector = CurrentLine.ToVector().Normal().Normalize(); IntersectPoint = CurrentLine.MidPoint + vector; if (!this.SubDivision[i].Contains(IntersectPoint)) { vector = -vector; } double length = CurrentLine.Length; LineSegment2D testLine = null; do { IntersectPoint = CurrentLine.MidPoint + vector * length; length /= 2; testLine = new LineSegment2D(CurrentPoint, IntersectPoint); } while (!this.SubDivision[i].Contains(testLine)); continue; } for (int j = 0; j < currentPolygon.VertexCount; j++) { Point2D point = currentPolygon.GetPoint(j); if (CurrentPoint == point) { continue; } LineSegment2D lineSegment = new LineSegment2D(CurrentPoint, point); if (currentPolygon.Contains(lineSegment) || currentPolygon.isEdge(lineSegment)) { if (CurrentLine.LineIntersects(lineSegment)) { IntersectPoint = CurrentLine.ToLine().Intersects(lineSegment.ToLine()); if (position < 0) { position = CurrentLine.GetPosition(IntersectPoint); } else { position += CurrentLine.GetPosition(IntersectPoint); position /= 2; } } } } if (position < -0.5) { CurrentPoint = IntersectPoint + IntersectLine.ToVector().Normalize(); i++; continue; } this.LinkDivisers.Add(CurrentPoint); IntersectPoint = CurrentLine.GetPoint(position); IntersectLine = new LineSegment2D(CurrentPoint, IntersectPoint); double extend = IntersectLine.Length; do { extend /= 2; CurrentPoint = IntersectLine.Extend(extend); } while (!this.SubDivision[i].Contains(CurrentPoint)); //CurrentPoint = CurrentLine.GetPoint(position); } CurrentLine = new LineSegment2D(CurrentPoint, this.FirstPoint); if (this.Parent.Contains(CurrentLine)) { this.LinkDivisers.Add(CurrentPoint); this.LinkDivisers.Add(this.FirstPoint); } else if (IntersectLine != null) { CurrentPoint = IntersectPoint + IntersectLine.ToVector().Normalize(); this.LinkDivisers.Add(CurrentPoint); this.LinkDivisers.Add(this.FirstPoint); } else { Vector2D vector = CurrentLine.ToVector().Normal().Normalize(); IntersectPoint = CurrentLine.MidPoint + vector; if (!this.Parent.Contains(IntersectPoint)) { vector = -vector; } IntersectPoint = CurrentLine.MidPoint; double length = CurrentLine.Length; do { length /= 2; CurrentPoint = IntersectPoint + vector * length; }while (!this.Parent.Contains(CurrentPoint)); this.LinkDivisers.Add(this.LastPoint); this.LinkDivisers.Add(CurrentPoint); this.LinkDivisers.Add(this.FirstPoint); } }
/// <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; } }