From 15aa822a118d12ecbdb4f30cc30bc8ef0abe0785 Mon Sep 17 00:00:00 2001
From: Brandon Lai-Cheong <brandon.lai-cheong@uwaterloo.ca>
Date: Wed, 30 Oct 2024 14:37:14 -0400
Subject: [PATCH] works for convex shapes

---
 CMakeLists.txt                         |  1 +
 src/utilities/contourize.cpp           | 75 ++++++++++++++------------
 tests/unit_tests/contourize_tests.cpp  |  8 +++
 tests/unit_tests/orientation_tests.cpp | 24 +++++++++
 4 files changed, 73 insertions(+), 35 deletions(-)
 create mode 100644 tests/unit_tests/orientation_tests.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6d6c94b..acfdd53 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,6 +36,7 @@ add_executable(
 	src/union.cpp
 	src/utilities/triangulation.cpp
 	src/utilities/pointList.cpp
+	tests/unit_tests/orientation_tests.cpp
 )
 
 include_directories(include)
diff --git a/src/utilities/contourize.cpp b/src/utilities/contourize.cpp
index 668b70e..3cee1fc 100644
--- a/src/utilities/contourize.cpp
+++ b/src/utilities/contourize.cpp
@@ -6,75 +6,78 @@ 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, candidate, point) != Counterclockwise) {
+        if (orientation(previous, point, candidate) != Counterclockwise) {
             return false;
         }
     }
     return true;
 }
+*/
 
-
-Point nextPoint(const Point &previous, std::vector<Point> candidates, const std::vector<Point> points) {
-    for (int i = 0; i < candidates.size(); i++) {
+/*
+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};
 } 
+*/
 
-std::vector<Point> sortPoints(const Triangle &t1, const Triangle &t2, const std::vector<Point> points) {
+std::vector<Point> contourize(const Triangle &t1, const Triangle &t2, const std::vector<Point> &intersections) {
     std::vector<Point> result;
     const int NUM_TRIANGLE_POINTS = 3;
     // using convex hull algorithm
     // start at leftmost point
-    Point minX = t1.points[0];
 
-    for (int i = 1; i < NUM_TRIANGLE_POINTS; i++) {
-        if (t1.points[i].x < minX.x) {
-            minX = t1.points[i];
-        }
-    }
+    // get points
+    // initially ignoring intersection points because they cannot be the leftmost
+    std::vector<Point> points;
+
+    points.insert(points.end(), t1.points, t1.points + NUM_TRIANGLE_POINTS);
+    points.insert(points.end(), t2.points, t2.points + NUM_TRIANGLE_POINTS);
 
-    for (int i = 0; i < NUM_TRIANGLE_POINTS; i++) {
-        if (t2. points[i].x < minX.x) {
-            minX = t2.points[i];
+    int minX = 0;
+    for (int i = 0; i < points.size(); i++) {
+        if (points[minX].x > points[i].x) {
+            minX = i;
         }
     }
 
-    // filter out points
+    // add intersection points
+    points.insert(points.end(), intersections.begin(), intersections.end());
 
-    std::vector<Point> candidates;
-     for (int i = 1; i < NUM_TRIANGLE_POINTS; i++) {
-        if (!(t1.points[i] == minX)) {
-            candidates.push_back(t1.points[i]);
-        } 
-    }
+    int previous = minX;
+    int candidate;
 
-    for (int i = 0; i < NUM_TRIANGLE_POINTS; i++) {
-        if (t2.points[i] != minX) {
-            candidates.push_back(t2.points[i]);
+    do {
+        
+        result.push_back(points[previous]);
+        candidate = (previous + 1) % points.size();
+        for (int i = 0; i < points.size(); i++) {
+            if (orientation(points[previous], points[candidate], points[i]) == Counterclockwise) {
+                candidate = i;
+            }
         }
-    }
-
+        previous = candidate;
+    } while (previous != minX);
 
-    Point previous = minX;
-    for (int i = 0; i < candidates.size(); i++) {
-        nextPoint(previous, candidates, points);
-    }
-
-     
+    return result;
 }
 
 
-
+/*
 
 std::vector<Point> contourize(const Triangle &t1, const Triangle &t2, const std::vector<Point> &newIntersections) {
     std::vector<Point> result;
@@ -95,4 +98,6 @@ std::vector<Point> contourize(const Triangle &t1, const Triangle &t2, const std:
     result.insert(result.end(), newIntersections.begin(), newIntersections.end());
 
     return result;
-}
\ No newline at end of file
+}
+
+*/
\ No newline at end of file
diff --git a/tests/unit_tests/contourize_tests.cpp b/tests/unit_tests/contourize_tests.cpp
index 93bda8d..98b279b 100644
--- a/tests/unit_tests/contourize_tests.cpp
+++ b/tests/unit_tests/contourize_tests.cpp
@@ -12,5 +12,13 @@ TEST(ContourizeTest, TwoTriangles) {
     auto contour = contourize(t1, t2, newIntersections);
 
     EXPECT_TRUE(contour.size() > 0);
+    std::vector<Point> expectedContour {Point{0,0}, 
+    Point{5,0}, 
+    Point{4, 1}, 
+    Point{6,1}, 
+    Point{4,3}, 
+    Point{3.33333325, 1.66666675}, 
+    Point{2,3}};
+    EXPECT_EQ(contour, expectedContour);
 
 }
\ No newline at end of file
diff --git a/tests/unit_tests/orientation_tests.cpp b/tests/unit_tests/orientation_tests.cpp
new file mode 100644
index 0000000..1a9a57c
--- /dev/null
+++ b/tests/unit_tests/orientation_tests.cpp
@@ -0,0 +1,24 @@
+#include <gtest/gtest.h>
+#include <orientation.h>
+#include <point.h>
+
+TEST (OrientationTests, CounterClockwiseTest) {
+    
+    EXPECT_EQ(orientation(Point{0,0}, Point{1,0}, Point{0.5, 0.5}), Counterclockwise);
+}
+
+TEST (OrientationTests, Clockwise) {
+    EXPECT_EQ(orientation(Point{0,0}, Point{0.5, 0.5}, Point{1,0}), Clockwise);
+}
+
+TEST (OrientationTests, Collinear) {
+    EXPECT_EQ(orientation(Point{0,0}, Point{1,0}, Point{2,0}), Collinear);
+}
+
+TEST (OrientationTests, ExampleCounterClockwiseTest) {
+    EXPECT_EQ(orientation(Point{0,0}, Point{4,4}, Point{1,2}), Counterclockwise);
+}
+
+/*TEST (OrientationTests, Counterclockwise2Test) {
+    EXPECT_EQ(orientation({}, {}, {}), Counterclockwise);
+}*/
\ No newline at end of file
-- 
GitLab