public bool RecreateTree(double GrowthFactor, bool ForceSquareLeaves, int GroupLimit) { bool flag; if (this.m_list == null) { flag = false; } else if (this.m_list.Count == 0) { flag = false; } else { if (GroupLimit < 1) { GroupLimit = 1; } double maxValue1 = double.MaxValue; double minValue1 = double.MinValue; double maxValue2 = double.MaxValue; double minValue2 = double.MinValue; if (!this.m_list.BoundingBox(GrowthFactor, ForceSquareLeaves, ref maxValue1, ref minValue1, ref maxValue2, ref minValue2)) { flag = false; } else { this.m_root = new Node2Leaf(maxValue1, minValue1, maxValue2, minValue2); this.m_root.SubDivide(this.m_list, (List <int>)null, GroupLimit); flag = true; } } return(flag); }
/// <summary>Blank constructor</summary> public Node2Leaf() { this.m_A = (Node2Leaf)null; this.m_B = (Node2Leaf)null; this.m_C = (Node2Leaf)null; this.m_D = (Node2Leaf)null; }
private void CreateSubLeafs() { double xMid = this.x_mid; double yMid = this.y_mid; this.m_A = new Node2Leaf(this.m_x0, xMid, this.m_y0, yMid); this.m_B = new Node2Leaf(xMid, this.m_x1, this.m_y0, yMid); this.m_C = new Node2Leaf(xMid, this.m_x1, yMid, this.m_y1); this.m_D = new Node2Leaf(this.m_x0, xMid, yMid, this.m_y1); }
/// <summary>Box constructor. Create an empty leaf with a specific box.</summary> public Node2Leaf(double x0, double x1, double y0, double y1) { this.m_A = (Node2Leaf)null; this.m_B = (Node2Leaf)null; this.m_C = (Node2Leaf)null; this.m_D = (Node2Leaf)null; this.m_x0 = x0; this.m_x1 = x1; this.m_y0 = y0; this.m_y1 = y1; }
private void TrimSubLeafs() { if (this.m_A != null && this.m_A.SubLeafCount == 0 && (this.m_A.Nodes == null || this.m_A.Nodes.Count == 0)) { this.m_A = (Node2Leaf)null; } if (this.m_B != null && this.m_B.SubLeafCount == 0 && (this.m_B.Nodes == null || this.m_B.Nodes.Count == 0)) { this.m_B = (Node2Leaf)null; } if (this.m_C != null && this.m_C.SubLeafCount == 0 && (this.m_C.Nodes == null || this.m_C.Nodes.Count == 0)) { this.m_C = (Node2Leaf)null; } if (this.m_D == null || this.m_D.SubLeafCount != 0 || this.m_D.Nodes != null && this.m_D.Nodes.Count != 0) { return; } this.m_D = (Node2Leaf)null; }
/// <summary>Copy constructor</summary> /// <param name="other">Leaf to mimic</param> public Node2Leaf(Node2Leaf other) { this.m_A = (Node2Leaf)null; this.m_B = (Node2Leaf)null; this.m_C = (Node2Leaf)null; this.m_D = (Node2Leaf)null; if (other == null) { throw new ArgumentNullException(nameof(other)); } this.m_x0 = other.m_x0; this.m_x1 = other.m_x1; this.m_y0 = other.m_y0; this.m_y1 = other.m_y1; if (other.m_nodes != null) { this.m_nodes = new List <int>(); this.m_nodes.AddRange((IEnumerable <int>)other.m_nodes); } if (other.m_A != null) { this.m_A = new Node2Leaf(other.m_A); } if (other.m_B != null) { this.m_B = new Node2Leaf(other.m_B); } if (other.m_C != null) { this.m_C = new Node2Leaf(other.m_C); } if (other.m_D == null) { return; } this.m_D = new Node2Leaf(other.m_D); }
/// <summary>Builds a subtree from a Node list.</summary> /// <param name="nodes">All the nodes that are supposed to be included in this tree.</param> /// <param name="index_subset">A subset of nodes on which to perform the subdivision. Pass a null-pointer to use ALL nodes. /// If the list is not null, used indices will be extracted from the list, in order to reduce the number of pointless inclusion tests.</param> /// <param name="group_limit">The number of allowed Nodes per Leaf. If a Leaf contains more than N nodes, it will subdivide.</param> public void SubDivide(Node2List nodes, List <int> index_subset, int group_limit) { this.m_nodes = new List <int>(nodes.Count); this.m_A = (Node2Leaf)null; this.m_B = (Node2Leaf)null; this.m_C = (Node2Leaf)null; this.m_D = (Node2Leaf)null; if (index_subset == null) { int num = nodes.Count - 1; for (int index = 0; index <= num; ++index) { this.m_nodes.Add(index); } } else { int num1 = index_subset.Count - 1; int index1 = 0; int num2 = num1; for (int index2 = 0; index2 <= num2; ++index2) { int index3 = index_subset[index2]; Node2 node = nodes[index3]; if (node != null) { if (this.Contains(node.x, node.y)) { this.m_nodes.Add(index3); } else { index_subset[index1] = index3; ++index1; } } } if (index1 < index_subset.Count) { if (index1 == 0) { index_subset.Clear(); } else { index_subset.RemoveRange(index1, index_subset.Count - index1); } } } double num3 = (this.m_x1 - this.m_x0) * (this.m_x1 - this.m_x0) + (this.m_y1 - this.m_y0) * (this.m_y1 - this.m_y0); if (this.m_nodes.Count > group_limit && num3 > 1E-08) { this.CreateSubLeafs(); this.m_A.SubDivide(nodes, this.m_nodes, group_limit); this.m_B.SubDivide(nodes, this.m_nodes, group_limit); this.m_C.SubDivide(nodes, this.m_nodes, group_limit); this.m_D.SubDivide(nodes, this.m_nodes, group_limit); this.TrimSubLeafs(); this.m_nodes = (List <int>)null; } else if (this.m_nodes.Count == 0) { this.m_nodes = (List <int>)null; } else { this.m_nodes.TrimExcess(); } }
/// <summary>Recursive method that solves a proximity search.</summary> /// <param name="nodes">Node set to search</param> /// <param name="prox">Proximity object to search with</param> public void SolveProximity(Node2List nodes, Node2Proximity prox) { double d0 = default(double); double d1 = default(double); prox.DistanceRange(ref d0, ref d1); double num1 = this.MinimumDistanceSquared(prox.Start.x, prox.Start.y); if (num1 >= d1 || num1 > prox.MaxSearchRadiusSquared || this.MaximumDistanceSquared(prox.Start.x, prox.Start.y) <= prox.MinSearchRadiusSquared) { return; } if (this.m_nodes == null) { Node2Leaf[] node2LeafArray; if (prox.Start.x < this.x_mid) { if (prox.Start.y < this.y_mid) { node2LeafArray = new Node2Leaf[4] { this.m_A, this.m_B, this.m_D, this.m_C } } ; else { node2LeafArray = new Node2Leaf[4] { this.m_D, this.m_A, this.m_C, this.m_B } }; } else if (prox.Start.y < this.y_mid) { node2LeafArray = new Node2Leaf[4] { this.m_B, this.m_A, this.m_C, this.m_D } } ; else { node2LeafArray = new Node2Leaf[4] { this.m_C, this.m_D, this.m_B, this.m_A } }; int num2 = node2LeafArray.Length - 1; for (int index = 0; index <= num2; ++index) { if (node2LeafArray[index] != null) { node2LeafArray[index].SolveProximity(nodes, prox); } } } else { if (this.m_nodes == null) { return; } int num2 = this.m_nodes.Count - 1; for (int index = 0; index <= num2; ++index) { prox.RegisterNode(nodes[this.m_nodes[index]], this.m_nodes[index]); } } }