Beispiel #1
0
        public bool borders(Polygon another)
        {
            var len1 = this.Count;
            var len2 = another.Count;

            for (var i = 0; i < len1; i++)
            {
                var j = another.IndexOf(this[i]);
                if (j != -1)
                {
                    var next = this[(i + 1) % len1];
                    // If this cause is not true, then should return false,
                    // but it doesn't work for some reason
                    if (next == another[(j + 1) % len2] || next == another[(j + len2 - 1) % len2])
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Beispiel #2
0
        // This  insets all edges by distances defined in an array.
        // It's kind of reliable for both convex and concave vertices, but only
        // if all distances are equal. Otherwise weird "steps" are created.
        // It does change the number of vertices.
        public Polygon buffer(List <float> d)
        {
            // Creating a polygon (probably invalid) with offset edges
            var q = new Polygon();
            var k = 0;

            forEdge((Point v0, Point v1) =>
            {
                var dd = d[k++];
                if (dd == 0)
                {
                    q.Add(v0);
                    q.Add(v1);
                }
                else
                {
                    // here we may want to do something fancier for nicer joints
                    var v = v1.vec - v0.vec;
                    var n = (Vector2)(Quaternion.Euler(0, 0, 90) * v.normalized * (dd));
                    q.Add(new Point(v0.vec + n));
                    q.Add(new Point(v1.vec + n));
                }
            });

            // Creating a valid polygon by dealing with self-intersection:
            // we need to find intersections of every edge with every other edge
            // and add intersection point (twice - for one edge and for the other)
            bool wasCut;
            var  lastEdge = 0;

            do
            {
                wasCut = false;

                var n = q.Count;
                for (var ii = lastEdge; ii < n - 2; ii++)
                {
                    lastEdge = ii;

                    var p11 = q[ii];
                    var p12 = q[ii + 1];
                    var x1  = p11.x;
                    var y1  = p11.y;
                    var dx1 = p12.x - x1;
                    var dy1 = p12.y - y1;

                    for (var j = ii + 2; j < (ii > 0 ? n : n - 1); j++)
                    {
                        var p21 = q[j];
                        var p22 = j < n - 1 ? q[j + 1] : q[0];
                        var x2  = p21.x;
                        var y2  = p21.y;
                        var dx2 = p22.x - x2;
                        var dy2 = p22.y - y2;

                        var int1 = GeomUtils.intersectLines(x1, y1, dx1, dy1, x2, y2, dx2, dy2);
                        if (int1 != null && int1?.x > DELTA && int1?.x < 1 - DELTA && int1?.y > DELTA && int1?.y < 1 - DELTA)
                        {
                            var pn = new Point(x1 + dx1 * int1.x, y1 + dy1 * int1.x);

                            q.Insert(j + 1, pn);
                            q.Insert(ii + 1, pn);

                            wasCut = true;
                            break;
                        }
                    }
                    if (wasCut)
                    {
                        break;
                    }
                }
            } while (wasCut);


            // Checking every part of the polygon to pick the biggest
            var regular = new List <int>();

            for (var i = 0; i < q.Count; i++)
            {
                regular.Add(i);
            }

            var bestPart   = new List <Point>();
            var bestPartSq = Mathf.NegativeInfinity;

            while (regular.Count > 0)
            {
                var indices = new List <int>();
                var start   = regular[0];
                var i       = start;
                do
                {
                    indices.Add(i);
                    regular.Remove(i);

                    var next  = (i + 1) % q.Count;
                    var v     = q[next];
                    var next1 = q.IndexOf(v);
                    if (next1 == next)
                    {
                        next1 = q.LastIndexOf(v);
                    }
                    i = (next1 == -1 ? next : next1);
                } while (i != start);

                var p = new Polygon(indices.Select(n => q[n]).ToList());

                var s = p.square;
                if (s > bestPartSq)
                {
                    bestPart   = p;
                    bestPartSq = s;
                }
            }

            return(new Polygon(bestPart));
        }