Esempio n. 1
0
        void DrawSimpleRectWithHoleExample(Painter painter)
        {
            Poly2Tri.TriangulationPoint[] box = new Poly2Tri.TriangulationPoint[]
            {
                new Poly2Tri.TriangulationPoint(5, 5),
                new Poly2Tri.TriangulationPoint(45, 5),
                new Poly2Tri.TriangulationPoint(45, 45),
                new Poly2Tri.TriangulationPoint(5, 45)
            };

            Poly2Tri.TriangulationPoint[] hole = new Poly2Tri.TriangulationPoint[]
            {
                new Poly2Tri.TriangulationPoint(10, 10),
                new Poly2Tri.TriangulationPoint(40, 10),
                new Poly2Tri.TriangulationPoint(40, 40),
                new Poly2Tri.TriangulationPoint(10, 40)
            };

            Poly2Tri.Polygon polygon = new Poly2Tri.Polygon(box);
            polygon.AddHole(new Poly2Tri.Polygon(hole));

            Poly2Tri.P2T.Triangulate(polygon);


            painter.StrokeColor = Color.Black;

            DrawPoly2TriPolygon(painter, new List <Poly2Tri.Polygon>()
            {
                polygon
            });
        }
Esempio n. 2
0
        static void CreateIndexedMesh(IList <Poly2Tri.DelaunayTriangle> listTriangles, List <Vector3> listVerticesOut, List <int> listIndicesOut, Matrix4x4 mtxTransform, bool bTransform)
        {
            listVerticesOut.Clear();
            listIndicesOut.Clear();

            Vector3 v3Vertex = Vector3.zero;

            foreach (Poly2Tri.DelaunayTriangle triangle in listTriangles)
            {
                for (int i = 0; i < 3; i++)
                {
                    bool bFound = false;
                    int  nIndex = 0;

                    Poly2Tri.TriangulationPoint point = triangle.PointCWFrom(triangle.Points[i]);
                    v3Vertex.x = point.Xf;
                    v3Vertex.z = point.Yf;

                    foreach (Vector3 v3VertexIndexed in listVerticesOut)
                    {
                        if ((v3Vertex - v3VertexIndexed).magnitude < Parameters.EPSILONDISTANCEVERTEX)
                        {
                            bFound = true;
                            break;
                        }

                        nIndex++;
                    }

                    if (bFound == false)
                    {
                        listIndicesOut.Add(listVerticesOut.Count);
                        listVerticesOut.Add(v3Vertex);
                    }
                    else
                    {
                        listIndicesOut.Add(nIndex);
                    }
                }
            }

            if (bTransform)
            {
                for (int i = 0; i < listVerticesOut.Count; i++)
                {
                    listVerticesOut[i] = mtxTransform.MultiplyPoint3x4(listVerticesOut[i]);
                }
            }
        }
Esempio n. 3
0
        public static void dbugDrawPoly2TriPolygon(this Painter painter, List <Poly2Tri.Polygon> polygons)
        {
            foreach (Poly2Tri.Polygon polygon in polygons)
            {
                foreach (Poly2Tri.DelaunayTriangle tri in polygon.Triangles)
                {
                    Poly2Tri.TriangulationPoint p0 = tri.P0;
                    Poly2Tri.TriangulationPoint p1 = tri.P1;
                    Poly2Tri.TriangulationPoint p2 = tri.P2;

                    painter.DrawLine(p0.X, p0.Y, p1.X, p1.Y);
                    painter.DrawLine(p1.X, p1.Y, p2.X, p2.Y);
                    painter.DrawLine(p2.X, p2.Y, p0.X, p0.Y);
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// create polygon from GlyphContour
        /// </summary>
        /// <param name="cnt"></param>
        /// <returns></returns>
        static Poly2Tri.Polygon CreatePolygon(List <Vertex> flattenPoints)
        {
            List <Poly2Tri.TriangulationPoint> points = new List <Poly2Tri.TriangulationPoint>();

            //limitation: poly tri not accept duplicated points! ***
            double prevX = 0;
            double prevY = 0;

#if DEBUG
            //dbug check if all point is unique
            dbugCheckAllGlyphsAreUnique(flattenPoints);
#endif


            int j = flattenPoints.Count;
            //pass
            for (int i = 0; i < j; ++i)
            {
                Vertex p = flattenPoints[i];
                double x = p.OX; //start from original X***
                double y = p.OY; //start from original Y***

                if (x == prevX && y == prevY)
                {
                    if (i > 0)
                    {
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    var triPoint = new Poly2Tri.TriangulationPoint(prevX = x, prevY = y)
                    {
                        userData = p
                    };
#if DEBUG
                    p.dbugTriangulationPoint = triPoint;
#endif
                    points.Add(triPoint);
                }
            }

            return(new Poly2Tri.Polygon(points.ToArray()));
        }
Esempio n. 5
0
        void DrawSimpleRectExample(Painter painter)
        {
            Poly2Tri.TriangulationPoint[] points = new Poly2Tri.TriangulationPoint[]
            {
                new Poly2Tri.TriangulationPoint(10, 10),
                new Poly2Tri.TriangulationPoint(40, 10),
                new Poly2Tri.TriangulationPoint(40, 40),
                new Poly2Tri.TriangulationPoint(10, 40)
            };

            Poly2Tri.Polygon polygon = new Poly2Tri.Polygon(points);
            Poly2Tri.P2T.Triangulate(polygon);


            painter.StrokeColor = Color.Black;

            DrawPoly2TriPolygon(painter, new List <Poly2Tri.Polygon>()
            {
                polygon
            });
        }
Esempio n. 6
0
        void DrawVxsArrowHoleExample(Painter painter)
        {
            //1. background box
            Poly2Tri.TriangulationPoint[] box = new Poly2Tri.TriangulationPoint[]
            {
                new Poly2Tri.TriangulationPoint(5, 5),
                new Poly2Tri.TriangulationPoint(200, 5),
                new Poly2Tri.TriangulationPoint(200, 200),
                new Poly2Tri.TriangulationPoint(5, 200)
            };

            Poly2Tri.Polygon bgBoxPolygon = new Poly2Tri.Polygon(box);

            //2. arrow-shape hole
            VertexStore vxs = BuildArrow(true);

            using (Poly2TriTool.Borrow(out var p23tool))
            {
                p23tool.YAxisPointDown = true; //since our vxs is create from Y axis point down world

                List <Poly2Tri.Polygon> polygons = new List <Poly2Tri.Polygon>();
                p23tool.PreparePolygons(vxs, polygons);

                foreach (Poly2Tri.Polygon polygon in polygons)
                {
                    //arrow-shape hole
                    bgBoxPolygon.AddHole(polygon);
                }

                Poly2Tri.P2T.Triangulate(bgBoxPolygon);

                painter.StrokeColor = Color.Black;
                DrawPoly2TriPolygon(painter, new List <Poly2Tri.Polygon>()
                {
                    bgBoxPolygon
                });
            }
        }
        /// <summary>
        /// create polygon from GlyphContour
        /// </summary>
        /// <param name="cnt"></param>
        /// <returns></returns>
        static Poly2Tri.Polygon CreatePolygon(List <System.Drawing.PointF> flattenPoints)
        {
            List <Poly2Tri.TriangulationPoint> points = new List <Poly2Tri.TriangulationPoint>();

            //limitation: poly tri not accept duplicated points! ***
            double prevX = 0;
            double prevY = 0;

            int j = flattenPoints.Count;

            //pass
            for (int i = 0; i < j; ++i)
            {
                System.Drawing.PointF p = flattenPoints[i];
                double x = p.X; //start from original X***
                double y = p.Y; //start from original Y***

                if (x == prevX && y == prevY)
                {
                    if (i > 0)
                    {
                        //skip duplicated point
                        continue;
                    }
                }
                else
                {
                    var triPoint = new Poly2Tri.TriangulationPoint(prevX = x, prevY = y)
                    {
                        userData = p
                    };
                    points.Add(triPoint);
                }
            }

            return(new Poly2Tri.Polygon(points.ToArray()));
        }
Esempio n. 8
0
        void DrawOutput()
        {
            if (_g == null)
            {
                return;
            }

            //-----------
            //for GDI+ only
            bool flipYAxis  = chkFlipY.Checked;
            int  viewHeight = this.panel1.Height;

            //-----------
            //show tess
            _g.Clear(Color.White);
            int[]   contourEndIndices;
            float[] polygon1 = GetPolygonData(out contourEndIndices);
            if (polygon1 == null)
            {
                return;
            }
            //
            if (flipYAxis)
            {
                var transformMat = new System.Drawing.Drawing2D.Matrix();
                transformMat.Scale(1, -1);
                transformMat.Translate(0, -viewHeight);
                polygon1 = TransformPoints(polygon1, transformMat);

                //when we flipY, meaning of clockwise-counter clockwise is changed.
                //
                //see https://stackoverflow.com/questions/1165647/how-to-determine-if-a-list-of-polygon-points-are-in-clockwise-order
                //...(comment)
                //...A minor caveat: this answer assumes a normal Cartesian coordinate system.
                //The reason that's worth mentioning is that some common contexts, like HTML5 canvas, use an inverted Y-axis.
                //Then the rule has to be flipped: if the area is negative, the curve is clockwise. – LarsH Oct 11 '13 at 20:49
            }


            using (Pen pen1 = new Pen(Color.LightGray, 6))
            {
                int    nn = polygon1.Length;
                int    a  = 0;
                PointF p0;
                PointF p1;

                int contourCount = contourEndIndices.Length;
                int startAt      = 3;
                for (int cnt_index = 0; cnt_index < contourCount; ++cnt_index)
                {
                    int endAt = contourEndIndices[cnt_index];
                    for (int m = startAt; m <= endAt;)
                    {
                        p0 = new PointF(polygon1[m - 3], polygon1[m - 2]);
                        p1 = new PointF(polygon1[m - 1], polygon1[m]);
                        _g.DrawLine(pen1, p0, p1);
                        _g.DrawString(a.ToString(), this.Font, Brushes.Black, p0);
                        m += 2;
                        a++;
                    }
                    //close contour

                    p0 = new PointF(polygon1[endAt - 1], polygon1[endAt]);
                    p1 = new PointF(polygon1[startAt - 3], polygon1[startAt - 2]);
                    _g.DrawLine(pen1, p0, p1);
                    _g.DrawString(a.ToString(), this.Font, Brushes.Black, p0);
                    //
                    startAt = (endAt + 1) + 3;
                }
            }
            //----------------------------------------------------------------------------

            //tess
            if (rdoTessSGI.Checked)
            {
                //SGI Tess Lib

                if (!_tessTool.TessPolygon(polygon1, _contourEnds))
                {
                    return;
                }

                //1.
                List <ushort> indexList = _tessTool.TessIndexList;
                //2.
                List <TessVertex2d> tempVertexList = _tessTool.TempVertexList;
                //3.
                int vertexCount = indexList.Count;
                //-----------------------------
                int     orgVertexCount = polygon1.Length / 2;
                float[] vtx            = new float[vertexCount * 2];//***
                int     n = 0;

                for (int p = 0; p < vertexCount; ++p)
                {
                    ushort index = indexList[p];
                    if (index >= orgVertexCount)
                    {
                        //extra coord (newly created)
                        TessVertex2d extraVertex = tempVertexList[index - orgVertexCount];
                        vtx[n]     = (float)extraVertex.x;
                        vtx[n + 1] = (float)extraVertex.y;
                    }
                    else
                    {
                        //original corrd
                        vtx[n]     = (float)polygon1[index * 2];
                        vtx[n + 1] = (float)polygon1[(index * 2) + 1];
                    }
                    n += 2;
                }
                //-----------------------------
                //draw tess result
                int j = vtx.Length;
                for (int i = 0; i < j;)
                {
                    var p0 = new PointF(vtx[i], vtx[i + 1]);
                    var p1 = new PointF(vtx[i + 2], vtx[i + 3]);
                    var p2 = new PointF(vtx[i + 4], vtx[i + 5]);

                    _g.DrawLine(Pens.Red, p0, p1);
                    _g.DrawLine(Pens.Red, p1, p2);
                    _g.DrawLine(Pens.Red, p2, p0);

                    i += 6;
                }
            }
            else
            {
                List <Poly2Tri.Polygon> outputPolygons = new List <Poly2Tri.Polygon>();
                Poly2TriExampleHelper.Triangulate(polygon1, contourEndIndices, flipYAxis, outputPolygons);
                foreach (Poly2Tri.Polygon polygon in outputPolygons)
                {
                    foreach (Poly2Tri.DelaunayTriangle tri in polygon.Triangles)
                    {
                        Poly2Tri.TriangulationPoint p0 = tri.P0;
                        Poly2Tri.TriangulationPoint p1 = tri.P1;
                        Poly2Tri.TriangulationPoint p2 = tri.P2;

                        _g.DrawLine(Pens.Red, (float)p0.X, (float)p0.Y, (float)p1.X, (float)p1.Y);
                        _g.DrawLine(Pens.Red, (float)p1.X, (float)p1.Y, (float)p2.X, (float)p2.Y);
                        _g.DrawLine(Pens.Red, (float)p2.X, (float)p2.Y, (float)p0.X, (float)p0.Y);
                    }
                }
            }
        }
Esempio n. 9
0
        /// <summary>
        /// create polygon from flatten curve outline point
        /// </summary>
        /// <param name="cnt"></param>
        /// <returns></returns>
        static Poly2Tri.Polygon CreatePolygon2(GlyphContour cnt)
        {
            List <Poly2Tri.TriangulationPoint> points = new List <Poly2Tri.TriangulationPoint>();
            List <GlyphPart> allParts = cnt.parts;
            //---------------------------------------
            //merge all generated points
            //also remove duplicated point too!
            List <GlyphPoint2D> mergedPoints = new List <GlyphPoint2D>();

            cnt.mergedPoints = mergedPoints;
            //---------------------------------------
            {
                int tt = 0;
                int j  = allParts.Count;

                for (int i = 0; i < j; ++i)
                {
                    GlyphPart p = allParts[i];

                    List <GlyphPoint2D> fpoints = p.GetFlattenPoints();
                    if (tt == 0)
                    {
                        int n = fpoints.Count;
                        for (int m = 0; m < n; ++m)
                        {
                            //GlyphPoint2D fp = fpoints[m];
                            mergedPoints.Add(fpoints[m]);
                            //allPoints.Add((float)fp.x);
                            //allPoints.Add((float)fp.y);
                        }
                        tt++;
                    }
                    else
                    {
                        //except first point
                        int n = fpoints.Count;
                        for (int m = 1; m < n; ++m)
                        {
                            //GlyphPoint2D fp = fpoints[m];
                            mergedPoints.Add(fpoints[m]);
                            //allPoints.Add((float)fp.x);
                            //allPoints.Add((float)fp.y);
                        }
                    }
                }
            }
            //---------------------------------------
            {
                //check last (x,y) and first (x,y)
                int lim = mergedPoints.Count - 1;
                {
                    if (mergedPoints[lim].IsEqualValues(mergedPoints[0]))
                    {
                        //remove last (x,y)
                        mergedPoints.RemoveAt(lim);
                        lim -= 1;
                    }
                }

                //limitation: poly tri not accept duplicated points!
                double prevX = 0;
                double prevY = 0;
                Dictionary <TmpPoint, bool> tmpPoints = new Dictionary <TmpPoint, bool>();
                lim = mergedPoints.Count;

                for (int i = 0; i < lim; ++i)
                {
                    GlyphPoint2D p = mergedPoints[i];
                    double       x = p.x;
                    double       y = p.y;

                    if (x == prevX && y == prevY)
                    {
                        if (i > 0)
                        {
                            throw new NotSupportedException();
                        }
                    }
                    else
                    {
                        TmpPoint tmp_point = new TmpPoint(x, y);
                        if (!tmpPoints.ContainsKey(tmp_point))
                        {
                            //ensure no duplicated point
                            tmpPoints.Add(tmp_point, true);
                            var userTriangulationPoint = new Poly2Tri.TriangulationPoint(x, y)
                            {
                                userData = p
                            };
                            p.triangulationPoint = userTriangulationPoint;
                            points.Add(userTriangulationPoint);
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }

                        prevX = x;
                        prevY = y;
                    }
                }

                Poly2Tri.Polygon polygon = new Poly2Tri.Polygon(points.ToArray());
                return(polygon);
            }
        }
Esempio n. 10
0
        void DrawOutput()
        {
            if (_g == null)
            {
                return;
            }

            //-----------
            //for GDI+ only
            bool drawInvert = chkInvert.Checked;
            int  viewHeight = this.panel1.Height;

            //-----------
            //show tess
            _g.Clear(Color.White);
            int[]   contourEndIndices;
            float[] polygon1 = GetPolygonData(out contourEndIndices);
            if (polygon1 == null)
            {
                return;
            }
            //
            if (drawInvert)
            {
                var transformMat = new System.Drawing.Drawing2D.Matrix();
                transformMat.Scale(1, -1);
                transformMat.Translate(0, -viewHeight);
                //
                polygon1 = TransformPoints(polygon1, transformMat);
            }


            using (Pen pen1 = new Pen(Color.LightGray, 6))
            {
                int    nn = polygon1.Length;
                int    a  = 0;
                PointF p0;
                PointF p1;

                int contourCount = contourEndIndices.Length;
                int startAt      = 3;
                for (int cnt_index = 0; cnt_index < contourCount; ++cnt_index)
                {
                    int endAt = contourEndIndices[cnt_index];
                    for (int m = startAt; m <= endAt;)
                    {
                        p0 = new PointF(polygon1[m - 3], polygon1[m - 2]);
                        p1 = new PointF(polygon1[m - 1], polygon1[m]);
                        _g.DrawLine(pen1, p0, p1);
                        _g.DrawString(a.ToString(), this.Font, Brushes.Black, p0);
                        m += 2;
                        a++;
                    }
                    //close contour

                    p0 = new PointF(polygon1[endAt - 1], polygon1[endAt]);
                    p1 = new PointF(polygon1[startAt - 3], polygon1[startAt - 2]);
                    _g.DrawLine(pen1, p0, p1);
                    _g.DrawString(a.ToString(), this.Font, Brushes.Black, p0);
                    //
                    startAt = (endAt + 1) + 3;
                }
            }
            //----------------------------------------------------------------------------

            //tess
            if (rdoTessSGI.Checked)
            {
                //SGI Tess Lib

                if (!_tessTool.TessPolygon(polygon1, _contourEnds))
                {
                    return;
                }

                //1.
                List <ushort> indexList = _tessTool.TessIndexList;
                //2.
                List <TessVertex2d> tempVertexList = _tessTool.TempVertexList;
                //3.
                int vertexCount = indexList.Count;
                //-----------------------------
                int     orgVertexCount = polygon1.Length / 2;
                float[] vtx            = new float[vertexCount * 2];//***
                int     n = 0;

                for (int p = 0; p < vertexCount; ++p)
                {
                    ushort index = indexList[p];
                    if (index >= orgVertexCount)
                    {
                        //extra coord (newly created)
                        TessVertex2d extraVertex = tempVertexList[index - orgVertexCount];
                        vtx[n]     = (float)extraVertex.x;
                        vtx[n + 1] = (float)extraVertex.y;
                    }
                    else
                    {
                        //original corrd
                        vtx[n]     = (float)polygon1[index * 2];
                        vtx[n + 1] = (float)polygon1[(index * 2) + 1];
                    }
                    n += 2;
                }
                //-----------------------------
                //draw tess result
                int j = vtx.Length;
                for (int i = 0; i < j;)
                {
                    var p0 = new PointF(vtx[i], vtx[i + 1]);
                    var p1 = new PointF(vtx[i + 2], vtx[i + 3]);
                    var p2 = new PointF(vtx[i + 4], vtx[i + 5]);

                    _g.DrawLine(Pens.Red, p0, p1);
                    _g.DrawLine(Pens.Red, p1, p2);
                    _g.DrawLine(Pens.Red, p2, p0);

                    i += 6;
                }
            }
            else
            {
                Poly2Tri.Polygon mainPolygon = Poly2TriExampleHelper.Triangulate(polygon1, contourEndIndices);
                foreach (Poly2Tri.DelaunayTriangle tri in mainPolygon.Triangles)
                {
                    Poly2Tri.TriangulationPoint p0 = tri.P0;
                    Poly2Tri.TriangulationPoint p1 = tri.P1;
                    Poly2Tri.TriangulationPoint p2 = tri.P2;

                    _g.DrawLine(Pens.Red, (float)p0.X, (float)p0.Y, (float)p1.X, (float)p1.Y);
                    _g.DrawLine(Pens.Red, (float)p1.X, (float)p1.Y, (float)p2.X, (float)p2.Y);
                    _g.DrawLine(Pens.Red, (float)p2.X, (float)p2.Y, (float)p0.X, (float)p0.Y);
                }
            }
        }
Esempio n. 11
0
        private void PreparePolygons(IEnumerable <Poly2Tri.DelaunayTriangle> triangles)
        {
            this.PolygonEdges.Clear();
            this.Polygons.Clear();

            // For building edges we need a mapping of the original triangles to polygons
            Dictionary <Poly2Tri.DelaunayTriangle, Poly2Tri.Point2DList> triangleToPolygon = new Dictionary <Poly2Tri.DelaunayTriangle, Poly2Tri.Point2DList>();
            Dictionary <Poly2Tri.Point2DList, Poly2Tri.DelaunayTriangle> polygonToTriangle = new Dictionary <Poly2Tri.Point2DList, Poly2Tri.DelaunayTriangle>();

            // Initially, our polygons are simply the triangles in polygon form
            foreach (var triangle in triangles)
            {
                var polygonPoints            = triangle.Points.Select(p => new Poly2Tri.Point2D(p.X, p.Y)).ToList();
                Poly2Tri.Point2DList polygon = new Poly2Tri.Point2DList(polygonPoints);

                triangleToPolygon[triangle] = polygon;
                polygonToTriangle[polygon]  = triangle;

                this.Polygons.Add(polygon);
            }

            // Build up the edge list
            foreach (var polygon in this.Polygons)
            {
                // Does this polygon have any neighbors? If so, that's how we make our edges.
                var triangle = polygonToTriangle[polygon];

                // We can have up to 3 neighbors on each triangle
                for (int n = 0; n < 3; ++n)
                {
                    var neighborTriangle = triangle.Neighbors[n];
                    if (neighborTriangle == null)
                    {
                        continue;
                    }

                    if (!triangleToPolygon.ContainsKey(neighborTriangle))
                    {
                        continue;
                    }

                    var neighborPolygon = triangleToPolygon[neighborTriangle];

                    // If the neighbor polygon still has a triangle associated with it then we haven't added its edges yet
                    // Otherwise, we have added her edges and we don't want to do so again
                    if (!polygonToTriangle.ContainsKey(neighborPolygon))
                    {
                        continue;
                    }

                    // Gather the points needed for the edge
                    Poly2Tri.TriangulationPoint triPoint1 = triangle.Points[(n + 1) % 3];
                    Poly2Tri.TriangulationPoint triPoint2 = triangle.Points[(n + 2) % 3];

                    // Create an polygon edge
                    SharedPolygonEdge edge = new SharedPolygonEdge();
                    edge.PolygonA   = polygon;
                    edge.PolygonB   = neighborPolygon;
                    edge.EdgePoint1 = new Poly2Tri.PolygonPoint(triPoint1.X, triPoint1.Y);
                    edge.EdgePoint2 = new Poly2Tri.PolygonPoint(triPoint2.X, triPoint2.Y);
                    this.PolygonEdges.Add(edge);
                }

                // Remove the polygon from the triangle mapping. We are done with it.
                polygonToTriangle.Remove(polygon);
            }
        }