/// <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);
        }
        /// <summary>
        /// Divide a polygon by a path.(point2DCollection)
        /// </summary>
        /// <param name="path">the path.</param>
        /// <param name="polygon">the polygon to divide.</param>
        public void DividedBy(Point2DCollection path, Polygon2D polygon)
        {
            int a = polygon.HasVertex(path.FirstPoint);
            int b = polygon.HasVertex(path.LastPoint);

            if (a == Polygon2D.NoSuchPoint || b == Polygon2D.NoSuchPoint)
            {
                throw (new ArgumentException());
            }

            if (a > b)
            {
                int tmp = a;

                a = b;
                b = tmp;
            }

            Point2DCollection p2 = new Point2DCollection();
            Point2DCollection p1 = new Point2DCollection();

            for (int i = 0; i < polygon.VertexCount; i++)
            {
                if (i <= a || i >= b)
                {
                    p1.Add(polygon.GetPoint(i));
                }

                if (i >= a && i <= b)
                {
                    p2.Add(polygon.GetPoint(i));
                }
            }

            for (int i = 1; i < path.Count - 1; i++)
            {
                p1.Add(path[i], a + i);
                p2.Add(path[i], 0);
                Parent.AddInner(path[i]);
            }

            if (p1.Count > p2.Count)
            {
                SubDivision.Add(new Polygon2D(p1));
                SubDivision.Add(new Polygon2D(p2));
            }
            else
            {
                SubDivision.Add(new Polygon2D(p2));
                SubDivision.Add(new Polygon2D(p1));
            }
        }
        public Polygon2DLinkMaker(Polygon2D polygon, int a, int b) : base(polygon)
        {
            if (!polygon.isRegular)
            {
                throw (new ArgumentException());
            }

            FirstPoint   = polygon.GetPoint(a);
            LastPoint    = polygon.GetPoint(b);
            LinkDivisers = new Point2DCollection();
            //Partitions = new Polygon2DCollection();
            //Partitions.Add(polygon);
        }
        /// <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);
                }
            }
        }
        public Polygon2DLinkMaker(Polygon2D polygon, int a, int b)
            : base(polygon)
        {
            if (!polygon.isRegular)
            {
                throw (new ArgumentException());
            }

            FirstPoint = polygon.GetPoint(a);
            LastPoint = polygon.GetPoint(b);
            LinkDivisers = new Point2DCollection();
            //Partitions = new Polygon2DCollection();
            //Partitions.Add(polygon);
        }
        /// <summary>
        /// Divide a polygon by a path.(point2DCollection)
        /// </summary>
        /// <param name="path">the path.</param>
        /// <param name="polygon">the polygon to divide.</param>
        public void DividedBy(Point2DCollection path, Polygon2D polygon)
        {
            int a = polygon.HasVertex(path.FirstPoint);
            int b = polygon.HasVertex(path.LastPoint);

            if (a == Polygon2D.NoSuchPoint || b == Polygon2D.NoSuchPoint)
            {
                throw (new ArgumentException());
            }

            if (a > b)
            {
                int tmp = a;

                a = b;
                b = tmp;
            }

            Point2DCollection p2 = new Point2DCollection();
            Point2DCollection p1 = new Point2DCollection();

            for (int i = 0; i < polygon.VertexCount; i++)
            {
                if (i <= a || i >= b)
                {
                    p1.Add(polygon.GetPoint(i));
                }

                if (i >= a && i <= b)
                {
                    p2.Add(polygon.GetPoint(i));
                }
            }

            for (int i = 1; i < path.Count - 1; i++)
            {
                p1.Add(path[i], a + i);
                p2.Add(path[i], 0);
                Parent.AddInner(path[i]);
            }

            if (p1.Count > p2.Count)
            {
                SubDivision.Add(new Polygon2D(p1));
                SubDivision.Add(new Polygon2D(p2));
            }
            else
            {
                SubDivision.Add(new Polygon2D(p2));
                SubDivision.Add(new Polygon2D(p1));
            }
        }
        /// <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);
            }
        }
        public Triangle2D ToTriangle(Polygon2D polygon)
        {
            Point2D a = polygon.GetPoint(this.A);
            Point2D b = polygon.GetPoint(this.B);
            Point2D c = polygon.GetPoint(this.C);

            return new Triangle2D(a, b, c);
        }
Example #9
0
 private void SetReverse(Polygon2D polygon)
 {
     for (int i = 0; i < polygon.VertexCount; i++)
     {
         Point2D point = polygon.GetPoint(i);
         if (this.Reverse < point.Y)
         {
             this.Reverse = point.Y;
         }
     }
 }
Example #10
0
        public void Write(Polygon2D Polygon)
        {
            this.SetReverse(Polygon);

            XmlTextWriter xmlWriter = new XmlTextWriter(Path, Encoding.UTF8);

            xmlWriter.WriteStartDocument(true);
                xmlWriter.WriteStartElement("pn", "Polygon", "urn:Microsoft.VS.Akira.Triangulations");
                    xmlWriter.WriteStartElement("pn:Coordinate");
                        xmlWriter.WriteStartAttribute("", "type", "");
                            xmlWriter.WriteString("Reversed");
                        xmlWriter.WriteEndAttribute();
                        xmlWriter.WriteStartAttribute("", "top", "");
                            xmlWriter.WriteString(this.Reverse.ToString());
                        xmlWriter.WriteEndAttribute();
                        xmlWriter.WriteStartAttribute("", "margin", "");
                            xmlWriter.WriteString(XWFParser.Margin.ToString());
                        xmlWriter.WriteEndAttribute();
                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteStartElement("pn:Vertices");
                        xmlWriter.WriteStartAttribute("","count","");
                        xmlWriter.WriteString(Polygon.VertexCount.ToString());
                        xmlWriter.WriteEndAttribute();

            for(int i = 0; i < Polygon.VertexCount; i++)
            {
                Point2D point = new Point2D(Polygon.GetPoint(i));
                point.Y = this.Reverse + XWFParser.Margin - point.Y;

                xmlWriter.WriteStartElement("pn:Vertex");
                xmlWriter.WriteStartAttribute("","index","");
                xmlWriter.WriteString(i.ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteStartAttribute("","x","");
                xmlWriter.WriteString(point.X.ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteStartAttribute("","y","");
                xmlWriter.WriteString(point.Y.ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteStartAttribute("","z","");
                xmlWriter.WriteString("0");
                xmlWriter.WriteEndAttribute();

                xmlWriter.WriteEndElement();
            }

                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteStartElement("pn:Edges");

            for (int i = 0; i < Polygon.VertexCount; i++)
            {
                xmlWriter.WriteStartElement("pn:Edge");
                xmlWriter.WriteStartAttribute("","from","");
                xmlWriter.WriteString(i.ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteStartAttribute("","to","");
                xmlWriter.WriteString(((i+1) % Polygon.VertexCount).ToString());
                xmlWriter.WriteEndAttribute();
                xmlWriter.WriteEndElement();
            }

                    xmlWriter.WriteEndElement();
                xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();

            xmlWriter.Close();
        }
Example #11
0
        public void Write(Polygon2D polygon)
        {
            Stream stream = new FileStream(this.Path, FileMode.Create, FileAccess.Write, FileShare.None);

            string str = "# WFMESH2";

            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            str = "# Created by Triangulator";

            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            str = "# Vertices";

            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            this.SetReverse(polygon);

            for (int i = 0; i < polygon.VertexCount; i++)
            {
                Point2D point = new Point2D(polygon.GetPoint(i));
                point.Y = this.Reverse + WFParser.Margin - point.Y;

                str = point.X.ToString() + " " + point.Y.ToString() + " " + "0.00" + " " + i.ToString();

                stream.Write(this.GetBytes(str), 0, str.Length);
                stream.WriteByte((byte)'\r');
                stream.WriteByte((byte)'\n');
            }

            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            str = "# Edges";
            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            for (int i = 0; i < polygon.VertexCount - 1; i++)
            {
                str = i.ToString() + " " + (i + 1).ToString();

                stream.Write(this.GetBytes(str), 0, str.Length);
                stream.WriteByte((byte)'\r');
                stream.WriteByte((byte)'\n');
            }

            str = (polygon.VertexCount - 1).ToString() + " 0";

            stream.Write(this.GetBytes(str), 0, str.Length);
            stream.WriteByte((byte)'\r');
            stream.WriteByte((byte)'\n');

            stream.Close();
        }
        public int GetParentIndex(int PointIndex, int SubIndex)
        {
            Polygon2D subPolygon = this.SubDivision[SubIndex];

            return(this.Parent.GetPointIndex(subPolygon.GetPoint(PointIndex)));
        }
        /// <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);
            }
        }
Example #14
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());
        }
        /// <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;
            }
        }
        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);
        }
Example #17
0
        private Polygon2D FlipArea(GhostTriangle2D a, GhostTriangle2D b, Polygon2D poly)
        {
            if (!isNeighbor(a, b))
            {
                throw (new ArgumentException());
            }

            Map(a, b);

            Point2DCollection points = new Point2DCollection(4);

            points.Add(poly.GetPoint(a.C));
            points.Add(poly.GetPoint(a.A));
            points.Add(poly.GetPoint(b.C));
            points.Add(poly.GetPoint(b.B));

            Polygon2D polygon = new Polygon2D(points);
            return polygon;
        }