/// <summary> /// converts a tree, represented as <see cref="TreeNodeTmp"/> (heap objects) /// into a compact array of value types /// </summary> /// <param name="treeTmp"></param> /// <param name="targ"></param> /// <param name="cnt"></param> public static void CollectInArray(TreeNodeTmp treeTmp, TreeNode[] targ, ref int cnt) { int ithis = cnt; targ[ithis].iMid = treeTmp.iMid; if (treeTmp.Left != null) { cnt++; targ[ithis].Left = cnt; CollectInArray(treeTmp.Left, targ, ref cnt); } else { targ[ithis].Left = int.MinValue; } if (treeTmp.Right != null) { cnt++; targ[ithis].Right = cnt; CollectInArray(treeTmp.Right, targ, ref cnt); } else { targ[ithis].Right = int.MinValue; } }
/// <summary> /// initializes <see cref="__tree"/> on demand /// </summary> private TreeNode[] InitTree() { if (__tree == null) { // construct tree // ============== TreeNodeTmp _tree = new TreeNodeTmp(); //Console.WriteLine("entering tree "); //DateTime startRec = DateTime.Now; _tree.InitRecursive(default(GeomBinTreeBranchCode), 0x80000000, this, 0, Codes.Length, 0); //TimeSpan dt = DateTime.Now - startRec; //Console.WriteLine("tree finished: " + dt.ToString()); __tree = new TreeNode[_tree.NoOfElements()]; int dummy = 0; TreeNode.CollectInArray(_tree, __tree, ref dummy); // test // ==== //vt = new VerifyTree(this); //vt.verify(); //VerifyRec(0, this.Codes.Length, default(BoundingBoxCode),0); } return(__tree); }
/* * static int MyBinarySearch(GeomBinTreeBranchCode[] array, int i0, int Length, GeomBinTreeBranchCode searchValue) { * if(Length <= 0) * return -1; * * if (array[i0] >= searchValue) * return i0; * if (array[i0 + Length - 1] < searchValue) * return i0 + Length; * * if (Length >= 2) { * int ifnd = int.MinValue; * MyBinarySearchRec(array, i0, Length, i0, Length, ref searchValue, out ifnd); * return ifnd; * } else { * if (array[i0] >= searchValue) * return i0; * else * return i0 + 1; * } * } * * static void MyBinarySearchRec(GeomBinTreeBranchCode[] array, int i0, int Length, int _i0, int _Len, ref GeomBinTreeBranchCode searchValue, out int ifnd) { * if( Length < 2) * throw new ApplicationException(); * int iMid = i0 + Length / 2; * * if (array[iMid] >= searchValue && array[iMid - 1] < searchValue) { * ifnd = iMid; * } else { * if (array[iMid] >= searchValue) { * MyBinarySearchRec(array, i0, Length, iMid, i0 + _Len - iMid, ref searchValue, out ifnd); * } else { * MyBinarySearchRec(array, i0, Length, i0, iMid - i0, ref searchValue, out ifnd); * } * * } * * //if( iMid == i0 && array[iMid] >= searchValue && ) { * // return i0; * //} * //if( * }*/ public void InitRecursive(GeomBinTreeBranchCode BoxCode, uint shifti, PointLocalization owner, int i0, int Len, uint RecDepth) { GeomBinTreeBranchCode BoxB = BoxCode; BoxB.Code |= shifti; int __iMid; for (__iMid = i0; __iMid < (i0 + Len); __iMid++) { if (owner.Codes[__iMid].Code >= BoxB.Code) { break; } // if there is a performance problem, this linear search should be exchanged by a binary one } this.iMid = __iMid; //{ // GeomBinTreeBranchCode search = BoxB; // search.Code -= 1; // int iMid2 = MyBinarySearch(owner.Codes, 0, owner.Codes.Length, search); // if (iMid2 != iMid) // throw new ApplicationException(); //} //if (iMid < 0) iMid = ~iMid; int LenLeft = iMid - i0; int LenRigt = Len + i0 - iMid; { /* * // test left * { * BoundingBoxCode cdLeft; * cdLeft.Branch = BoxCode; * cdLeft.SignificantBits = RecDepth + 1; * Test(i0, iMid, owner, cdLeft); * } * * // test right * { * BoundingBoxCode cdRight; * cdRight.Branch = BoxB; * cdRight.SignificantBits = RecDepth + 1; * Test(iMid, i0 + Len, owner, cdRight); * } */ } if (shifti == 1) { return; // reached max. supported tree depth } shifti = shifti >> 1; if (LenLeft > 0) { Left = new TreeNodeTmp(); Left.InitRecursive(BoxCode, shifti, owner, i0, LenLeft, RecDepth + 1); } if (LenRigt > 0) { Right = new TreeNodeTmp(); Right.InitRecursive(BoxB, shifti, owner, iMid, LenRigt, RecDepth + 1); } }