/// <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);
 }