diff --git a/CgMath/CgPointWrangler.h b/CgMath/CgPointWrangler.h
index 7b04f3dc887257652919d34744f507b7e1cb8d81..ba1be38afba82cb5dce259ff2df676efa0015735 100644
--- a/CgMath/CgPointWrangler.h
+++ b/CgMath/CgPointWrangler.h
@@ -4,6 +4,7 @@
 // stl
 #include <vector>
 #include <queue>
+#include <deque>
 #include <limits>
 #include <string>
 #include <algorithm>
@@ -313,38 +314,46 @@ inline std::vector<std::pair<unsigned int, unsigned int>> CgPointWrangler::makeN
     }
     visited[max_y_index] = true;
 
-    // stack of point indices to process next
-    std::vector<unsigned int> stack;
     // record the "best" parent found for each vertex
     std::vector<std::pair<unsigned int, double>> scores;
     scores.resize(pca.size());
 
+    // queue of point indices to process next
+    std::vector<unsigned int> queue;
+
+    auto cmp = [&](const unsigned int left, unsigned int right) {
+        return scores[left].second > scores[right].second;
+    };
+
     auto visit = [&](unsigned int curr) {
         glm::vec3 normal = pca[curr].evec0;
+        glm::vec3 point = pca[curr].centroid;
+        double rad = pca[curr].radius2;
 
         // retrieve neighbourhood indices
         auto curr_nh_ind = neighbourhoods[curr];
 
         // find out which of the neighbours we didn't process yet
         // and score them to find out in which order to process
-        // push them to the stack in reverse order so we process the
-        // closest one first
-        for(unsigned int i = curr_nh_ind.size() - 1; i > 0; i--) {
+        for(unsigned int i = 0; i < curr_nh_ind.size(); i++) {
             unsigned int index = curr_nh_ind[i];
             // score by how far away it is from the current point
             // and how parallel the normals are.
             double alignment = 1.0 - std::abs(glm::dot(pca[index].evec0, normal));
-            double distance = glm::distance(pca[index].centroid, pca[curr].centroid);
-            double score = alignment;
+            double distance = glm::distance(pca[index].centroid, point) / rad;
+            double score = distance + alignment;
             if(!visited[index]) {
                 scores[index].first = curr;
                 scores[index].second = score;
-                stack.push_back(index);
+                queue.push_back(index);
+                std::push_heap(queue.begin(), queue.end(), cmp);
                 visited[index] = true;
             } else if(scores[index].second > score) {
                 // update current neighbors parent to current node, since it's closer
                 scores[index].first = curr;
                 scores[index].second = score;
+                // re-sort the heap with the new score
+                std::make_heap(queue.begin(), queue.end(), cmp);
             }
         }
     };
@@ -354,10 +363,12 @@ inline std::vector<std::pair<unsigned int, unsigned int>> CgPointWrangler::makeN
     visit(max_y_index); 
 
     // start processing
-    while(!stack.empty()) {
-        unsigned int curr = stack.back();
+    while(!queue.empty()) {
+        // pop the index with the smallest score
+        std::pop_heap(queue.begin(), queue.end(), cmp);
+        unsigned int curr = queue.back();
         unsigned int parent = scores[curr].first;
-        stack.pop_back();
+        queue.pop_back();
         spanning_tree.push_back({parent, curr});
         visit(curr);
     }
@@ -400,7 +411,7 @@ inline std::vector<PCA> CgPointWrangler::performHierarchicalSimplification(
     float max_cluster_radius
 ){
     unsigned int MAX_POINTS = std::min(100.0f, max_cluster_size);
-    unsigned int MIN_POINTS = 6;
+    unsigned int MIN_POINTS = 3;
 
     std::vector<unsigned int> hist;
     hist.resize(MAX_POINTS + 1, 0);
@@ -431,6 +442,8 @@ inline std::vector<PCA> CgPointWrangler::performHierarchicalSimplification(
         } else {
             // split it & recurse
             // indices vector is not behind mutex because 
+        // indices vector is not behind mutex because 
+            // indices vector is not behind mutex because 
             // the threads work on mutually exclusive ranges
             unsigned int lower = job.first;
             unsigned int upper = job.second;
diff --git a/CgSceneGraph/CgSceneControl.cpp b/CgSceneGraph/CgSceneControl.cpp
index 0f858ea0d188b10d32b39daf218fdbdc88ee5d78..4e94832f09e3264a936e1b37250dae401770474e 100644
--- a/CgSceneGraph/CgSceneControl.cpp
+++ b/CgSceneGraph/CgSceneControl.cpp
@@ -304,7 +304,7 @@ void CgSceneControl::handleEvent(CgBaseEvent* e) {
         std::vector<glm::vec3> new_colors(pca.size());
         CgPointWrangler::buildKdTree(pca.data(), pca.data() + pca.size(), 0);
         for(unsigned int i = 0; i < pca.size(); i++) new_points[i] = pca[i].centroid;
-        std::vector<std::vector<unsigned int>> neighbourhoods = CgPointWrangler::getKNeighbourhoods(5, new_points);
+        std::vector<std::vector<unsigned int>> neighbourhoods = CgPointWrangler::getKNeighbourhoods(15, new_points);
         std::vector<std::pair<unsigned int, unsigned int>> spanning_tree = CgPointWrangler::makeNaiveSpanningTree(neighbourhoods, pca);
         std::vector<glm::vec3> new_normals = CgPointWrangler::alignNormals(glm::vec3(0.0,1.0,0.0), spanning_tree, pca);