예제 #1
0
        private SectorPolygon EarClip(List <Vector2> polygon)
        {
            SectorPolygon output = new SectorPolygon();

            // Early out for convex polygons
            int conv = IsConvex(polygon);

            if (conv != 0)
            {
                if (conv == -1)
                {
                    polygon.Reverse();
                }

                output.points = polygon;

                for (int t = 0; t < polygon.Count - 2; t++)
                {
                    output.triangles.Add(0);
                    output.triangles.Add(t + 1);
                    output.triangles.Add(t + 2);
                }

                return(output);
            }

            // Now we earclip
            List <int> clippedIndexes = new List <int>();

            int polygonCount = polygon.Count;
            int i = 0;
            int i1, i2, i3;
            int safe = 5000;

            while (clippedIndexes.Count < polygonCount - 2 && safe >= 0)               // be careful!!!

            {
                i1 = i % polygonCount;

                while (clippedIndexes.Contains(i1))
                {
                    i1 = (i1 + 1) % polygonCount;
                }

                i2 = (i1 + 1) % polygonCount;

                while (clippedIndexes.Contains(i2) || i2 == i1)
                {
                    i2 = (i2 + 1) % polygonCount;
                }

                i3 = (i2 + 1) % polygonCount;

                while (clippedIndexes.Contains(i3) || i3 == i2)
                {
                    i3 = (i3 + 1) % polygonCount;
                }

                bool clipped      = false;
                bool intersects   = false;
                bool straightLine = false;

                if (PointOnLine(polygon[i1], polygon[i2], polygon[i3]))
                {
                    straightLine = true;
                }

                if (straightLine == false)
                {
                    for (int j = 0; j < polygonCount; j++)
                    {
                        int j1 = (j + 1) % polygonCount;
                        if (!Vector2.Equals(polygon[i1], polygon[j]) &&
                            !Vector2.Equals(polygon[i3], polygon[j]))
                        {
                            if (LinesIntersect(polygon, i1, i3, j, j1) &&
                                !Vector2.Equals(polygon[i1], polygon[j1]) &&
                                !Vector2.Equals(polygon[i3], polygon[j1]))
                            {
                                intersects = true;
                                break;
                            }

                            List <Vector2> testPoly = new List <Vector2>()
                            {
                                polygon[i1],
                                polygon[i2],
                                polygon[i3]
                            };

                            if (!Vector2.Equals(polygon[i2], polygon[j]) &&
                                PointInPolygon(polygon[j], testPoly))
                            {
                                intersects = true;
                                break;
                            }
                        }
                    }
                }

                if (intersects == false && straightLine == false)
                {
                    Vector2 midpoint = new Vector2((polygon[i3].x + polygon[i1].x) / 2f, (polygon[i3].y + polygon[i1].y) / 2f);

                    if (PointInPolygon(midpoint, polygon))
                    {
                        // Clippit!!!
                        clippedIndexes.Add(i2);
                        output.triangles.Add(i1);
                        output.triangles.Add(i2);
                        output.triangles.Add(i3);
                        clipped = true;
                    }
                }

                if (clipped == false)
                {
                    i    += 1;
                    safe -= 1;
                }
            }



            if (!IsClockwise(polygon))
            {
                output.triangles.Reverse();
            }

            output.points = polygon;

            if (safe <= 0)
            {
                // OPTIMISATION: Every time this is hit, the polygon is triangulated but we didn't catch it had finished
                // If we can succeessfully detect when it is done it'll hit this less and triangulation will be faster
                // Edit: i think we don't hit this any more
                Debug.LogWarning("EarClip: while loop broke safety net. Clipped Indexes :" + clippedIndexes.Count + " polygonCount: " + polygonCount);
                System.IO.File.WriteAllText("outputtriangles.json", JsonUtility.ToJson(output, true));
            }

            return(output);
        }
예제 #2
0
        public List <SectorPolygon> Triangulate(int sector)
        {
            if (benchmark)
            {
                debugTime = Time.realtimeSinceStartup;
            }
            int i;

            // Trace sector lines
            List <List <Vector2> > polygons;

            try {
                polygons = TraceLines(sector);
            } catch {
                Debug.LogError("Error tracing lines on sector: " + sector.ToString());
                return(null);
            }

            if (benchmark)
            {
                traceLinesTime += Time.realtimeSinceStartup - debugTime;
                debugTime       = Time.realtimeSinceStartup;
            }

            if (polygons == null)
            {
                return(null);
            }

            // Remove points on straight lines
            for (i = 0; i < polygons.Count; i++)
            {
                polygons[i] = CleanLines(polygons[i]);
            }

            if (benchmark)
            {
                cleanLinesTime += Time.realtimeSinceStartup - debugTime;
                debugTime       = Time.realtimeSinceStartup;
            }

            // Determine islands
            if (polygons.Count == 0)
            {
                return(null);
            }
            List <SectorIsland> islands = BuildIslands(polygons);

            if (benchmark)
            {
                buildIslandsTime += Time.realtimeSinceStartup - debugTime;
                debugTime         = Time.realtimeSinceStartup;
            }

            // Cut islands
            List <List <Vector2> > cutPolygons = new List <List <Vector2> >();

            for (i = 0; i < islands.Count; i++)
            {
                List <Vector2> cut = islands[i].Cut();
                if (cut != null)
                {
                    cutPolygons.Add(cut);
                }
            }

            if (benchmark)
            {
                cutPolygonsTime += Time.realtimeSinceStartup - debugTime;
                debugTime        = Time.realtimeSinceStartup;
            }

            // Ear clip
            List <SectorPolygon> output = new List <SectorPolygon>();

            for (i = 0; i < cutPolygons.Count; i++)
            {
                SectorPolygon sp = EarClip(cutPolygons[i]);
                if (sp != null)
                {
                    output.Add(sp);
                }
            }

            if (benchmark)
            {
                earClipTime += Time.realtimeSinceStartup - debugTime;
                debugTime    = Time.realtimeSinceStartup;
            }

            // Output
            return(output);
        }