예제 #1
0
        public void VerifyRec(int i0, int Len, BoundingBoxCode cd, int idx)
        {
            TreeNode[] tree = InitTree();

            TreeNode nt = tree[idx];

            for (int n = 0; n < Codes.Length; n++)
            {
                bool innen  = cd.IsInside(this.Codes[n]);
                bool innen2 = n >= i0 && n < (i0 + Len);
                if (innen != innen2)
                {
                    throw new ApplicationException();
                }
            }


            if (nt.Left >= 0)
            {
                int i0L  = i0;
                int LenL = nt.iMid - i0L;
                VerifyRec(i0L, LenL, cd.GetSubBox(false), nt.Left);
            }
            if (nt.Right >= 0)
            {
                int i0R  = nt.iMid;
                int LenR = i0 + Len - i0R;
                VerifyRec(i0R, LenR, cd.GetSubBox(true), nt.Right);
            }
        }
예제 #2
0
 /// <summary>
 /// true, if the box notated by <paramref name="code"/> is fully contained in this box
 /// </summary>
 public bool IsInside(BoundingBoxCode code)
 {
     if (code.SignificantBits < this.SignificantBits)
     {
         return(false);
     }
     return(IsInside(code.Branch));
 }
예제 #3
0
        /// <summary>
        /// computes the leave bounding-box of a geometric binary tree
        /// </summary>
        /// <param name="subBB">
        /// on exit, the bounding box associated with the branch code <paramref name="bbCode"/>;
        /// The output is not returned (via return value) to avoid heap allocation.
        /// </param>
        /// <param name="bbCode">
        /// bounding box code
        /// </param>
        public void SubBoxFromCode(BoundingBox subBB, BoundingBoxCode bbCode)
        {
            if (subBB.D != this.D)
            {
                throw new ArgumentException("must have the same dimension as this bounding box.", "subBB");
            }
            int  _D        = D;
            uint TreeDepth = bbCode.SignificantBits;

            if (TreeDepth > 32)
            {
                throw new ArgumentException("tree Depth is limited to 32.");
            }

            Array.Copy(this.Max, subBB.Max, _D);
            Array.Copy(this.Min, subBB.Min, _D);

            uint cd  = bbCode.Branch.Code;
            uint mxx = 0x80000000;
            //for (int i = 0; i < 30; i++)
            //    mxx *= 2;

            int cur_d = 0;

            for (int i = (int)TreeDepth - 1; i >= 0; i--)
            {
                double mean = (subBB.Min[cur_d] + subBB.Max[cur_d]) * 0.5;

                // split bb;
                //uint kaes = cd / mxx;
                //switch (kaes) {
                //    case 0: subBB.Max[cur_d] = mean; break;
                //    case 1: subBB.Min[cur_d] = mean; break;
                //    default: throw new ApplicationException("error in algorithm");
                //}
                if ((cd & mxx) != 0)
                {
                    subBB.Min[cur_d] = mean;
                }
                else
                {
                    subBB.Max[cur_d] = mean;
                }

                // increment
                mxx = mxx >> 1;
                //mxx = Math.Max(1, mxx / 2);
                //cd = cd % mxx;
                cur_d++;
                if (cur_d >= _D)
                {
                    cur_d = 0;
                }
            }
        }
예제 #4
0
 public void Test(int i0, int iMid, PointLocalization owner, BoundingBoxCode b)
 {
     for (int i = 0; i < owner.Codes.Length; i++)
     {
         bool innen  = b.IsInside(owner.Codes[i]);
         bool innen2 = i >= i0 && i < iMid;
         if (innen != innen2)
         {
             throw new ApplicationException();
         }
     }
 }
예제 #5
0
        /// <summary>
        /// gets the code of either the 'left' or the 'right' sub-box of this box
        /// </summary>
        /// <param name="leftOrRight">
        /// if false, the 'left' branch, i.e. the box with lower coordinate values;<br/>
        /// if false, the 'right' branch, i.e. the box with higher coordinate values;<br/>
        /// </param>
        /// <returns></returns>
        public BoundingBoxCode GetSubBox(bool leftOrRight)
        {
            if (this.SignificantBits >= 32)
            {
                throw new ApplicationException("maximum tree depth reached.");
            }

            BoundingBoxCode Ret = this;

            Ret.SignificantBits++;
            if (leftOrRight)
            {
                // right branch
                uint upper = 0x80000000 >> ((int)this.SignificantBits);
                Ret.Branch.Code |= upper;
            }
            return(Ret);
        }
예제 #6
0
        void FindNearPointsRecursice(ICollection <int> IndicesIntoPoints, double epsPow2, double[] pt, int i0, int Len, int _D, BoundingBoxCode BoxCode, uint shifti, ref uint MaxDepth, bool forceTst, int treeNodeIdx)
        {
            TreeNode[] tree  = __tree;
            uint       Depth = BoxCode.SignificantBits;

            {
                /*/ test and debug:
                 * VerifyTree l = vt.Get(BoxCode, (int)Depth);
                 * if (l != null) {
                 *  if (l.I0 != i0)
                 *      throw new ApplicationException();
                 *  if (l.Len != Len)
                 *      throw new ApplicationException();
                 * }
                 *
                 * PointsBB.SubBoxFromCode(helper, BoxCode, Depth);
                 * for (int n = 0; n < Codes.Length; n++) {
                 *  double[] _pt = new double[Points.GetLength(1)];
                 *  for (int d = 0; d < pt.Length; d++) _pt[d] = Points[n, d];
                 *
                 *  bool loc = helper.IsInsideStrict(_pt);
                 *
                 *  if (n >= i0 && n < (i0 + Len)) {
                 *      if (!loc)
                 *          throw new ApplicationException("error in alg");
                 *  } else {
                 *      if (loc)
                 *          throw new ApplicationException("error in alg 2");
                 *  }
                 * }
                 * // end */


                if (Len <= 0)
                {
                    // no points in branch => terminate recursion
                    return;
                }

                PointsBB.SubBoxFromCode(helper, BoxCode);
                //helper.ExtendByFactor(0.01);
                double di = helper.Distance(pt);
                if (di * di > epsPow2)
                {
                    //if (helper.IsInside(pt))
                    //    throw new ApplicationException("ohne Worte");


                    //for (int n = i0; n < (i0 + Len); n++) {
                    //    double distPow2 = 0;
                    //    for (int d = _D - 1; d >= 0; d--) {
                    //        double delta = pt[d] - this.Points[n, d];
                    //        distPow2 += delta * delta;
                    //    }

                    //    if (distPow2 <= epsPow2)
                    //        throw new ApplicationException("ohne Worte");
                    //}


                    return; // no interesting points in box => terminate recursion
                }
            }

            MaxDepth = Math.Max(MaxDepth, Depth);

            if (Len <= 2 || Depth == 32 || forceTst)
            {
                // only a few points remaining, or maximum tree depth reached - test all of them

                for (int n = i0; n < (i0 + Len); n++)
                {
                    double distPow2 = 0;
                    for (int d = _D - 1; d >= 0; d--)
                    {
                        double delta = pt[d] - this.Points[n, d];
                        distPow2 += delta * delta;
                    }

                    if (distPow2 <= epsPow2)
                    {
                        IndicesIntoPoints.Add(n);
                    }
                }
            }
            else
            {
                // do recursion;

                BoundingBoxCode BoxB = BoxCode; BoxB.Branch.Code += shifti;
                shifti = shifti >> 1;
                Depth++;
                BoxB.SignificantBits++;
                BoxCode.SignificantBits++;

                int idxMid = tree[treeNodeIdx].iMid;


                int LenLeft = idxMid - i0;
                int LenRigt = Len + i0 - idxMid;

                bool forceLeft = (LenLeft == Len);
                bool forceRigt = (LenRigt == Len);

                FindNearPointsRecursice(IndicesIntoPoints, epsPow2, pt, i0, LenLeft, _D, BoxCode, shifti, ref MaxDepth, forceLeft, tree[treeNodeIdx].Left);
                FindNearPointsRecursice(IndicesIntoPoints, epsPow2, pt, idxMid, LenRigt, _D, BoxB, shifti, ref MaxDepth, forceRigt, tree[treeNodeIdx].Right);
            }
        }
예제 #7
0
        void FindNextPointsRecursice(Vector pt, ref double MinDistSoFarPow2, ref int iMin,
                                     int i0, int Len, int _D, BoundingBoxCode BoxCode, uint shifti, ref uint MaxDepth, bool forceTst, int treeNodeIdx)
        {
            TreeNode[] tree  = __tree;
            uint       Depth = BoxCode.SignificantBits;

            {
                if (Len <= 0)
                {
                    // no points in branch => terminate recursion
                    return;
                }

                var __helper = new BoundingBox(_D);
                PointsBB.SubBoxFromCode(__helper, BoxCode);
                //helper.ExtendByFactor(0.01);
                double di = __helper.Distance(pt);
                if (di * di > MinDistSoFarPow2)
                {
                    return; // no interesting points in box => terminate recursion
                }
            }

            MaxDepth = Math.Max(MaxDepth, Depth);

            if (Len <= 2 || Depth == 32 || forceTst)
            {
                // only a few points remaining, or maximum tree depth reached - test all of them

                for (int n = i0; n < (i0 + Len); n++)
                {
                    double distPow2 = 0;
                    for (int d = _D - 1; d >= 0; d--)
                    {
                        double delta = pt[d] - this.Points[n, d];
                        distPow2 += delta * delta;
                    }

                    if (distPow2 < MinDistSoFarPow2)
                    {
                        MinDistSoFarPow2 = distPow2;
                        iMin             = n;
                    }
                }
            }
            else
            {
                // do recursion;

                BoundingBoxCode BoxB = BoxCode; BoxB.Branch.Code += shifti;
                shifti = shifti >> 1;
                Depth++;
                BoxB.SignificantBits++;
                BoxCode.SignificantBits++;

                int idxMid = tree[treeNodeIdx].iMid;

                int LenLeft = idxMid - i0;
                int LenRigt = Len + i0 - idxMid;

                bool forceLeft = (LenLeft == Len);
                bool forceRigt = (LenRigt == Len);

                FindNextPointsRecursice(pt, ref MinDistSoFarPow2, ref iMin, i0, LenLeft, _D, BoxCode, shifti, ref MaxDepth, forceLeft, tree[treeNodeIdx].Left);
                FindNextPointsRecursice(pt, ref MinDistSoFarPow2, ref iMin, idxMid, LenRigt, _D, BoxB, shifti, ref MaxDepth, forceRigt, tree[treeNodeIdx].Right);
            }
        }