Esempio n. 1
0
        /// <summary>
        ///  Non destructive join of two rectangles.
        /// </summary>
        /// <param name="a">first joined rectangle
        /// </param>
        /// <param name="b">second joined rectangle
        /// </param>
        /// <returns>rectangle containing cover of these two rectangles
        /// </returns>
        public static RectangleRn Join(RectangleRn a, RectangleRn b)
        {
            RectangleRn r = new RectangleRn(a);

            r.Join(b);
            return(r);
        }
            public RectangleRn WrappingRectangle()
            {
                Line        line = new Line(points[0], points[1]);
                RectangleRn wr   = line.WrappingRectangle();

                for (int i = 1; i < points.Length; i++)
                {
                    line = new Line(points[i], points[(i + 1) % points.Length]);
                    wr.Join(line.WrappingRectangle());
                }
                return(wr);
            }
 /// <summary>
 ///  Non destructive join of two rectangles. 
 /// </summary>
 /// <param name="a">first joined rectangle
 /// </param>
 /// <param name="b">second joined rectangle
 /// </param>
 /// <returns>rectangle containing cover of these two rectangles
 /// </returns>
 public static RectangleRn Join(RectangleRn a, RectangleRn b) 
 {
     RectangleRn r = new RectangleRn(a);
     r.Join(b);
     return r;
 }
 internal RectangleRn cover()
 {
     RectangleRn r = new RectangleRn(b[0]);
     for (int i = 1; i < n; i++)
     {
         r.Join(b[i]);
     }
     return r;
 }
        RtreeRnPage splitPage(Storage storage, RectangleRn r, object obj)
        {
            int i, j, seed0 = 0, seed1 = 0;
            double[] rectArea = new double[card+1];
            double   waste;
            double   worstWaste = Double.MinValue;
            //
            // As the seeds for the two groups, find two rectangles which waste
            // the most area if covered by a single rectangle.
            //
            rectArea[0] = r.Area();
            for (i = 0; i < card; i++)
            {
                rectArea[i+1] = b[i].Area();
            }
            RectangleRn bp = r;
            for (i = 0; i < card; i++)
            {
                for (j = i+1; j <= card; j++)
                {
                    waste = RectangleRn.JoinArea(bp, b[j-1]) - rectArea[i] - rectArea[j];
                    if (waste > worstWaste)
                    {
                        worstWaste = waste;
                        seed0 = i;
                        seed1 = j;
                    }
                }
                bp = b[i];
            }
            byte[] taken = new byte[card];
            RectangleRn group0, group1;
            double      groupArea0, groupArea1;
            int         groupCard0, groupCard1;
            RtreeRnPage pg;

            taken[seed1-1] = 2;
            group1 = new RectangleRn(b[seed1-1]);

            if (seed0 == 0)
            {
                group0 = new RectangleRn(r);
                pg = new RtreeRnPage(storage, obj, r);
            }
            else
            {
                group0 = new RectangleRn(b[seed0-1]);
                pg = new RtreeRnPage(storage, branch.GetRaw(seed0-1), group0);
                setBranch(seed0-1, r, obj);
            }
            groupCard0 = groupCard1 = 1;
            groupArea0 = rectArea[seed0];
            groupArea1 = rectArea[seed1];
            //
            // Split remaining rectangles between two groups.
            // The one chosen is the one with the greatest difference in area
            // expansion depending on which group - the rect most strongly
            // attracted to one group and repelled from the other.
            //
            while (groupCard0 + groupCard1 < card + 1
                && groupCard0 < card + 1 - card/2
                && groupCard1 < card + 1 - card/2)
            {
                int betterGroup = -1, chosen = -1;
                double biggestDiff = -1;
                for (i = 0; i < card; i++)
                {
                    if (taken[i] == 0)
                    {
                        double diff = (RectangleRn.JoinArea(group0, b[i]) - groupArea0)
                            - (RectangleRn.JoinArea(group1, b[i]) - groupArea1);
                        if (diff > biggestDiff || -diff > biggestDiff)
                        {
                            chosen = i;
                            if (diff < 0)
                            {
                                betterGroup = 0;
                                biggestDiff = -diff;
                            }
                            else
                            {
                                betterGroup = 1;
                                biggestDiff = diff;
                            }
                        }
                    }
                }
                Debug.Assert(chosen >= 0);
                if (betterGroup == 0)
                {
                    group0.Join(b[chosen]);
                    groupArea0 = group0.Area();
                    taken[chosen] = 1;
                    pg.setBranch(groupCard0++, b[chosen], branch.GetRaw(chosen));
                }
                else
                {
                    groupCard1 += 1;
                    group1.Join(b[chosen]);
                    groupArea1 = group1.Area();
                    taken[chosen] = 2;
                }
            }
            //
            // If one group gets too full, then remaining rectangle are
            // split between two groups in such way to balance cards of two groups.
            //
            if (groupCard0 + groupCard1 < card + 1)
            {
                for (i = 0; i < card; i++)
                {
                    if (taken[i] == 0)
                    {
                        if (groupCard0 >= groupCard1)
                        {
                            taken[i] = 2;
                            groupCard1 += 1;
                        }
                        else
                        {
                            taken[i] = 1;
                            pg.setBranch(groupCard0++, b[i], branch.GetRaw(i));
                        }
                    }
                }
            }
            pg.n = groupCard0;
            n = groupCard1;
            for (i = 0, j = 0; i < groupCard1; j++)
            {
                if (taken[j] == 2)
                {
                    setBranch(i++, b[j], branch.GetRaw(j));
                }
            }
            // truncate rest of link
            branch.Length = groupCard1;
            branch.Length = card;
            return pg;
        }