/// <summary> /// Returns the nearest neighbours for the given point. /// </summary> /// <param name="point"></param> /// <returns></returns> public PointType SearchNearestNeighbour(PointType point) { return(_root.SearchNearestNeighbour(point, null)); }
/// <summary> /// Returns the nearest neighbours for the given point. /// </summary> /// <param name="point"></param> /// <param name="exceptions"></param> /// <returns></returns> public PointType SearchNearestNeighbour(PointType point, ICollection <PointType> exceptions) { // keeps the result. PointType result = default(PointType); // decide where to get the result from. double value_dimension = point[_dimension]; bool lesser = true; if (value_dimension < _value[_dimension]) { // get from the lesser side. if (_lesser == null) { if (exceptions == null || !exceptions.Contains(_value)) { result = _value; } } else { result = _lesser.SearchNearestNeighbour(point, exceptions); } } else { // get from the bigger side. lesser = false; if (_bigger == null) { if (exceptions == null || !exceptions.Contains(_value)) { result = _value; } } else { result = _bigger.SearchNearestNeighbour(point, exceptions); } } // do we need to search the other side. double distance = double.MaxValue; if (result != null) { _distance_delegate.Invoke(result, point); } // check if the current point is closer. double distance_this = _distance_delegate.Invoke(_value, point); if (distance > distance_this) { result = _value; distance = distance_this; } // test if the other side needs to be tested. double distance_to_other_side = 0; if (result != null) { System.Math.Abs(result[_dimension] - _value[_dimension]); } if (distance > distance_to_other_side) { PointType other_result = default(PointType); if (lesser) { if (_bigger != null) { other_result = _bigger.SearchNearestNeighbour(point, exceptions); } } else { if (_lesser != null) { other_result = _lesser.SearchNearestNeighbour(point, exceptions); } } if (other_result != null) { double distance_other = _distance_delegate.Invoke(other_result, point); if (distance_other < distance) { result = other_result; } } } return(result); }