/// <summary> /// Recursive search for neighbours. /// </summary> /// <param name="query">center of the search</param> /// <param name="node">current checked node</param> /// <param name="depth">current recursion depth</param> /// <param name="neighbours">KDTreeNeighbours-object, collecting results of nm-search</param> private void NMSearch(Point query, KDTreeNode node, int depth, NeigbourCollector neighbours) { // The NM-search does only look for potential neighbours. The // final decision if this node is to be returned or not will // be done by the KDTreeNeighbours-object // If there is no node, return. if (node == null) { return; } // If the node is a leaf, it will always be added to the neighbours-list if (node.IsLeaf()) { neighbours.AddNeighbour(node.Point); return; } // locked to 3 axis int axis = depth % 3; // One subtree usually lies closer to the query point along the currently // viewed axis. This one is the close-tree. The other one is the far-tree. KDTreeNode farSubTree, closeSubTree; if (query[axis] < node.Point[axis]) { farSubTree = node.Right; closeSubTree = node.Left; } else { farSubTree = node.Left; closeSubTree = node.Right; } // Search the close-tree first NMSearch(query, closeSubTree, depth + 1, neighbours); // Since the current point was not sortet out by the // previous recursion level, it needs to be added to // the neighbour list. neighbours.AddNeighbour(node.Point); // If the current 'boundary' lies closer to the query // point than the farest approved neighbour so far, // the other side of the boundary also needs to be // searched. if (System.Math.Pow(node.Point[axis] - query[axis], 2) < neighbours.LargestSquareDistance) { NMSearch(query, farSubTree, depth + 1, neighbours); } return; }
//DOKU private void TraverseSearch(Point query, OctreeBox node, NeigbourCollector neighbours) { if (node.IsLeaf) { foreach (Point p in node.Points) { neighbours.AddNeighbour(p); } return; } // not leaf foreach (OctreeBox subNode in node.SubBoxes) { double curMinSDist = subNode.MinimumSquareDistanceTo(query); //TODO that shit about the Neighbourlist count // is really, really crappy! if (neighbours.BestNeighbours.Count > 0 && curMinSDist > neighbours.LargestSquareDistance) { continue; } TraverseSearch(query, subNode, neighbours); } return; }