Beispiel #1
0
        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]);
                }
            }
        }