Building a quadtree

In this assignment you will build (and visualize) a quadtree for a a point cloud. The point cloud is in 3D, so technically one could build an octree. In this assignment you will ignore the z-coordinates and build a quadtree on the (x,y)-coordinates of the points. Your code will consist of three parts:
  1. Read the points from a LiDAR ASCII text form *.txt file into an array in memory.
  2. Build a quadtree.
  3. Visualize it.

User interface

Your code should take on the command line the name of the .txt file that contains the LiDAR data, and the number of points in a quadtree leaf. For example:
./mylastoqdt  house.txt 10 
This will read the points from file house.txt and build a quadtree with at most 10 points per leaf.

Reading the LiDAR data in ASCII format

You will read the LiDAR points from a LiDAR ASCII file. You can generate LiDAR ASCII files as follows:
  1. Download your favorite LiDAR data. The standard format for LiDAR data is .las or .laz. LiDAR data will come as *.las or *.laz files.
  2. Use LAStools free module las2txt to convert a .las or .laz file to ASCII form. You can read detailed documentation about las2txt in LAStools folder, LAStools/bin/las2txt_README.txt
For example I ran las2txt on the las file called house.laz from the data directory in LAStools:
./las2txt -i ../data/house.laz  -o house.txt -sep comma -parse xyzc -header percent
Here: This generated a file house.txt that looks like this:
% file signature:            'LASF'
% file source ID:            0
% reserved (global encoding):0
% project ID GUID data 1-4:  0 0 0 ''
% version major.minor:       1.2
% system_identifier:         'LAStools (c) by Martin Isenburg'
% generating_software:       'las2las (version 130506)'
% file creation day/year:    151/2012
% header size                227
% offset to point data       321
% number var. length records 1
% point data format          1
% point data record length   28
% number of point records    57084
% number of points by return 37047 12918 5615 1299 191
% scale factor x y z         0.01 0.01 0.01
% offset x y z               0 0 0
% min x y z                  309227.00 6143455.00 451.40
% max x y z                  309268.99 6143496.99 471.39
309227.13,6143496.73,466.79,5
309227.12,6143496.59,466.74,5
309227.09,6143496.45,466.63,5
309227.09,6143496.24,466.87,5
309227.10,6143496.04,467.09,5
309227.08,6143495.90,467.04,5
309227.05,6143495.78,466.83,5
309227.03,6143495.61,466.87,5
309227.50,6143496.75,466.83,5
309227.49,6143496.59,466.84,5
309227.48,6143496.41,467.00,5
309227.47,6143496.24,467.03,5
309227.47,6143496.04,467.23,5
309227.42,6143495.97,466.81,5
309227.41,6143495.80,466.86,5
309227.39,6143495.64,466.84,5
309227.35,6143495.77,466.24,5
309227.37,6143495.51,466.73,5
...

Building the quadtree

I placed some startup code as the usual place here: First you will need to define a data structure to encode a quadtree such as below --- feel free to change as needed.

//forward declaration necessary for recursive definition of treeNode
typedef struct _treeNode treeNode;

struct _treeNode {
     int k;    //how many points in this quadrant 
     point3D* p; /* If this is a leaf node,  p represents the array of
                    points that are stored in this leaf.
                    For an internal node p is NULL
                */
     treeNode  *ne, *nw, *se, *sw; /* children. */
}


typedef struct _quadtree{

   treeNode* root; 

   int count; //number of nodes  in the tree

   int height; //height of tree
   //add any other useful info you can think of  
} quadtree; 

Write helper function such that: a function that prints some basic info about the quadtree, such as number of nodes, and height. Call this function in the main functin so that we can see its output.

 void quadtree_printinfo(quadtree* t); 
The main function that you will write is building a quadtree from a set of points. The function takes as input the set of points and returns the quadtree.
/* Build a quadtree for the set of n points, where each leaf cell
   contains  at most k points. 
   Return a pointer to the root.
*/
treeNode*  quadtree_build(point2D* points, int n)
Note that the function returns a treeNode and not a Quadtree. This is because it is recursive. You will probably have a wrapper that takes the root of the quadtree and puts it into a Quadtree structure.

Testing: What test data will you run your code on? If you run it first on house.txt containing 57,084 points, you haven't learnt enough.

To test your quadtree, I would start by generating some small test files. For small number of points you'll want to start by printing the entire tree. Once your code works for small n, you'll probably want to switch to just printing the info of the quadtree (number of nodes and height).


Rendering the quadtree

Write a function that renders the quadtree in OpenGL. The OpenGL part is pretty easy --- basically traverse the tree for e.g. in pre-order and at each internal node, draw the cross; and at a leaf node, draw the points in the leaf.
  traverse_and_draw(treeNode* t, quadrant of this node) {

     if (isLeaf(t))
          //draw all points in this leaf
          for (i=0; i < k; i++): glVertex2f(t->p[i]);
     else
          //draw two lines that cut this square into 4 quadrants    
          glBegin(gl_LINE);
          //identify the endpoints p1 and p2 of the line segment that you
          //need to draw
          glVertex2f(p1);
          glVertex2f(p2); 
          glEnd(gl_LINE);

          //recurse on children
          traverse_and_draw(t->nw,  nw quadrant of square)
          traverse_and_draw(t->sw,  sw quadrant of square)
          traverse_and_draw(t->se,  se quadrant of square)
          traverse_and_draw(t->ne,  ne quadrant of square)
}

Enjoy!