diff --git a/CMakeLists.txt b/CMakeLists.txt
index 67b5a53e11bc08c5bf849e85fcccbef0b652f519..414230a8b5c4fcf00ac10f3df35a136be792247d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,6 +40,7 @@ add_executable(
 	tests/unit_tests/intersections_tests.cpp
 	src/data_structures/box.cpp
 	src/data_structures/quad_tree.cpp
+	tests/quad_tree_tests.cpp
 )
 
 include_directories(include)
diff --git a/include/box.h b/include/box.h
index 57a99adfcbb9a9ca32cedc6b2a3aa4d76ce927f1..96a894b597fdf14315a79cccd81aeaf64e542941 100644
--- a/include/box.h
+++ b/include/box.h
@@ -1,5 +1,7 @@
 #pragma once
 
+struct Triangle;
+
 struct Box {
     float minX, maxX, minY, maxY;
     bool isIn(const Triangle &t) const;
diff --git a/include/constants.h b/include/constants.h
index 553fad2756aeba4a270a1aa8fb85a0ed6ab47663..f1f3727c36c40a566cb997d1b880945147709b93 100644
--- a/include/constants.h
+++ b/include/constants.h
@@ -2,4 +2,4 @@
 
 #define MAX_TRIANGLE_INTERSECTION_POINTS 12
 
-#define NB_TRIANGLE_SIDES 3
\ No newline at end of file
+#define NB_TRIANGLE_SIDES 3
diff --git a/include/quad_tree.h b/include/quad_tree.h
new file mode 100644
index 0000000000000000000000000000000000000000..5081945bfa80f293b738a22d05ca059103966b74
--- /dev/null
+++ b/include/quad_tree.h
@@ -0,0 +1,21 @@
+#pragma once
+#include "triangle.h"
+#include <memory>
+#include <vector>
+#include "box.h"
+
+#define QUADTREE_NODE_MAX_SHAPE 4
+
+class QuadTree {
+    Box b;
+    std::shared_ptr<Triangle> t;
+
+    std::vector<QuadTree> children;
+
+    public:
+        QuadTree(Box b);
+        void addTriangle(std::shared_ptr<Triangle> t);
+        std::vector<Triangle> visibleSurface() const;
+        Triangle pointIntersection(Point p) const;
+
+};
\ No newline at end of file
diff --git a/include/triangle.h b/include/triangle.h
index 6aa04986716e6e5d2a51dae394683968b8993d8b..c1cf50fd6c69fa0a6cde95e43b5d7016fd43a2b4 100644
--- a/include/triangle.h
+++ b/include/triangle.h
@@ -2,9 +2,11 @@
 #include "point.h"
 
 // points specified counterclockwise
-struct Triangle {
-	Point points[3];
-	int depth;
+struct Triangle
+{
+    Point points[3];
+    int depth;
+    int id;
     bool neighbours(const Triangle &other) const;
     Triangle(Point p1, Point p2, Point p3, int depth);
     bool pointInTriangle(const Point &p) const;
diff --git a/src/data_structures/quad_tree.cpp b/src/data_structures/quad_tree.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..57c101dcc72f6697eb0c0d9170d42e8699c38725
--- /dev/null
+++ b/src/data_structures/quad_tree.cpp
@@ -0,0 +1,44 @@
+#include <quad_tree.h>
+#include <union.h>
+
+QuadTree::QuadTree(Box b) : b{b} {}
+
+void QuadTree::addTriangle(std::shared_ptr<Triangle> t)
+{
+
+    if (!b.isIn(*t))
+    {
+        return;
+    }
+
+    if (this->t == nullptr && children.empty())
+    {
+        this->t = t;
+        return;
+    }
+
+    if (!children.empty())
+    {
+        for (auto &c : children)
+        {
+            c.addTriangle(t);
+        }
+    }
+
+    children = {
+        QuadTree(Box{b.minX, b.maxX / 2, b.minY, b.maxY}),
+        QuadTree(Box{b.maxX / 2, b.maxX, b.minY, b.maxY / 2}),
+        QuadTree(Box{b.maxX / 2, b.maxX, b.maxY / 2, b.maxY}),
+        QuadTree(Box{b.minX, b.maxX / 2, b.minY, b.maxY / 2})};
+
+    auto newTriangles = unionize(*t, *(this->t));
+    this->t = nullptr;
+
+    for (auto &c : children)
+    {
+        for (auto &newT : newTriangles)
+        {
+            c.addTriangle(std::make_shared<Triangle>(newT));
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/utilities/contourize.cpp b/src/utilities/contourize.cpp
index b57d2c793885fece8e4deb67fa49642fd49614e4..62528522be1a3a92b5e6dbbb81953f3c8b80f3bd 100644
--- a/src/utilities/contourize.cpp
+++ b/src/utilities/contourize.cpp
@@ -10,34 +10,7 @@ Triangle clockwiseToCounterclockwise(const Triangle &t)
     return Triangle(t.points[0], t.points[2], t.points[1], t.depth);
 }
 
-/*
-bool isCounterClockwiseForAll(const Point &previous, const Point &candidate, const std::vector<Point> & points) {
-    for (const auto &point : points) {
-        if (previous == point || candidate == point) {
-            continue;
-        }
-        if (orientation(previous, point, candidate) != Counterclockwise) {
-            return false;
-        }
-    }
-    return true;
-}
-*/
 
-/*
-Point nextPoint(const Point &previous, std::vector<Point> &candidates, const std::vector<Point> &points) {
-    Point mostCounterclockwise = candidates[0];
-    for (int i = 1; i < candidates.size(); i++) {
-        if (isCounterClockwiseForAll(previous, candidates[i], points)) {
-            Point p = candidates[i];
-            candidates.erase(i + candidates.begin());
-            return p;
-        }
-    }
-
-    return Point{-69,-69};
-}
-*/
 
 float distanceSquared(const Point &p1, const Point &p2)
 {
diff --git a/src/utilities/triangulation.cpp b/src/utilities/triangulation.cpp
index ea59fa81bdedc85d636d149c28569b385da2667f..bc3ab8c88153a97bbbe385607ebba46237cb6435 100644
--- a/src/utilities/triangulation.cpp
+++ b/src/utilities/triangulation.cpp
@@ -4,6 +4,7 @@
 #include <triangle.h>
 #include <optional>
 #include <pointList.h>
+#include <orientation.h>
 
 
 
@@ -17,23 +18,19 @@ bool isAnEar(Triangle triangle, const std::vector<Point> &points) {
     return true;
 }
 
-int mod(int a, int b) {
-    return (a + b) % b;
-}
-
-
 
 std::optional<Triangle> removeEar(int &index, PointList &pointList, const std::vector<Point> &allPoints) {
     PointNode &p = pointList.points[index];
-    const int next = pointList.next(p);
-    const int prev = pointList.prev(p);
+    const int next = p.next();
+    const int prev = p.prev();
+
 
     const PointNode &nextNode = pointList.points[next];
     const PointNode &prevNode = pointList.points[prev];
 
     Triangle candidate = Triangle{p.p, nextNode.p, prevNode.p, 0}; 
 
-    if (isAnEar(candidate, allPoints)) {
+    if (orientation(p.p, nextNode.p, prevNode.p) == Counterclockwise && isAnEar(candidate, allPoints)) {
 
         pointList.remove(index);
         index = next;
@@ -61,8 +58,8 @@ std::vector<Triangle> triangulate(std::vector<Point> points) {
     }
 
     const PointNode curr = polygon.points[i];
-    const int next = polygon.next(curr);
-    const int prev = polygon.prev(curr);
+    const int next = curr.next();
+    const int prev = curr.prev();
     
     Triangle last {curr.p, polygon.points[next].p, polygon.points[prev].p, 0};
     result.push_back(last);
diff --git a/tests/quad_tree_tests.cpp b/tests/quad_tree_tests.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..91a6db9afbc0be6b8047dc70641846f242ff8048
--- /dev/null
+++ b/tests/quad_tree_tests.cpp
@@ -0,0 +1,16 @@
+#include <gtest/gtest.h>
+#include <quad_tree.h>
+
+TEST (QuadTreeTest, SingleInsertion) {
+    QuadTree q{Box{0, 10, 0, 10}};
+
+    auto t1 = Triangle(Point{0,0}, Point{5,0},  Point{2,3}, 0);
+
+    auto t2 = Triangle(Point{3,1}, Point{6,1}, Point{4,3}, 0);
+    
+
+    q.addTriangle(std::make_shared<Triangle>(t1));
+    q.addTriangle(std::make_shared<Triangle>(t2));
+
+    EXPECT_TRUE(true);
+}
\ No newline at end of file