示例#1
0
        public Polygon RectangleInside()
        {
            var p1        = Vector2.zero;
            var p2        = Vector2.zero;
            var maxLength = float.MinValue;

            ForEachEdge((a, b, i) =>
            {
                var len = (a - b).magnitude;
                if (len > maxLength)
                {
                    p1        = a;
                    p2        = b;
                    maxLength = len;
                }
            });

            var rotated          = Rotate(GeometryHelpers.Angle(p1 - p2));
            var minY             = rotated.Vertices.Min(v => v.y);
            var greatestDistance = rotated.Vertices.Max(v => v.y - minY);

            var normal   = GeometryHelpers.Rotate90(p2 - p1).normalized;
            var newHouse = new Polygon(p1, p2, p2 - GeometryHelpers.Scale(normal, greatestDistance),
                                       p1 - GeometryHelpers.Scale(normal, greatestDistance)).ZoomShrink(0.2f);

            newHouse = newHouse.Translate(newHouse.Center - Center);

            return(newHouse);
        }
示例#2
0
        public Polygon Peel(Vector2 v1, float amount)
        {
            var v2 = GetNextVertex(v1);

            var n = GeometryHelpers.Scale(GeometryHelpers.Normalize(GeometryHelpers.Rotate90(v2 - v1)), amount);

            return(Cut(v1 + n, v2 + n, 0).First());
        }
示例#3
0
        public Polygon Shrink(IList <float> shrinkAmounts)
        {
            var newPoly = new Polygon(this);

            ForEachEdge((p1, p2, index) =>
            {
                var amount = shrinkAmounts[index];
                if (amount > 0)
                {
                    var n   = GeometryHelpers.Scale(GeometryHelpers.Normalize(GeometryHelpers.Rotate90(p2 - p1)), amount);
                    newPoly = newPoly.Cut(p1 + n, p2 + n, 0).First();
                }
            });
            return(newPoly);
        }
示例#4
0
        public Polygon Buffer(IList <float> shrinkAmounts)
        {
            var newPoly = new Polygon();

            ForEachEdge((p1, p2, index) =>
            {
                var amount = shrinkAmounts[index];
                if (amount <= 0.01)
                {
                    newPoly.Vertices.Add(p1);
                    newPoly.Vertices.Add(p2);
                }
                else
                {
                    var n = GeometryHelpers.Scale(GeometryHelpers.Normalize(GeometryHelpers.Rotate90(p2 - p1)), amount);
                    newPoly.Vertices.Add(p1 + n);
                    newPoly.Vertices.Add(p2 + n);
                }
            });

            bool wasCut;
            var  lastEdge = 0;

            do
            {
                wasCut = false;

                var n = newPoly.Vertices.Count;

                for (var i = lastEdge; i < n - 2; i++)
                {
                    lastEdge = i;

                    var p11 = newPoly.Vertices[i];
                    var p12 = newPoly.Vertices[i + 1];
                    var x1  = p11.x;
                    var y1  = p11.y;
                    var dx1 = p12.x - x1;
                    var dy1 = p12.y - y1;

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

                        var intersect = GeometryHelpers.IntersectLines(x1, y1, dx1, dy1, x2, y2, dx2, dy2);
                        if (intersect.x > Delta && intersect.x < (1 - Delta) && intersect.y > Delta && intersect.y < (1 - Delta))
                        {
                            var pn = new Vector2(x1 + dx1 * intersect.x, y1 + dy1 * intersect.x);
                            newPoly.Vertices.Insert(j + 1, pn);
                            newPoly.Vertices.Insert(i + 1, pn);

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

            var regular = Enumerable.Range(0, newPoly.Vertices.Count).ToList();

            Polygon bestPart   = null;
            var     bestPartSq = float.MinValue;

            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) % newPoly.Vertices.Count;
                    var v     = newPoly.Vertices[next];
                    var next1 = newPoly.Vertices.IndexOf(v);
                    if (next1 == next)
                    {
                        next1 = newPoly.Vertices.LastIndexOf(v);
                    }
                    i = next1 == -1 ? next : next1;
                } while (i != start && indices.Count < 1000);

                if (indices.Count >= 999)
                {
                    indices = indices.Take(4).ToList();
                }

                var poly = new Polygon(indices.Select(v => newPoly.Vertices[v]));

                var s = poly.Area();
                if (s > bestPartSq)
                {
                    bestPart   = poly;
                    bestPartSq = s;
                }
            }

            return(bestPart);
        }