public static TRow Row(TAxis axis, int sub_cube_i) { switch (axis) { case TAxis.x: return((TRow)(sub_cube_i % 3)); case TAxis.y: return((TRow)((sub_cube_i % 9) / 3)); case TAxis.z: return((TRow)(sub_cube_i / 9)); } return(TRow.mid); }
private TAxis chooseSplitAxis(int nodeFather, int nodeChild) { //Console.WriteLine("chooseSplitAxis work"); int[] arr_node; int i, j, k, idx; TRNode node_1, node_2; double perimetr, perimetr_min; TAxis result = new TAxis(); arr_node = new int[MAX_M + 1]; for (i = 0; i < FNodeArr[nodeFather].FChildren.Length; i++) { arr_node[i] = FNodeArr[nodeFather].FChildren[i]; } arr_node[arr_node.Length - 1] = nodeChild; perimetr_min = double.MaxValue; node_1 = new TRNode(); node_2 = new TRNode(); for (i = 0; i <= 1; i++) { perimetr = 0; for (j = 0; j <= 1; j++) { node_1.clearChildren(); node_2.clearChildren(); QuickSort(arr_node, 0, arr_node.Length - 1, (TAxis)i, (TBound)j); for (k = 1; k <= MAX_M - MIN_M * 2 + 2; k++) { idx = 0; while (idx < ((MIN_M - 1) + k)) { node_1.setChild(idx, arr_node[idx]); idx++; } for (; idx < arr_node.Length; idx++) { node_2.setChild(idx - ((MIN_M - 1) + k), arr_node[idx]); } updateMBR(node_1); updateMBR(node_2); perimetr = perimetr + node_1.margin() + node_2.margin(); } } if (perimetr <= perimetr_min) { result = (TAxis)i; perimetr_min = perimetr; } perimetr = 0; } node_1 = null; node_2 = null; arr_node = new int[0]; return(result); }
/// <summary> /// TAXis /// </summary> /// <param name="obj"></param> /// <param name="node_id"></param> /// <returns></returns> #region private TAxis chooseSplitAxis(MyLib.Point obj, int node_id) { //Console.WriteLine("chooseSplitAxis1 work"); MyLib.Point[] arr_obj; int i, j, k, idx; TRNode node_1, node_2; double perimetr_min, perimetr; TAxis result = new TAxis(); arr_obj = new MyLib.Point[MAX_M + 1]; if (!FNodeArr[node_id].isLeaf) { return(0); } for (i = 0; i < FNodeArr[node_id].FObject.Length; i++) { arr_obj[i] = FNodeArr[node_id].FObject[i]; } arr_obj[arr_obj.Length - 1] = obj; node_1 = new TRNode(); node_2 = new TRNode(); perimetr_min = double.MaxValue; for (i = 0; i <= 1; i++) { perimetr = 0; for (j = 0; j <= 1; j++) { node_1.clearObjects(); node_2.clearObjects(); QuickSort(arr_obj, 0, arr_obj.Length - 1, (TAxis)i); for (k = 1; k <= MAX_M - MIN_M * 2 + 2; k++) // высчитваем периметры { idx = 0; while (idx < ((MIN_M - 1) + k)) { node_1.setObject(idx, arr_obj[idx]); idx++; } for (; idx < arr_obj.Length; idx++) { node_2.setObject(idx - ((MIN_M - 1) + k), arr_obj[idx]); } updateMBR(node_1); updateMBR(node_2); perimetr = perimetr + ((node_1.mbr.Right.X - node_1.mbr.Left.X) * 2 + (node_2.mbr.Left.Y - node_2.mbr.Right.Y) * 2); } } if (perimetr <= perimetr_min) { result = (TAxis)i; perimetr_min = perimetr; } } return(result); }
private int FHeight; // высота дерева /// <summary> /// Бытсрая сортировка массива точек по заданной оси /// </summary> /// <param name="a">Массив точек</param> /// <param name="l">Левая граница</param> /// <param name="r">Правая граница</param> /// <param name="axe">Ось по которой происходит сортировка</param> static void QuickSort(MyLib.Point[] a, int l, int r, TAxis axe) { MyLib.Point temp; double mid = 0; switch (axe) { case TAxis.X: mid = a[l + (r - l) / 2].x; break; case TAxis.Y: mid = a[l + (r - l) / 2].y; break; } //запись эквивалентна (l+r)/2, //но не вызввает переполнения на больших данных int i = l; int j = r; //код в while обычно выносят в процедуру particle while (i <= j) { switch (axe) { case TAxis.X: { while (a[i].x < mid) { i++; } while (a[j].x > mid) { j--; } } break; case TAxis.Y: { while (a[i].y < mid) { i++; } while (a[j].y > mid) { j--; } } break; } if (i <= j) { temp = a[i]; a[i] = a[j]; a[j] = temp; i++; j--; } } if (i < r) { QuickSort(a, i, r, axe); } if (l < j) { QuickSort(a, l, j, axe); } }
/// <summary> /// быстрая сортировка для узлов по их MBR. axe - ось по которой происходит сортировка, bound - граница по которой происходит сортировка (левая/правая) /// </summary> /// <param name="List"></param> /// <param name="iLo"></param> /// <param name="iHi"></param> /// <param name="axe"></param> /// <param name="bound"></param> #region private void QuickSort(int[] List, int iLo, int iHi, TAxis axe, TBound bound) { //Console.WriteLine("QuickSort2 work"); int Lo = iLo, Hi = iHi; int T; double Mid = 0.0; switch (bound) { case TBound.Left: { switch (axe) { case TAxis.X: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Left.X; break; case TAxis.Y: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Left.Y; break; } } break; case TBound.Right: { switch (axe) { case TAxis.X: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Right.X; break; case TAxis.Y: Mid = FNodeArr[List[(Lo + Hi) / 2]].mbr.Right.Y; break; } } break; } do { switch (bound) { case TBound.Left: { switch (axe) { case TAxis.X: { while (FNodeArr[List[Lo]].mbr.Left.X < Mid) { Lo++; } while (FNodeArr[List[Hi]].mbr.Left.X > Mid) { Hi--; } } break; case TAxis.Y: { while (FNodeArr[List[Lo]].mbr.Left.Y < Mid) { Lo++; } while (FNodeArr[List[Hi]].mbr.Left.Y > Mid) { Hi--; } } break; } } break; case TBound.Right: { switch (axe) { case TAxis.X: { while (FNodeArr[List[Lo]].mbr.Right.X < Mid) { Lo++; } while (FNodeArr[List[Hi]].mbr.Right.X > Mid) { Hi--; } } break; case TAxis.Y: { while (FNodeArr[List[Lo]].mbr.Right.Y < Mid) { Lo++; } while (FNodeArr[List[Hi]].mbr.Right.Y > Mid) { Hi--; } } break; } } break; } if (Lo <= Hi) { T = List[Lo]; List[Lo] = List[Hi]; List[Hi] = T; Lo++; Hi--; } } while (Lo <= Hi); if (Hi > iLo) { QuickSort(List, iLo, Hi, axe, bound); } if (Lo < iHi) { QuickSort(List, Lo, iHi, axe, bound); } }