MP5
Photomosaic

KDTree class: implemented using Points in Dim dimensional space (given by the template parameter). More...
#include "kdtree.h"
Classes  
struct  KDTreeNode 
Internal structure for a node of KDTree. More...  
Public Member Functions  
bool  smallerDimVal (const Point< Dim > &first, const Point< Dim > &second, int curDim) const 
Determines if Point a is smaller than Point b in a given dimension d. More...  
bool  shouldReplace (const Point< Dim > &target, const Point< Dim > ¤tBest, const Point< Dim > &potential) const 
Determines if a Point is closer to the target Point than another reference Point. More...  
KDTree (const vector< Point< Dim >> &newPoints)  
Constructs a KDTree from a vector of Points, each having dimension Dim. More...  
KDTree (const KDTree &other)  
Copy constructor for KDTree. More...  
KDTree const &  operator= (const KDTree &rhs) 
Assignment operator for KDTree. More...  
~KDTree ()  
Destructor for KDTree. More...  
Point< Dim >  findNearestNeighbor (const Point< Dim > &query) const 
Finds the closest point to the parameter point in the KDTree. More...  
void  printTree (ostream &out=cout, colored_out::enable_t enable_bold=colored_out::COUT, int modWidth=1) const 
You do not need to modify this function. More...  
Private Member Functions  
int  getPrintData (KDTreeNode *subroot) const 
Helper function for grading. More...  
void  printTree (KDTreeNode *subroot, std::vector< std::string > &output, int left, int top, int width, int currd) const 
Helper function for grading. More...  
Private Attributes  
KDTreeNode *  root 
Internal representation, root and size. More...  
KDTree class: implemented using Points in Dim dimensional space (given by the template parameter).
Constructs a KDTree from a vector of Points, each having dimension Dim.
You need to handle the case that the vector has no Point in it. It should build the tree using recursive helper functions.
Since we know the size of the KDTree at construction, we can represent the tree as a linear structure and building the tree nodes based off this structure efficiently. For testing, we require the following:
KDtrees are created recursively; at any stage of the construction, the median value in the current dimension is selected and a node is created based on it. Then, all the elements in the current subtree are divided up into elements which are less than the median, or greater than the median, and then the subtrees are created recursively. The children pick the median in the next dimension, and repeat until the entire set of inputs has been processed. Successive levels of the tree split on increasing dimensions, modulo the total number: a 3D tree will have levels split by dimension 0, 1, 2, 0, 1, 2, etc.
You will probably want to write a helper function which performs the median selection and partitioning. Maybe you can use a function you already wrote...
newPoints  The vector of points to build your KDTree off of. 
bool KDTree< Dim >::smallerDimVal  (  const Point< Dim > &  first, 
const Point< Dim > &  second,  
int  curDim  
)  const 
Determines if Point a is smaller than Point b in a given dimension d.
If there is a tie, break it with Point::operator<().
For example:
Point<3> a(1, 2, 3); Point<3> b(3, 2, 1); cout << smallerDimVal(a, b, 0) << endl; // should print true cout << smallerDimVal(a, b, 2) << endl; // should print false cout << smallerDimVal(a, b, 1) << endl; // based on operator<, this should be true
first  Point to compare. 
second  Second point to compare. 
curDim  Dimension these points are being compared in. 
bool KDTree< Dim >::shouldReplace  (  const Point< Dim > &  target, 
const Point< Dim > &  currentBest,  
const Point< Dim > &  potential  
)  const 
Determines if a Point is closer to the target Point than another reference Point.
Takes three points: target, currentBest, and potential, and returns whether or not potential is closer to target than currentBest.
We are using Euclidean distance to compare kdimensional points: \(\sqrt{(p_1q_1)^2+(p_2q_2)^2+\ldots+(p_nq_n)^2} = \sqrt{\sum_{i=1}^n (p_iq_i)^2}\). Note, however, that minimizing distance is the same as minimizing squared distance, so you can avoid invoking the square root and just compare squared distances in your code.
For example:
Point<3> target(1, 3, 5); Point<3> currentBest1(1, 3, 2); Point<3> possibleBest1(2, 4, 4); Point<3> currentBest2(1, 3, 6); Point<3> possibleBest2(2, 4, 4); Point<3> currentBest3(0, 2, 4); Point<3> possibleBest3(2, 4, 6); cout << shouldReplace(target, currentBest1, possibleBest1) << endl; // true cout << shouldReplace(target, currentBest2, possibleBest2) << endl; // false cout << shouldReplace(target, currentBest3, possibleBest3) << endl; // based on operator<, this should be false
target  The Point we want to be close to. 
currentBest  The Point that is currently our closest Point to target. 
potential  Our Point that is a candidate to replace currentBest (that is, it may be closer to target than currentBest). 
Point< Dim > KDTree< Dim >::findNearestNeighbor  (  const Point< Dim > &  query  )  const 
Finds the closest point to the parameter point in the KDTree.
This function takes a reference to a template parameter Point and returns the Point closest to it in the tree. We are defining closest here to be the minimum Euclidean distance between elements. Again, if there are ties (this time in distance), they must be decided using Point::operator<(). Recall that an HSLAPixel is defined by three components: hue, saturation, and luminance.
The findNearestNeighbor() search is done in two steps: a search to find the smallest hyperrectangle that contains the target element, and then a back traversal to see if any other hyperrectangle could contain a closer point, which may be a point with smaller distance or a point with equal distance, but a "smaller" point (as defined by operator< in the point class). In the first step, you must recursively traverse down the tree, at each level choosing the subtree which represents the region containing the search element (another place to save some duplicate code?). When you reach the lowest bounding hyperrectangle, then the corresponding node is effectively the "current best" neighbor.
However, it may be the case that a better match exists outside of the containing hyperrectangle. At then end of first step of the search, we start traversing back up the kdtree to the parent node. The current best distance defines a radius which contains the nearest neighbor. During the backtraversal (i.e., stepping out of the recursive calls), you must first check if the distance to the parent node is less than the current radius. If so, then that distance now defines the radius, and we replace the "current best" match. Next, it is necessary to check to see if the current splitting plane's distance from search node is within the current radius. If so, then the opposite subtree could contain a closer node, and must also be searched recursively.
During the backtraversal, it is important to only check the subtrees that are within the current radius, or else the efficiency of the kdtree is lost. If the distance from the search node to the splitting plane is greater than the current radius, then there cannot possibly be a better nearest neighbor in the subtree, so the subtree can be skipped entirely.
You can assume that findNearestNeighbor will only be called on a valid kdtree.
query  The point we wish to find the closest neighbor to in the tree. 
void KDTree< Dim >::printTree  (  ostream &  out = cout , 
colored_out::enable_t  enable_bold = colored_out::COUT , 

int  modWidth = 1 

)  const 
You do not need to modify this function.
Its implementation is in kdtree_extras.cpp. Prints the KDTree to the terminal in a pretty way.

private 
Helper function for grading.

private 
Helper function for grading.

private 
Internal representation, root and size.