コード例 #1
0
 /// <summary>
 /// Join two rectangles. This rectangle is updates to contain cover of this and specified rectangle.
 /// </summary>
 /// <param name="r">rectangle to be joined with this rectangle
 /// </param>
 public void Join(RectangleRn r)
 {
     for (int i = 0, n = coords.Length / 2; i < n; i++)
     {
         coords[i]     = Math.Min(coords[i], r.coords[i]);
         coords[i + n] = Math.Max(coords[i + n], r.coords[i + n]);
     }
 }
コード例 #2
0
 internal RtreeRnPage(Storage storage, object obj, RectangleRn r)
 {
     branch = storage.CreateLink(card);
     branch.Length = card;
     b = new RectangleRn[card];
     setBranch(0, new RectangleRn(r), obj);
     n = 1;
 }
コード例 #3
0
 /// <summary>
 /// Area of covered rectangle for two sepcified rectangles
 /// </summary>
 public static double JoinArea(RectangleRn a, RectangleRn b) 
 {
     double area = 1.0;
     for (int i = 0, n = a.coords.Length/2; i < n; i++) { 
         double min = Math.Min(a.coords[i], b.coords[i]);
         double max = Math.Max(a.coords[n + i], b.coords[n + i]);
         area *= max - min;
     }
     return area;
 }
コード例 #4
0
 /// <summary>
 /// Checks if this rectangle contains the specified rectangle
 /// </summary>
 public bool Contains(RectangleRn r)
 {
     for (int i = 0, n = coords.Length / 2; i < n; i++)
     {
         if (coords[i] > r.coords[i] || coords[i + n] < r.coords[i + n])
         {
             return(false);
         }
     }
     return(true);
 }
コード例 #5
0
        /// <summary>
        /// Area of covered rectangle for two sepcified rectangles
        /// </summary>
        public static double JoinArea(RectangleRn a, RectangleRn b)
        {
            double area = 1.0;

            for (int i = 0, n = a.coords.Length / 2; i < n; i++)
            {
                double min = Math.Min(a.coords[i], b.coords[i]);
                double max = Math.Max(a.coords[n + i], b.coords[n + i]);
                area *= max - min;
            }
            return(area);
        }
コード例 #6
0
            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);
            }
コード例 #7
0
 public void Unpack(ObjectReader reader)
 {
     n = reader.ReadInt32();
     branch = (Link)reader.ReadObject();
     card = branch.Count;
     int nDims = ((Page.pageSize-ObjectHeader.Sizeof-12)/card - 4) / 16;
     double[] coords = new double[nDims*2];
     b = new RectangleRn[card];
     for (int i = 0; i < n; i++) {
         for (int j = 0; j < nDims; j++) {
             coords[j] = reader.ReadDouble();
             coords[j+nDims] = reader.ReadDouble();
         }
         b[i] = new RectangleRn(coords);
     }
 }
コード例 #8
0
 internal RtreeRnPage insert(Storage storage, RectangleRn r, object obj, int level)
 {
     Modify();
     if (--level != 0)
     {
         // not leaf page
         int i, mini = 0;
         double minIncr = Double.MaxValue;
         double minArea = Double.MaxValue;
         for (i = 0; i < n; i++)
         {
             double area = b[i].Area();
             double incr = RectangleRn.JoinArea(b[i], r) - area;
             if (incr < minIncr)
             {
                 minIncr = incr;
                 minArea = area;
                 mini = i;
             }
             else if (incr == minIncr && area < minArea)
             {
                 minArea = area;
                 mini = i;
             }
         }
         RtreeRnPage p = (RtreeRnPage)branch[mini];
         RtreeRnPage q = p.insert(storage, r, obj, level);
         if (q == null)
         {
             // child was not split
             b[mini].Join(r);
             return null;
         }
         else
         {
             // child was split
             setBranch(mini, p.cover(),  p);
             return addBranch(storage, q.cover(), q);
         }
     }
     else
     {
         return addBranch(storage, new RectangleRn(r), obj);
     }
 }
コード例 #9
0
            public RectangleRn WrappingRectangle()
            {
                Euler euler = new Euler();

                euler.phi     = phi;
                euler.theta   = theta;
                euler.psi     = psi;
                euler.psi_a   = Euler.AXIS_Z;
                euler.theta_a = Euler.AXIS_X;
                euler.phi_a   = Euler.AXIS_Z;

                if (FP.zero(length))
                {
                    Point3D beg3d = new Point3D();
                    Point3D end3d = new Point3D();
                    euler.transform(beg3d, new Point3D(0.0, 0.0));
                    euler.transform(end3d, new Point3D(length, 0.0));
                    RectangleRn r = beg3d.toRectangle();
                    end3d.addToRectangle(r);
                    return(r);
                }
                else
                {
                    double    l, ls, lc;
                    Point3D[] v  = new Point3D[4];
                    Point3D   tv = new Point3D();
                    l          = length / 2.0;
                    ls         = Math.Sin(l);
                    lc         = Math.Cos(l);
                    euler.phi += l;

                    v[0] = new Point3D(lc, lc < 0 ? -1.0 : -ls, 0.0);
                    v[1] = new Point3D(1.0, lc < 0 ? -1.0 : -ls, 0.0);
                    v[2] = new Point3D(lc, lc < 0 ? +1.0 : +ls, 0.0);
                    v[3] = new Point3D(1.0, lc < 0 ? +1.0 : +ls, 0.0);

                    Point3D min = new Point3D(1.0, 1.0, 1.0);
                    Point3D max = new Point3D(-1.0, -1.0, -1.0);

                    for (int i = 0; i < 4; i++)
                    {
                        euler.transform(tv, v[i]);
                        if (tv.x < -1.0)
                        {
                            min.x = -1.0;
                        }
                        else if (tv.x > 1.0)
                        {
                            max.x = 1.0;
                        }
                        else
                        {
                            if (tv.x < min.x)
                            {
                                min.x = tv.x;
                            }
                            if (tv.x > max.x)
                            {
                                max.x = tv.x;
                            }
                        }

                        if (tv.y < -1.0)
                        {
                            min.y = -1.0;
                        }
                        else if (tv.y > 1.0)
                        {
                            max.y = 1.0;
                        }
                        else
                        {
                            if (tv.y < min.y)
                            {
                                min.y = tv.y;
                            }
                            if (tv.y > max.y)
                            {
                                max.y = tv.y;
                            }
                        }
                        if (tv.z < -1.0)
                        {
                            min.z = -1.0;
                        }
                        else if (tv.z > 1.0)
                        {
                            max.z = 1.0;
                        }
                        else
                        {
                            if (tv.z < min.z)
                            {
                                min.z = tv.z;
                            }
                            if (tv.z > max.z)
                            {
                                max.z = tv.z;
                            }
                        }
                    }
                    return(new RectangleRn(new double[] { min.x, min.y, min.z, max.x, max.y, max.z }));
                }
            }
コード例 #10
0
 internal void addToRectangle(RectangleRn r)
 {
     addToRectangle(r, x, y, z);
 }
コード例 #11
0
 /// <summary>
 /// Create copy of the rectangle
 /// </summary>
 public RectangleRn(RectangleRn r) 
 {
     coords = new double[r.coords.Length];
     Array.Copy(r.coords, 0, coords, 0, coords.Length);
 }
コード例 #12
0
 void setBranch(int i, RectangleRn r, object obj)
 {
     b[i] = r;
     branch[i] = obj;
 }
コード例 #13
0
 /// <summary>
 /// Checks if this rectangle contains the specified rectangle
 /// </summary>
 public bool Contains(RectangleRn r) 
 { 
     for (int i = 0, n = coords.Length/2; i < n; i++) {             
         if (coords[i] > r.coords[i] || coords[i+n] < r.coords[i+n]) { 
             return false;
         }
     }
     return true;
 }
コード例 #14
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;
 }
コード例 #15
0
 /// <summary>
 /// Join two rectangles. This rectangle is updates to contain cover of this and specified rectangle.
 /// </summary>
 /// <param name="r">rectangle to be joined with this rectangle
 /// </param>
 public void Join(RectangleRn r) 
 { 
     for (int i = 0, n = coords.Length/2; i < n; i++) 
     {             
         coords[i] = Math.Min(coords[i], r.coords[i]);
         coords[i+n] = Math.Max(coords[i+n], r.coords[i+n]);
     }
 }
コード例 #16
0
 internal void find(RectangleRn r, ArrayList result, int level)
 {
     if (--level != 0)
     { /* this is an internal node in the tree */
         for (int i = 0; i < n; i++)
         {
             if (r.Intersects(b[i]))
             {
                 ((RtreeRnPage)branch[i]).find(r, result, level);
             }
         }
     }
     else
     { /* this is a leaf node */
         for (int i = 0; i < n; i++)
         {
             if (r.Intersects(b[i]))
             {
                 result.Add(branch[i]);
             }
         }
     }
 }
コード例 #17
0
 internal static void addToRectangle(RectangleRn r, double ra, double dec) { 
     double x = Math.Cos(ra)*Math.Cos(dec);
     double y = Math.Sin(ra)*Math.Cos(dec);
     double z = Math.Sin(dec);
     addToRectangle(r, x, y, z);
 }
コード例 #18
0
 RtreeRnPage addBranch(Storage storage, RectangleRn r, object obj)
 {
     if (n < card)
     {
         setBranch(n++, r, obj);
         return null;
     }
     else
     {
         return splitPage(storage, r, obj);
     }
 }
コード例 #19
0
        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;
        }
コード例 #20
0
 internal RectangleRn cover()
 {
     RectangleRn r = new RectangleRn(b[0]);
     for (int i = 1; i < n; i++)
     {
         r.Join(b[i]);
     }
     return r;
 }
コード例 #21
0
 internal void addToRectangle(RectangleRn r) { 
     addToRectangle(r, x, y, z);
 }
コード例 #22
0
 /// <summary>
 /// Create copy of the rectangle
 /// </summary>
 public RectangleRn(RectangleRn r)
 {
     coords = new double[r.coords.Length];
     Array.Copy(r.coords, 0, coords, 0, coords.Length);
 }
コード例 #23
0
 internal static void addToRectangle(RectangleRn r, double x, double y, double z) { 
     if (x < r.coords[0]) { 
         r.coords[0] = x;
     }
     if (y < r.coords[1]) { 
         r.coords[1] = y;
     }
     if (z < r.coords[2]) { 
         r.coords[2] = z;
     }
     if (x > r.coords[3]) { 
         r.coords[3] = x;
     }
     if (y > r.coords[4]) { 
         r.coords[4] = y;
     }
     if (z > r.coords[5]) { 
         r.coords[5] = z;
     }
 }       
コード例 #24
0
 internal int remove(RectangleRn r, object obj, int level, ArrayList reinsertList)
 {
     if (--level != 0)
     {
         for (int i = 0; i < n; i++)
         {
             if (r.Intersects(b[i]))
             {
                 RtreeRnPage pg = (RtreeRnPage)branch[i];
                 int reinsertLevel = pg.remove(r, obj, level, reinsertList);
                 if (reinsertLevel >= 0)
                 {
                     if (pg.n >= card/2)
                     {
                         setBranch(i, pg.cover(), pg);
                         Modify();
                     }
                     else
                     {
                         // not enough entries in child
                         reinsertList.Add(pg);
                         reinsertLevel = level - 1;
                         removeBranch(i);
                     }
                     return reinsertLevel;
                 }
             }
         }
     }
     else
     {
         for (int i = 0; i < n; i++)
         {
             if (branch.ContainsElement(i, obj))
             {
                 removeBranch(i);
                 return 0;
             }
         }
     }
     return -1;
 }