/// <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); }
/// <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); } } }
/// <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); } }
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); }
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); } }
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); } }