Example #1
0
        public static bool addSteinerPointsAtOffset(ref Polygon _polygon, ref ClipperOffset co, float offset, int seglenBigInt)
        {
            PolyTree resPolytree = new AXClipperLib.PolyTree();

            co.Execute(ref resPolytree, (double)(-offset * AXGeometryTools.Utilities.IntPointPrecision));
            Paths paths = Clipper.PolyTreeToPaths(resPolytree);

            if (paths != null && paths.Count > 0 && paths[0] != null && paths[0].Count > 0)
            {
                foreach (Path path in paths)
                {
                    if (path != null && path.Count > 0)
                    {
                        Path ppp = Pather.segmentPath(path, seglenBigInt);
                        if (ppp != null && ppp.Count > 0)
                        {
                            foreach (IntPoint ip in ppp)
                            {
                                _polygon.AddSteinerPoint(new TriangulationPoint((double)ip.X / (double)AXGeometryTools.Utilities.IntPointPrecision, (double)ip.Y / (double)AXGeometryTools.Utilities.IntPointPrecision));
                            }
                        }
                    }
                }


                return(true);
            }
            return(false);
        }
Example #2
0
        /// <summary>
        /// Add inner steiner points (for coly polygons)
        /// </summary>
        /// <param name="points"></param>
        public void AddSteiner(SplineLines.Line points)
        {
            for (int i = 0; i < points.polyPoints.Count; ++i)
            {
                polygon.AddSteinerPoint(points.polyPoints[i]);
            }

            this.data.Add(points);
        }
Example #3
0
    /// <summary>
    /// Creates a triangulation of the vertices given, and gives you the indices of it.
    /// </summary>
    /// <param name="aPoints">A list of points to triangulate.</param>
    /// <param name="aTreatAsPath">Should we discard any triangles at all? Use this if you want to get rid of triangles that are outside the path.</param>
    /// <param name="aInvert">if we're treating it as a path, should we instead sicard triangles inside the path?</param>
    /// <returns>A magical list of indices describing the triangulation!</returns>
    ///

    public static void GetVerticesAndIndices(List <Vector2> inputPoints, out List <Vector2> outputPoints, out List <int> outputIndices, float chunkWidth, float chunkHeight, float jitterX, float jitterY)
    {
        Polygon             poly;
        List <PolygonPoint> points             = new List <PolygonPoint>();
        List <Vector2>      interpolatedPoints = new List <Vector2>();
        float edgeCutLength = (chunkWidth + chunkHeight) * 0.5f;
        int   triangleIndex = 0;
        int   numChunksX;
        int   numChunksY;

        outputPoints  = new List <Vector2>();
        outputIndices = new List <int>();

        // Cut all the edges into smaller segments (so triangulation won't create long, thin shards along the edges)
        for (int i = 0; i < inputPoints.Count; i++)
        {
            Vector2 a;
            Vector2 b;
            float   distance;
            int     numCuts;
            float   cutLength;

            a = i == 0 ? inputPoints[inputPoints.Count - 1] : inputPoints[i - 1];
            b = inputPoints[i];

            distance  = (b - a).magnitude;
            numCuts   = (int)(distance / edgeCutLength);
            cutLength = distance / (float)numCuts;

            for (int j = 0; j < numCuts; j++)
            {
                Vector2 p = Vector2.Lerp(a, b, Mathf.Max(0f, Mathf.Min(1f, (j * cutLength / distance))));

                interpolatedPoints.Add(p);
            }
        }

        // Convert points to P2T, and create polygon
        foreach (Vector2 p in interpolatedPoints)
        {
            points.Add(new PolygonPoint(p.x, p.y));
        }
        poly = new Polygon(points);

        // Calculate number of chunks to split the polygon up into
        numChunksX = (int)(poly.Bounds.Width / chunkWidth);
        numChunksY = (int)(poly.Bounds.Height / chunkHeight);

        // Add steiner points (this is the reason for using Poly2Tri)
        UnityEngine.Random.seed = (int)(poly.Bounds.Left * poly.Bounds.Top);
        for (int i = 0; i < numChunksX; i++)
        {
            for (int j = 0; j < numChunksY; j++)
            {
                TriangulationPoint p = new TriangulationPoint(
                    i * chunkWidth + poly.Bounds.Left + UnityEngine.Random.Range(-jitterX, jitterX),
                    j * -chunkHeight + poly.Bounds.Top + UnityEngine.Random.Range(-jitterY, jitterY));

                if (poly.IsPointInside(p))
                {
                    poly.AddSteinerPoint(p);
                }
            }
        }

        // Triangulate
        P2T.Triangulate(poly);

        // Build output from triangulated polygon
        foreach (DelaunayTriangle triangle in poly.Triangles)
        {
            TriangulationPoint p1 = triangle.Points[0];
            TriangulationPoint p2 = triangle.PointCWFrom(p1);
            TriangulationPoint p3 = triangle.PointCWFrom(p2);

            outputPoints.Add(new Vector2(p1.Xf, p1.Yf));
            outputPoints.Add(new Vector2(p2.Xf, p2.Yf));
            outputPoints.Add(new Vector2(p3.Xf, p3.Yf));
            outputIndices.Add(triangleIndex++);
            outputIndices.Add(triangleIndex++);
            outputIndices.Add(triangleIndex++);
        }
    }