コード例 #1
0
        /// <summary>
        /// Given a set of points ordered counter-clockwise along a contour and a set of holes, return triangle indexes.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="holes"></param>
        /// <param name="indexes">Indices outside of the points list index into holes when layed out linearly.
        /// {vertices 0,1,2...vertices.length-1, holes 0 values, hole 1 values etc.} </param>
        /// <returns></returns>
        public static bool Triangulate(IList <Vector2> points, IList <IList <Vector2> > holes, out List <int> indexes)
        {
            indexes = new List <int>();

            int index = 0;

            var allPoints = new List <Vector2>(points);

            Polygon polygon = new Polygon(points.Select(x => new PolygonPoint(x.x, x.y, index++)));

            if (holes != null)
            {
                for (int i = 0; i < holes.Count; i++)
                {
                    allPoints.AddRange(holes[i]);
                    var holePolgyon = new Polygon(holes[i].Select(x => new PolygonPoint(x.x, x.y, index++)));
                    polygon.AddHole(holePolgyon);
                }
            }

            try
            {
                P2T.Triangulate(TriangulationAlgorithm.DTSweep, polygon);
            }
            catch (System.Exception e)
            {
                Log.Info("Triangulation failed: " + e.ToString());
                return(false);
            }

            foreach (DelaunayTriangle d in polygon.Triangles)
            {
                if (d.Points[0].Index < 0 || d.Points[1].Index < 0 || d.Points[2].Index < 0)
                {
                    Log.Info("Triangulation failed: Additional vertices were inserted.");
                    return(false);
                }

                indexes.Add(d.Points[0].Index);
                indexes.Add(d.Points[1].Index);
                indexes.Add(d.Points[2].Index);
            }

            WindingOrder originalWinding = SurfaceTopology.GetWindingOrder(points);

            // if the re-triangulated first tri doesn't match the winding order of the original
            // vertices, flip 'em

            if (SurfaceTopology.GetWindingOrder(new Vector2[3]
            {
                allPoints[indexes[0]],
                allPoints[indexes[1]],
                allPoints[indexes[2]],
            }) != originalWinding)
            {
                indexes.Reverse();
            }

            return(true);
        }
コード例 #2
0
        /// <summary>
        /// Given a set of points ordered counter-clockwise along a contour, return triangle indexes.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="indexes"></param>
        /// <param name="convex">Triangulation may optionally be set to convex, which will result in some a convex shape.</param>
        /// <returns></returns>
        public static bool Triangulate(IList <Vector2> points, out List <int> indexes, bool convex = false)
        {
            indexes = new List <int>();

            int index = 0;

            Triangulatable soup = convex
                ? new PointSet(points.Select(x => new TriangulationPoint(x.x, x.y, index++)).ToList())
                : (Triangulatable) new Polygon(points.Select(x => new PolygonPoint(x.x, x.y, index++)));

            try
            {
                triangulationContext.Clear();
                triangulationContext.PrepareTriangulation(soup);
                DTSweep.Triangulate((DTSweepContext)triangulationContext);
            }
            catch (System.Exception e)
            {
                Log.Info("Triangulation failed: " + e.ToString());
                return(false);
            }

            foreach (DelaunayTriangle d in soup.Triangles)
            {
                if (d.Points[0].Index < 0 || d.Points[1].Index < 0 || d.Points[2].Index < 0)
                {
                    Log.Info("Triangulation failed: Additional vertices were inserted.");
                    return(false);
                }

                indexes.Add(d.Points[0].Index);
                indexes.Add(d.Points[1].Index);
                indexes.Add(d.Points[2].Index);
            }

            WindingOrder originalWinding = SurfaceTopology.GetWindingOrder(points);

            // if the re-triangulated first tri doesn't match the winding order of the original
            // vertices, flip 'em

            if (SurfaceTopology.GetWindingOrder(new Vector2[3]
            {
                points[indexes[0]],
                points[indexes[1]],
                points[indexes[2]],
            }) != originalWinding)
            {
                indexes.Reverse();
            }

            return(true);
        }