void Swap(int i, int j)
 {
     if (i != j)
     {
         ObjectWithBox t = geometries[i];
         geometries[i] = geometries[j];
         geometries[j] = t;
     }
 }
        private void FindSeeds(int first, int count, out int seed0, out BBox b0, out int seed1)
        {
            seed0 = first;
            b0    = geometries[seed0].Box;

            double area = -1.0f;

            //looking for seed0
            for (int i = first + 1; i < first + count; i++)
            {
                ObjectWithBox g  = geometries[i];
                BBox          b  = g.Box;
                double        ar = CommonArea(ref b0, ref b);
                if (ar > area)
                {
                    seed0 = i;
                    area  = ar;
                }
            }

            //looking for seed1
            seed1 = first;//I'm getting a compiler error: there is no need actually to init seed1
            area  = -1.0f;

            b0 = geometries[seed0].Box;

            for (int i = first; i < first + count; i++)
            {
                if (i == seed0)
                {
                    continue;
                }

                ObjectWithBox g = geometries[i];

                BBox b = g.Box;

                double ar = CommonArea(ref b0, ref b);
                if (ar > area)
                {
                    seed1 = i;
                    area  = ar;
                }
            }

            if (seed0 > seed1)
            {
                int t = seed1;
                seed1 = seed0;
                seed0 = t;
            }
        }
        private void SplitOnGroups(int first, int count, int seed0, ref BBox b0, int seed1, out BBox b1, out int count0, out int count1)
        {
            b0 = geometries[seed0].Box;
            b1 = geometries[seed1].Box;

            //reshuffling in place:
            //put the next element of the first group on the first not occupied place on from the left
            //put the next element of the second group to the last not occupied place to the right
            Swap(first, seed0);             //this puts the seed0 the most left position
            Swap(first + count - 1, seed1); //this puts seed1 to the right most position

            double ratio = 2;
            //lp points to the first not assigned element to the right of group 0
            int lp = first + 1;
            //rp
            int rp = first + count - 2; //seed1 stands at first +count-1

            count0 = 1;
            count1 = 1;

            while (count0 + count1 < count)
            {
                //First check the ratio of numbers of elements of the groups.
                //We need to keep the tree balanced. Let's watch that the ratio of the numbers of elements of the
                // two groups is between ratio and 1/ratio.
                ObjectWithBox g = geometries[lp];
                if (count0 * ratio < count1)
                {
                    AddToTheLeftGroup(ref b0, ref count0, ref lp, g);
                }
                else if (count1 * ratio < count0)
                {
                    AddToTheRightGroup(ref b1, ref count1, lp, ref rp, g);
                }
                else   //make decision based on the growing of the group boxes
                {
                    BBox   b             = g.Box;
                    double squareGrouth0 = CommonArea(ref b0, ref b) - b0.Area;
                    double squareGrouth1 = CommonArea(ref b1, ref b) - b1.Area;
                    if (squareGrouth0 < squareGrouth1)
                    {
                        AddToTheLeftGroup(ref b0, ref count0, ref lp, g);
                    }
                    else
                    {
                        AddToTheRightGroup(ref b1, ref count1, lp, ref rp, g);
                    }
                }
            }
        }
 private static void AddToTheLeftGroup(ref BBox b0, ref int count0, ref int lp, ObjectWithBox g) {
     lp++;
     count0++;
     b0.Add(g.Box);
 }
 private void AddToTheRightGroup(ref BBox b1, ref int count1, int lp, ref int rp, ObjectWithBox g) {
     Swap(lp, rp);
     rp--;
     b1.Add(g.Box);
     count1++;
 }
 private static void AddToTheLeftGroup(ref BBox b0, ref int count0, ref int lp, ObjectWithBox g)
 {
     lp++;
     count0++;
     b0.Add(g.Box);
 }
 private void AddToTheRightGroup(ref BBox b1, ref int count1, int lp, ref int rp, ObjectWithBox g)
 {
     Swap(lp, rp);
     rp--;
     b1.Add(g.Box);
     count1++;
 }