Ejemplo n.º 1
0
        /// <summary>
        /// Divide the polygon by the line segment between two vertices.
        /// </summary>
        /// <param name="a">the index of first vertex.</param>
        /// <param name="b">the index of second vertex.</param>
        public void DividedBy(int a, int b)
        {
            if (a < 0 || b < 0 || a > Parent.VertexCount || b > Parent.VertexCount)
            {
                throw (new ArgumentException());
            }

            LineSegment2D lineSegment = new LineSegment2D(Parent.GetPoint(a), Parent.GetPoint(b));

            DividedBy(lineSegment);
        }
        public LineSegment2DCollection(LineSegment2D[] lineSegments, int capacity)
        {
            Capacity = capacity;
            CurrentCount = lineSegments.Length;
            if (Capacity < CurrentCount)
            {
                throw (new CollectionCapacityException());
            }

            LineSegments = lineSegments;
        }
Ejemplo n.º 3
0
 /// <summary>
 /// Whether the line segment inflects the edges of the polygon.
 /// </summary>
 /// <param name="lineSegment">the line segment.</param>
 /// <returns>true if inflects.</returns>
 public bool InflectsEdge(LineSegment2D lineSegment)
 {
     for (int i = 0; i < this.VertexCount; i++)
     {
         if (lineSegment.Inflects(this.GetEdge(i)))
         {
             return(true);
         }
     }
     return(false);
 }
        public void Union(LineSegment2DCollection lineSegment2DCollection)
        {
            Capacity += lineSegment2DCollection.Capacity;

            LineSegment2D[] lineSegments = new LineSegment2D[Capacity];

            this.LineSegments.CopyTo(lineSegments, 0);
            lineSegment2DCollection.LineSegments.CopyTo(lineSegments, this.Count);
            this.LineSegments = lineSegments;
            CurrentCount     += lineSegment2DCollection.Count;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Divide the polygon by a line segment.
        /// </summary>
        /// <param name="lineSegment">the line segment.</param>
        public void DividedBy(LineSegment2D lineSegment)
        {
            Divisers.Add(lineSegment);

            int Count = SubDivision.Count;

            for (int i = 0; i < Count; i++)
            {
                Polygon2D poly = SubDivision[i];

                SubDivision[i] = DividedBy(lineSegment, poly);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Divide the polygon to triangles.
        /// </summary>
        public void Triangulation()
        {
            for (int i = 0; i < SubDivision.Count; i++)
            {
                Polygon2D poly = SubDivision[i];

                if (poly.PointCount > 3)
                {
                    LineSegment2D lineSegment = new LineSegment2D(poly.GetPoint(0), poly.GetPoint(2));

                    SubDivision[i] = DividedBy(lineSegment, poly);
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// If the point is on one of the edges of this polygon, it returns the index, otherwise it returns NoSuchPoint.
        /// </summary>
        /// <param name="point">the point.</param>
        /// <returns>the index</returns>
        public int OnEdge(Point2D point)
        {
            for (int i = 0; i < this.VertexCount; i++)
            {
                LineSegment2D line = this.GetEdge(i);

                if (line.Contains(point))
                {
                    return(i);
                }
            }

            return(NoSuchPoint);
        }
        private LineSegment2D ChooseDiviser(LineSegment2D lineSegment)
        {
            for (int i = 0; i < CurrentPolygon.VertexCount; i++)
            {
                LineSegment2D Edge = CurrentPolygon.GetEdge(i);

                if (Edge == lineSegment || Edge.Intersects(lineSegment) || !Edge.LineIntersects(lineSegment))
                {
                    continue;
                }

                Point2D divPoint = lineSegment.ToLine().Intersects(Edge.ToLine());

                if (lineSegment.Contains(divPoint))
                {
                    continue;
                }

                LineSegment2D divLine = new LineSegment2D(lineSegment.LastPoint, divPoint);

                if (divLine.Contains(lineSegment.FirstPoint))
                {
                    //divLine = new LineSegment2D(lineSegment.FirstPoint, divPoint);
                    continue;
                }

                /*if (CurrentPolygon.InflectsEdge(divLine))
                 * {
                 *      int ssi = 0;
                 * }*/
                if (!CurrentPolygon.Contains(divLine))
                {
                    continue;
                }

                if (divPoint == this.LastPoint)
                {
                    ///need trace here
                    return(divLine);
                }

                if (this.isApart(divLine, this.CurrentPointIndex, this.LastPointIndex))
                {
                    return(divLine);
                }
            }

            return(null);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Whether the line segment is inside the polygon.
 /// </summary>
 /// <param name="lineSegment">the line segment.</param>
 /// <returns>true if contains.</returns>
 public bool Contains(LineSegment2D lineSegment)
 {
     /*for (int i = 0; i < this.VertexCount; i++)
      * {
      *      if (lineSegment.Contains(this.GetEdge(i)))
      *      {
      *              return false;
      *      }
      * }*/
     if (this.InflectsEdge(lineSegment))
     {
         return(false);
     }
     return(!lineSegment.Intersects(this) && this.Contains(lineSegment.MidPoint) && !this.isOnEdge(lineSegment.MidPoint));
 }
        private bool isApart(LineSegment2D lineSegment, int c, int d)
        {
            double a = CurrentPolygon.OnEdge(lineSegment.FirstPoint) - 0.5;
            double b = CurrentPolygon.OnEdge(lineSegment.LastPoint) - 0.5;

            if (a < 0)
            {
                a += CurrentPolygon.VertexCount;
            }
            if (b < 0)
            {
                b += CurrentPolygon.VertexCount;
            }

            return(isApart(a, b, c, d));
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Whether the two line segments inflect each other.
        /// </summary>
        /// <param name="lineSegment">the target linesegment</param>
        /// <returns>true if inflect</returns>
        public bool Inflects(LineSegment2D lineSegment)
        {
            if (this.TrulyContains(lineSegment.FirstPoint) || this.TrulyContains(lineSegment.LastPoint))
            {
                if (this.ToVector() * lineSegment.ToVector() < ZeroTolerance)
                {
                    return(true);
                }
            }

            if (this.Contains(lineSegment) || lineSegment.Contains(this))
            {
                return(true);
            }

            return(false);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Whether ths line segment intersects a polygon.
        /// </summary>
        /// <param name="polygon">the polygon.</param>
        /// <returns>true if intersects.</returns>
        public bool Intersects(Polygon2D polygon)
        {
            bool bResult = false;

            for (int i = 0; i < polygon.VertexCount; i++)
            {
                LineSegment2D lineSegment = polygon.GetEdge(i);

                //bResult |= this.TrulyIntersects(polygon.GetEdge(i));
                bResult |= (this.TrulyLineIntersects(lineSegment) && lineSegment.Intersects(this));
                if (bResult)
                {
                    return(true);
                }
            }

            return(bResult);
        }
        public void Add(LineSegment2D lineSegment)
        {
            try
            {
                base.Add();
            }
            catch (CollectionCapacityException e)
            {
                string emsg = e.Message;

                this.Capacity *= 2;

                LineSegment2D[] lineSegments = new LineSegment2D[Capacity];

                this.LineSegments.CopyTo(lineSegments, 0);
                this.LineSegments = lineSegments;
                base.Add();
            }
            LineSegments[CurrentCount - 1] = lineSegment;
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Get the intersect point of the two line segment.
        /// </summary>
        /// <param name="lineSegment">the ohter line segment.</param>
        /// <returns>the intersect point.</returns>
        public Point2D GetIntersectPoint(LineSegment2D lineSegment)
        {
            if (this.Intersects(lineSegment))
            {
                try
                {
                    Point2D point = this.ToLine().Intersects(lineSegment.ToLine());

                    return(point);
                }
                catch (ArgumentException e)
                {
                    string emsg = e.Message;

                    return(new Point2D(double.NaN, double.NaN));
                }
            }
            else
            {
                return(new Point2D(double.NaN, double.NaN));
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Determines whether the specified object is equal to this line segment.
        /// </summary>
        /// <param name="obj">The object to compare with this line segment.</param>
        /// <returns><c>true</c> if the specified object is equal to this linesegment; otherwise, <c>false</c>.</returns>
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }

            LineSegment2D lineSegment = (LineSegment2D)obj;

            if (lineSegment.FirstPoint == this.FirstPoint && lineSegment.LastPoint == this.LastPoint)
            {
                return(true);
            }
            else if (lineSegment.FirstPoint == this.LastPoint && lineSegment.LastPoint == this.FirstPoint)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Whether the line segment is the diagonal of this polygon.
        /// </summary>
        /// <param name="lineSegment">the line segment.</param>
        /// <returns>true if is diagonal.</returns>
        public bool isDiagonal(LineSegment2D lineSegment)
        {
            if (!lineSegment.isRegular)
            {
                return(false);
            }
            if (this.isEdge(lineSegment))
            {
                return(false);
            }
            if (!this.Contains(lineSegment))
            {
                return(false);
            }

            for (int i = 0; i < this.VertexCount; i++)
            {
                if (lineSegment.TrulyContains(this.Vertices[i]))
                {
                    return(false);
                }
            }
            for (int i = 0; i < this.VertexCount; i++)
            {
                if (lineSegment.FirstPoint == this.Vertices[i])
                {
                    for (int j = 0; j < this.VertexCount; j++)
                    {
                        if (lineSegment.LastPoint == this.Vertices[j])
                        {
                            return(true);
                        }
                    }
                    return(false);
                }
            }
            return(false);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Whether the two extents intersect each other.
        /// (x1,y1)-----------------------------
        /// -         Extent                   -
        /// ------------------------------(x2,y2)
        /// </summary>
        /// <param name="line">the other line.</param>
        /// <returns>true if intersect.</returns>
        private bool ExtentIntersects(LineSegment2D line)
        {
            double x1, y1;
            double x2, y2;
            double x3, y3;
            double x4, y4;

            x1 = Math.Min(this.FirstPoint.X, this.LastPoint.X);
            x2 = Math.Max(this.FirstPoint.X, this.LastPoint.X);
            y1 = Math.Min(this.FirstPoint.Y, this.LastPoint.Y);
            y2 = Math.Max(this.FirstPoint.Y, this.LastPoint.Y);
            x3 = Math.Min(line.FirstPoint.X, line.LastPoint.X);
            x4 = Math.Max(line.FirstPoint.X, line.LastPoint.X);
            y3 = Math.Min(line.FirstPoint.Y, line.LastPoint.Y);
            y4 = Math.Max(line.FirstPoint.Y, line.LastPoint.Y);
            if (x1 <= x4 && x2 >= x3 && y1 <= y4 && y2 >= y3)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Divide the polygon to triangles.
        /// </summary>
        public void Triangulation()
        {
            for (int i = 0; i < SubDivision.Count; i++)
            {
                Polygon2D poly = SubDivision[i];

                if (poly.PointCount > 3)
                {
                    LineSegment2D lineSegment = new LineSegment2D(poly.GetPoint(0), poly.GetPoint(2));

                    SubDivision[i] = DividedBy(lineSegment, poly);
                }
            }
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Divide the polygon by a line segment.
        /// </summary>
        /// <param name="lineSegment">the line segment.</param>
        public void DividedBy(LineSegment2D lineSegment)
        {
            Divisers.Add(lineSegment);

            int Count = SubDivision.Count;

            for (int i = 0; i < Count; i++)
            {
                Polygon2D poly = SubDivision[i];

                SubDivision[i] = DividedBy(lineSegment, poly);
            }
        }
        public void Add(LineSegment2D lineSegment)
        {
            try
            {
                base.Add();
            }
            catch (CollectionCapacityException e)
            {
                string emsg = e.Message;

                this.Capacity *= 2;

                LineSegment2D[] lineSegments = new LineSegment2D[Capacity];

                this.LineSegments.CopyTo(lineSegments, 0);
                this.LineSegments = lineSegments;
                base.Add();
            }
            LineSegments[CurrentCount - 1] = lineSegment;
        }
Ejemplo n.º 21
0
        /// <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);
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Whether the three points is on a line.
        /// </summary>
        /// <param name="a">the first point.</param>
        /// <param name="b">the second point.</param>
        /// <param name="c">the third point.</param>
        /// <returns>true if is on a line.</returns>
        static public bool isOnLine(Point2D a, Point2D b, Point2D c)
        {
            LineSegment2D line = new LineSegment2D(a, b);

            return(line.isOnLine(c));
        }
        public void FastTriangluation()
        {
            int from = 0;
            int to = 2;
            Polygon2DEditor polygonEditor = new Polygon2DEditor(this.FirstPolygons.Parent);

            polygonEditor.Clear();
            polygonEditor = new Polygon2DEditor(this.SecondPolygons.Parent);
            polygonEditor.Clear();

            this.InitLinkDistance();

            for (int i = 0; i < FirstPolygons.SubDivision.Count; i++)
            {
                int vertexCount = FirstPolygons.SubDivision[i].VertexCount;
                Polygon2D firstPolygon = FirstPolygons.SubDivision[i];
                Polygon2D secondPolygon = SecondPolygons.SubDivision[i];

                if (vertexCount <= 3)
                {
                    continue;
                }

                int dist = MAX_DIST;

                for (int j = 0; j < vertexCount; j++)
                {
                    for (int k = j + 2; k < vertexCount; k++)
                    {
                        if (j == k || Math.Abs(j - k) == 1 || Math.Abs(j - k) == vertexCount - 1)
                        {
                            continue;
                        }

                        LineSegment2D testLine = new LineSegment2D(firstPolygon.GetPoint(j), firstPolygon.GetPoint(k));

                        if (firstPolygon.InflectsEdge(testLine))
                        {
                            continue;
                        }

                        testLine = new LineSegment2D(secondPolygon.GetPoint(j), secondPolygon.GetPoint(k));
                        if (secondPolygon.InflectsEdge(testLine))
                        {
                            continue;
                        }

                        LinkDistance link = this.linkDistance.Contains(this.FirstPolygons.GetParentIndex(j, i), this.FirstPolygons.GetParentIndex(k, i), 0);

                        int d;

                        if (link != null)
                        {
                            d = link.linkDistance;
                        }

                        else
                        {
                            FirstTarget = new Polygon2DLinkMaker(firstPolygon, j, k);
                            SecondTarget = new Polygon2DLinkMaker(secondPolygon, j, k);
                            FirstTarget.Divide();
                            SecondTarget.Divide();

                            d = Math.Max(FirstTarget.LinkDistance, SecondTarget.LinkDistance);

                            link = new LinkDistance(this.FirstPolygons.GetParentIndex(j, i), this.FirstPolygons.GetParentIndex(k, i), 0, d);
                        }

                        if (dist > d)
                        {
                            dist = d;
                            from = j;
                            to = k;
                        }
                        else if (dist == d)
                        {
                            if (Math.Abs(vertexCount / 2 - Math.Abs(j - k)) > Math.Abs(vertexCount / 2 - Math.Abs(from - to)))
                            {
                                from = j;
                                to = k;
                            }
                        }
                    }
                }

                FirstTarget = new Polygon2DLinkMaker(firstPolygon, from, to);
                SecondTarget = new Polygon2DLinkMaker(secondPolygon, from, to);
                FirstTarget.Divide();
                FirstTarget.BuildPath();
                SecondTarget.Divide();
                SecondTarget.BuildPath();

                if (dist != Math.Max(FirstTarget.LinkDistance, SecondTarget.LinkDistance))
                {
                    dist = Math.Max(FirstTarget.LinkDistance, SecondTarget.LinkDistance);
                    this.linkDistance.Set(this.FirstPolygons.GetParentIndex(from, i), this.FirstPolygons.GetParentIndex(to, i), 0, dist);
                }

                int Extra = dist - FirstTarget.LinkDistance;

                if (Extra > 0)
                {
                    FirstTarget.LinkDivisers.Extend(Extra);
                }

                Extra = dist - SecondTarget.LinkDistance;
                if (Extra > 0)
                {
                    SecondTarget.LinkDivisers.Extend(Extra);
                }

                FirstPolygons.DividedBy(FirstTarget.LinkDivisers, firstPolygon);
                SecondPolygons.DividedBy(SecondTarget.LinkDivisers, secondPolygon);
            }

            GetResult();
            BuildGhostTriangle();
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Whether the two line segment share terminal point with each other.
 /// </summary>
 /// <param name="lineSegment"></param>
 /// <returns></returns>
 public bool SharePointWith(LineSegment2D lineSegment)
 {
     if (lineSegment == this)
     {
         return false;
     }
     return lineSegment.FirstPoint == this.FirstPoint || lineSegment.FirstPoint == this.LastPoint || lineSegment.LastPoint == this.FirstPoint || lineSegment.LastPoint == this.LastPoint;
 }
Ejemplo n.º 25
0
        private LineSegment2D Max(LineSegment2D a, LineSegment2D b, LineSegment2D c)
        {
            LineSegment2D lineSegment = a;

            if (lineSegment.Length < b.Length)
            {
                lineSegment = b;
            }

            if (lineSegment.Length < c.Length)
            {
                lineSegment = c;
            }

            return lineSegment;
        }
        private void AddInnerPoints(Polygon2DAdorner polygon)
        {
            for (int j = 0; j < this.ghostPoint.Count; j++)
            {
                for (int i = 0; i < polygon.internalSegments.Count; i++)
                {
                    int a = (int)(polygon.internalSegments[i].X);
                    int b = (int)(polygon.internalSegments[i].Y);

                    if (a == this.ghostPoint[j].FirstIndex && b == this.ghostPoint[j].LastIndex || a == this.ghostPoint[j].LastIndex && b == this.ghostPoint[j].FirstIndex)
                    {
                        Point2D point = null;
                        LineSegment2D lineSegment = null;

                        lineSegment = new LineSegment2D(polygon.polygon.GetPoint(a), polygon.polygon.GetPoint(b));

                        point = lineSegment.GetPoint(this.ghostPoint[j].LocalPosition);

                        Polygon2DEditor polygonEditor = new Polygon2DEditor(polygon.polygon);

                        polygonEditor.AddInnerPoint(point);

                        break;
                    }
                }
            }
        }
        private void InitLinkDistance()
        {
            int Count = this.FirstPolygons.Parent.VertexCount;

            Polygon2D firstPolygon = FirstPolygons.Parent;
            Polygon2D secondPolygon = SecondPolygons.Parent;

            for (int i = 0; i < Count; i++)
            {

                for (int j = i + 2; j < Count; j++)
                {
                    if (i == j || Math.Abs(i - j) == 1 || Math.Abs(i - j) == Count - 1)
                    {
                        continue;
                    }

                    LineSegment2D testLine = new LineSegment2D(firstPolygon.GetPoint(i), firstPolygon.GetPoint(j));
                    if (firstPolygon.InflectsEdge(testLine))
                    {
                        continue;
                    }

                    testLine = new LineSegment2D(secondPolygon.GetPoint(i), secondPolygon.GetPoint(j));

                    if (secondPolygon.InflectsEdge(testLine))
                    {
                        continue;
                    }

                    FirstTarget = new Polygon2DLinkMaker(firstPolygon, i, j);
                    SecondTarget = new Polygon2DLinkMaker(secondPolygon, i, j);
                    FirstTarget.Divide();
                    SecondTarget.Divide();

                    int linkDistance = Math.Max(FirstTarget.LinkDistance, SecondTarget.LinkDistance);

                    if (this.linkDistance == null)
                    {
                        this.linkDistance = new LinkDistance(i, j, 0, linkDistance);
                    }
                    else
                    {
                        this.linkDistance.Add(new LinkDistance(i, j, 0, linkDistance));
                    }
                }
            }
        }
Ejemplo n.º 28
0
        private bool isApart(LineSegment2D lineSegment, int c, int d)
        {
            double a = CurrentPolygon.OnEdge(lineSegment.FirstPoint) - 0.5;
            double b = CurrentPolygon.OnEdge(lineSegment.LastPoint) - 0.5;

            if (a < 0)
            {
                a += CurrentPolygon.VertexCount;
            }
            if (b < 0)
            {
                b += CurrentPolygon.VertexCount;
            }

            return isApart(a, b, c, d);
        }
Ejemplo n.º 29
0
        private LineSegment2D ChooseDiviser(LineSegment2D lineSegment)
        {
            for (int i = 0; i < CurrentPolygon.VertexCount; i++)
            {
                LineSegment2D Edge = CurrentPolygon.GetEdge(i);

                if (Edge == lineSegment || Edge.Intersects(lineSegment) || !Edge.LineIntersects(lineSegment))
                {
                    continue;
                }

                Point2D divPoint = lineSegment.ToLine().Intersects(Edge.ToLine());

                if (lineSegment.Contains(divPoint))
                {
                    continue;
                }

                LineSegment2D divLine = new LineSegment2D(lineSegment.LastPoint, divPoint);

                if (divLine.Contains(lineSegment.FirstPoint))
                {
                    //divLine = new LineSegment2D(lineSegment.FirstPoint, divPoint);
                    continue;
                }

                /*if (CurrentPolygon.InflectsEdge(divLine))
                {
                    int ssi = 0;
                }*/
                if (!CurrentPolygon.Contains(divLine))
                {
                    continue;
                }

                if (divPoint == this.LastPoint)
                {
                    ///need trace here
                    return divLine;
                }

                if (this.isApart(divLine, this.CurrentPointIndex, this.LastPointIndex))
                {
                    return divLine;
                }
            }

            return null;
        }
Ejemplo n.º 30
0
        /// <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;
            }
        }
Ejemplo n.º 31
0
        /// <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;
            }
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Whether the three points is on a line.
        /// </summary>
        /// <param name="a">the first point.</param>
        /// <param name="b">the second point.</param>
        /// <param name="c">the third point.</param>
        /// <returns>true if is on a line.</returns>
        public static bool isOnLine(Point2D a, Point2D b, Point2D c)
        {
            LineSegment2D line = new LineSegment2D(a, b);

            return line.isOnLine(c);
        }
Ejemplo n.º 33
0
        /// <summary>
        /// Divide the polygon by the line segment between two vertices.
        /// </summary>
        /// <param name="a">the index of first vertex.</param>
        /// <param name="b">the index of second vertex.</param>
        public void DividedBy(int a, int b)
        {
            if (a < 0 || b < 0 || a > Parent.VertexCount || b > Parent.VertexCount)
            {
                throw (new ArgumentException());
            }

            LineSegment2D lineSegment = new LineSegment2D(Parent.GetPoint(a), Parent.GetPoint(b));

            DividedBy(lineSegment);
        }
Ejemplo n.º 34
0
        /// <summary>
        /// Get the intersect point of the two line segment.
        /// </summary>
        /// <param name="lineSegment">the ohter line segment.</param>
        /// <returns>the intersect point.</returns>
        public Point2D GetIntersectPoint(LineSegment2D lineSegment)
        {
            if (this.Intersects(lineSegment))
            {
                try
                {
                    Point2D point = this.ToLine().Intersects(lineSegment.ToLine());

                    return point;
                }
                catch (ArgumentException e)
                {
                    string emsg = e.Message;

                    return new Point2D(double.NaN, double.NaN);
                }
            }
            else
            {
                return new Point2D(double.NaN, double.NaN);
            }
        }
Ejemplo n.º 35
0
        /// <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);
            }
        }
Ejemplo n.º 36
0
        public void Triangulation()
        {
            if (!this.polygon.isRegular || !this.polygon.isSimple)
            {
                throw (new ApplicationException("Can not triangulate this polygon!"));
            }

            //this.triangles.Clear();
            //this.lineSegments.Clear();
            this.internalSegments.Clear();
            this.ghostTriangles = new GhostTriangle2DCollection();
            this.Clear();

            int Count = this.polygon.VertexCount;
            int[] flag = new int[Count];

            for (int i = 0; i < Count; i++)
            {
                flag[i] = i;
            }

            int a = 0;
            int b = 1;
            int c = 2;

            while (Count > 3)
            {
                LineSegment2D lineSegment = new LineSegment2D(this.polygon.GetPoint(flag[a]), this.polygon.GetPoint(flag[c]));

                if (this.polygon.Contains(lineSegment))
                {
                    Count--;
                    this.Triangulation(flag[a], flag[b], flag[c]);

                    for (int i = b; i < Count; i++)
                    {
                        flag[i] = flag[i + 1];
                    }

                    a = a % Count;
                    b = (a + 1) % Count;
                    c = (b + 1) % Count;
                    continue;
                }
                else
                {
                    a = (a + 1) % Count;
                    b = (b + 1) % Count;
                    c = (c + 1) % Count;
                }
            }
            this.Triangulation(flag[a],flag[b],flag[c]);

            if (this.child != null)
            {
                this.child.Triangulation();
            }
        }
Ejemplo n.º 37
0
        private void Divide(Polygon2D poly)
        {
            for (int i = 0; i < poly.VertexCount; i++)  //Find Convex Angle
            {
                if (poly.isConvexAngle(i))
                {
                    continue;
                }
                int index = i;
                double min_dist = 10000;

                for (int j = 0; j < poly.VertexCount; j++) //Divide Polygon
                {
                    if (j == i)
                    {
                        continue;
                    }
                    LineSegment2D line = new LineSegment2D(poly.GetPoint(i), poly.GetPoint(j));

                    if (poly.isDiagonal(line))
                    {
                        //double dist = line.Length;
                        Vector2D v1 = line.ToVector();
                        LineSegment2D line1 = poly.GetEdge(i);
                        line1.SwapPoints();
                        LineSegment2D line2 = poly.GetEdge((i + 1) % poly.VertexCount);
                        Vector2D v2 = line1.ToVector();
                        Vector2D v3 = line2.ToVector();

                        double angle1 = Vector2D.Angle(v2, v1);
                        double angle2 = Vector2D.Angle(v1, v3);  //ѡȡ���ֽǶ�����ȵĵ����ָ��

                        if (angle1 < 0)
                        {
                            angle1 += Math.PI * 2;
                        }
                        if (angle2 < 0)
                        {
                            angle2 += Math.PI * 2;
                        }

                        double dist = Math.Max(angle1, angle2);
                        if (!poly.isConvexAngle(j) && dist < Math.PI)
                        {
                            dist -= Math.PI;
                        }

                        if(dist < min_dist)
                        {
                            index = j;
                            min_dist = dist;
                        }
                    }
                }
                if (index != i)
                {
                    this.DividedBy(new LineSegment2D(poly.GetPoint(i), poly.GetPoint(index)));
                    return;
                }
            }
            throw (new ArgumentException());
        }
Ejemplo n.º 38
0
        /// <summary>
        /// Whether the line segment is the diagonal of this polygon.
        /// </summary>
        /// <param name="lineSegment">the line segment.</param>
        /// <returns>true if is diagonal.</returns>
        public bool isDiagonal(LineSegment2D lineSegment)
        {
            if (!lineSegment.isRegular)
            {
                return false;
            }
            if (this.isEdge(lineSegment))
            {
                return false;
            }
            if (!this.Contains(lineSegment))
            {
                return false;
            }

            for (int i = 0; i < this.VertexCount; i++)
            {
                if (lineSegment.TrulyContains(this.Vertices[i]))
                {
                    return false;
                }
            }
            for (int i = 0; i < this.VertexCount; i++)
            {
                if (lineSegment.FirstPoint == this.Vertices[i])
                {
                    for (int j = 0; j < this.VertexCount; j++)
                    {
                        if (lineSegment.LastPoint == this.Vertices[j])
                        {
                            return true;
                        }
                    }
                    return false;
                }
            }
            return false;
        }
Ejemplo n.º 39
0
        /// <summary>
        /// Whether the other line segment's line can truly intersects this line segment.
        /// </summary>
        /// <param name="line">the other line segment.</param>
        /// <returns>true if truly intersects.</returns>
        internal bool TrulyLineIntersects(LineSegment2D line)
        {
            /*Vector2D v1 = this.FirstPoint - line.FirstPoint;
            Vector2D v2 = line.LastPoint - line.FirstPoint;
            Vector2D v3 = this.LastPoint - line.FirstPoint;

            if (Vector2D.Determinant(v1, v2) * Vector2D.Determinant(v2, v3) >= ZeroTolerance)
            {
                double d = Vector2D.Determinant(v1, v2) * Vector2D.Determinant(v2, v3);
                return true;
            }
            else
            {
                return false;
            }*/
            double x1 = this.FirstPoint.X - line.FirstPoint.X;
            double y1 = this.FirstPoint.Y - line.FirstPoint.Y;
            double x2 = line.LastPoint.X - line.FirstPoint.X;
            double y2 = line.LastPoint.Y - line.FirstPoint.Y;
            double x3 = this.LastPoint.X - line.FirstPoint.X;
            double y3 = this.LastPoint.Y - line.FirstPoint.Y;
            double d1 = x1 * y2 - x2 * y1;
            double d2 = x2 * y3 - x3 * y2;

            if (d1 * d2 >= ZeroTolerance)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
Ejemplo n.º 40
0
        /// <summary>
        /// Whether the line segment is a edge of this polygon.
        /// </summary>
        /// <param name="lineSegment">the line segment.</param>
        /// <returns>true if is edge.</returns>
        public bool isEdge(LineSegment2D lineSegment)
        {
            for (int i = 0; i < this.VertexCount; i++)
            {
                if (lineSegment == this.GetEdge(i))
                {
                    return true;
                }
            }

            return false;
        }
Ejemplo n.º 41
0
        private GhostTriangle2D Split(Polygon2D first, Polygon2D second, GhostTriangle2D ghostTriangle)
        {
            Triangle2D triangle = ghostTriangle.ToTriangle(first);
            LineSegment2D splitLine = Max(triangle.AB, triangle.BC, triangle.AC);
            int a = first.GetPointIndex(splitLine.FirstPoint);
            int b = first.GetPointIndex(splitLine.LastPoint);
            Point2D p1 = splitLine.MidPoint;
            splitLine = new LineSegment2D(second.GetPoint(a), second.GetPoint(b));
            Point2D p2 = splitLine.MidPoint;

            Polygon2DEditor polygonEditor = new Polygon2DEditor(first);
            polygonEditor.AddInnerPoint(p1);
            polygonEditor = new Polygon2DEditor(second);
            polygonEditor.AddInnerPoint(p2);

            return new GhostTriangle2D(a, b, first.PointCount - 1);
        }
        public void Union(LineSegment2DCollection lineSegment2DCollection)
        {
            Capacity += lineSegment2DCollection.Capacity;

            LineSegment2D[] lineSegments = new LineSegment2D[Capacity];

            this.LineSegments.CopyTo(lineSegments, 0);
            lineSegment2DCollection.LineSegments.CopyTo(lineSegments, this.Count);
            this.LineSegments = lineSegments;
            CurrentCount += lineSegment2DCollection.Count;
        }
Ejemplo n.º 43
0
        /// <summary>
        /// Whether this line segment contains the other.
        /// </summary>
        /// <param name="lineSegment">the other line segment.</param>
        /// <returns>true if contains.</returns>
        public bool Contains(LineSegment2D lineSegment)
        {
            if (this.Contains(lineSegment.FirstPoint) && this.Contains(lineSegment.LastPoint))
            {
                return true;
            }

            return false;
        }
 public LineSegment2DCollection(LineSegment2D[] lineSegments)
 {
     Capacity = lineSegments.Length;
     LineSegments = lineSegments;
     CurrentCount = Capacity;
 }
Ejemplo n.º 45
0
        /// <summary>
        /// Whether the two line segments inflect each other.
        /// </summary>
        /// <param name="lineSegment">the target linesegment</param>
        /// <returns>true if inflect</returns>
        public bool Inflects(LineSegment2D lineSegment)
        {
            if (this.TrulyContains(lineSegment.FirstPoint) || this.TrulyContains(lineSegment.LastPoint))
            {
                if (this.ToVector() * lineSegment.ToVector() < ZeroTolerance)
                {
                    return true;
                }
            }

            if (this.Contains(lineSegment) || lineSegment.Contains(this))
            {
                return true;
            }

            return false;
        }
Ejemplo n.º 46
0
        private void Triangulation(int a, int b, int c)
        {
            Debug.Assert(a != b && b != c && c != a);

            Triangle2D triangle = new Triangle2D(this.polygon.GetPoint(a), this.polygon.GetPoint(b), this.polygon.GetPoint(c));
            GhostTriangle2D ghost = new GhostTriangle2D(a, b, c);
            this.triangles.Add(triangle);
            this.ghostTriangles.Add(ghost);

            if (lineSegments.Count < polygon.VertexCount - 3)
            {
                Vector2D internalSegment = new Vector2D(a, c);
                LineSegment2D lineSegment = new LineSegment2D(this.polygon.GetPoint(a), this.polygon.GetPoint(c));
                this.lineSegments.Add(lineSegment);
                this.internalSegments.Add(internalSegment);
            }
        }
Ejemplo n.º 47
0
 /// <summary>
 /// Whether the two line segment truly intersect each other.
 /// </summary>
 /// <param name="lineSegment">the other line segment.</param>
 /// <returns>true if truly intersect.</returns>
 public bool TrulyIntersects(LineSegment2D lineSegment)
 {
     if (!this.ExtentIntersects(lineSegment))
     {
         return false;
     }
     return lineSegment.TrulyLineIntersects(this) && this.TrulyLineIntersects(lineSegment);
 }
        /// <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;
            }
        }
Ejemplo n.º 49
0
        /// <summary>
        /// Whether the two extents intersect each other.
        /// (x1,y1)-----------------------------
        /// -         Extent                   -
        /// ------------------------------(x2,y2)
        /// </summary>
        /// <param name="line">the other line.</param>
        /// <returns>true if intersect.</returns>
        private bool ExtentIntersects(LineSegment2D line)
        {
            double x1, y1;
            double x2, y2;
            double x3, y3;
            double x4, y4;

            x1 = Math.Min(this.FirstPoint.X, this.LastPoint.X);
            x2 = Math.Max(this.FirstPoint.X, this.LastPoint.X);
            y1 = Math.Min(this.FirstPoint.Y, this.LastPoint.Y);
            y2 = Math.Max(this.FirstPoint.Y, this.LastPoint.Y);
            x3 = Math.Min(line.FirstPoint.X, line.LastPoint.X);
            x4 = Math.Max(line.FirstPoint.X, line.LastPoint.X);
            y3 = Math.Min(line.FirstPoint.Y, line.LastPoint.Y);
            y4 = Math.Max(line.FirstPoint.Y, line.LastPoint.Y);
            if (x1 <= x4 && x2 >= x3 && y1 <= y4 && y2 >= y3)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <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);
            }
        }