예제 #1
0
        /// <summary>
        /// Creates a new 2-dimensional k-d tree.
        /// </summary>
        /// <param name="points"></param>
        /// <param name="distance_delegate"></param>
        public Tree2D(IEnumerable <PointType> points,
                      Distance distance_delegate)
        {
            // set the distance delegate.
            _distance_delegate = distance_delegate;

            // create the list.
            List <PointType>[] sorted_points = new List <PointType> [2];

            // sort points per dimension.
            for (int dim = 0; dim < 2; dim++)
            {
                // create the points list.
                List <PointType> points_list = new List <PointType>(points);

                // sort the list.
                points_list.Sort(new Comparison <PointType>(delegate(PointType p1, PointType p2)
                {
                    return(p1[dim].CompareTo(p2[dim]));
                }));

                // add the list to the array.
                sorted_points[dim] = points_list;
            }

            // construct the root.
            _root = new Tree2DNode <PointType>(_distance_delegate, sorted_points, 0);
        }
예제 #2
0
        /// <summary>
        /// Adds a point to the tree.
        /// </summary>
        /// <param name="value"></param>
        public void Add(PointType value)
        {
            double value_dimension = value[_dimension];

            if (value_dimension < _value[_dimension])
            { // add to the lesser side.
                if (_lesser == null)
                {
                    _lesser = new Tree2DNode <PointType>(_distance_delegate, value, _dimension + 1 % 2);
                }
                else
                {
                    _lesser.Add(value);
                }
            }
            else
            { // add to the bigger side.
                if (_bigger == null)
                {
                    _bigger = new Tree2DNode <PointType>(_distance_delegate, value, _dimension + 1 % 2);
                }
                else
                {
                    _bigger.Add(value);
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Creates a 2D tree in a balanced way.
        /// </summary>
        /// <param name="distance_delegate"></param>
        /// <param name="sorted_points"></param>
        /// <param name="dimension"></param>
        public Tree2DNode(Tree2D <PointType> .Distance distance_delegate, List <PointType>[] sorted_points, int dimension)
        {
            // set the distance delegate.
            _distance_delegate = distance_delegate;

            // set the dimension.
            _dimension = dimension;

            // get the sorted list in question.
            List <PointType> points = sorted_points[_dimension];

            // get the middle point.
            int middle = points.Count / 2;

            // create this point.
            _value = points[middle];

            // split the list.
            List <PointType>[] lesser_points = new List <PointType> [2];
            List <PointType>[] bigger_points = new List <PointType> [2];
            lesser_points[_dimension] = new List <PointType>(points.GetRange(
                                                                 0, middle - 1));
            bigger_points[_dimension] = new List <PointType>(points.GetRange(
                                                                 middle + 1, points.Count - (middle + 1)));

            // calculate the other dimension.
            int other_dimension =
                (_dimension + 1) % 2;

            // remove the points from the other dimension lists.
            lesser_points[other_dimension] = new List <PointType>(
                sorted_points[other_dimension].Except <PointType>(bigger_points[_dimension]));
            lesser_points[other_dimension].Remove(_value);
            bigger_points[other_dimension] = new List <PointType>(
                sorted_points[other_dimension].Except <PointType>(lesser_points[_dimension]));
            bigger_points[other_dimension].Remove(_value);

            // create the other nodes.
            if (lesser_points[other_dimension].Count == 1)
            {
                _lesser = new Tree2DNode <PointType>(_distance_delegate,
                                                     lesser_points[other_dimension][0], other_dimension);
            }
            else if (lesser_points[other_dimension].Count > 1)
            {
                _lesser = new Tree2DNode <PointType>(_distance_delegate,
                                                     lesser_points, other_dimension);
            }
            if (bigger_points[other_dimension].Count == 1)
            {
                _bigger = new Tree2DNode <PointType>(_distance_delegate,
                                                     bigger_points[other_dimension][0], other_dimension);
            }
            else if (bigger_points[other_dimension].Count > 1)
            {
                _bigger = new Tree2DNode <PointType>(_distance_delegate,
                                                     bigger_points, other_dimension);
            }
        }
예제 #4
0
        public Tree2D(IEnumerable <PointType> points, Tree2D <PointType> .Distance distance_delegate)
        {
            this._distance_delegate = distance_delegate;
            List <PointType>[] sorted_points = new List <PointType> [2];
            int num;

            for (int dim = 0; dim < 2; dim = num + 1)
            {
                List <PointType> pointTypeList = new List <PointType>(points);
                pointTypeList.Sort((Comparison <PointType>)((p1, p2) => p1[dim].CompareTo(p2[dim])));
                sorted_points[dim] = pointTypeList;
                num = dim;
            }
            this._root = new Tree2DNode <PointType>(this._distance_delegate, sorted_points, 0);
        }
예제 #5
0
 public void Add(PointType value)
 {
     if (value[this._dimension] < this._value[this._dimension])
     {
         if (this._lesser == null)
         {
             this._lesser = new Tree2DNode <PointType>(this._distance_delegate, value, this._dimension + 1);
         }
         else
         {
             this._lesser.Add(value);
         }
     }
     else if (this._bigger == null)
     {
         this._bigger = new Tree2DNode <PointType>(this._distance_delegate, value, this._dimension + 1);
     }
     else
     {
         this._bigger.Add(value);
     }
 }
예제 #6
0
        public Tree2DNode(Tree2D <PointType> .Distance distance_delegate, List <PointType>[] sorted_points, int dimension)
        {
            this._distance_delegate = distance_delegate;
            this._dimension         = dimension;
            List <PointType> sortedPoint = sorted_points[this._dimension];
            int index = sortedPoint.Count / 2;

            this._value = sortedPoint[index];
            List <PointType>[] sorted_points1 = new List <PointType> [2];
            List <PointType>[] sorted_points2 = new List <PointType> [2];
            sorted_points1[this._dimension] = new List <PointType>((IEnumerable <PointType>)sortedPoint.GetRange(0, index - 1));
            sorted_points2[this._dimension] = new List <PointType>((IEnumerable <PointType>)sortedPoint.GetRange(index + 1, sortedPoint.Count - (index + 1)));
            int dimension1 = (this._dimension + 1) % 2;

            sorted_points1[dimension1] = new List <PointType>(sorted_points[dimension1].Except <PointType>((IEnumerable <PointType>)sorted_points2[this._dimension]));
            sorted_points1[dimension1].Remove(this._value);
            sorted_points2[dimension1] = new List <PointType>(sorted_points[dimension1].Except <PointType>((IEnumerable <PointType>)sorted_points1[this._dimension]));
            sorted_points2[dimension1].Remove(this._value);
            if (sorted_points1[dimension1].Count == 1)
            {
                this._lesser = new Tree2DNode <PointType>(this._distance_delegate, sorted_points1[dimension1][0], dimension1);
            }
            else if (sorted_points1[dimension1].Count > 1)
            {
                this._lesser = new Tree2DNode <PointType>(this._distance_delegate, sorted_points1, dimension1);
            }
            if (sorted_points2[dimension1].Count == 1)
            {
                this._bigger = new Tree2DNode <PointType>(this._distance_delegate, sorted_points2[dimension1][0], dimension1);
            }
            else
            {
                if (sorted_points2[dimension1].Count <= 1)
                {
                    return;
                }
                this._bigger = new Tree2DNode <PointType>(this._distance_delegate, sorted_points2, dimension1);
            }
        }