From acd8ee916396d318858e5d0cb16181a28c2fd6c5 Mon Sep 17 00:00:00 2001
From: Brandon Lai-Cheong <brandon.lai-cheong@uwaterloo.ca>
Date: Mon, 21 Oct 2024 13:16:47 -0400
Subject: [PATCH] added intersections

---
 .gitignore                                 |  4 +-
 CMakeLists.txt                             |  7 +-
 src/contourize/contourize.cpp              | 23 ++++++
 src/intersections/intersections.cpp        | 81 ++++++++++++++++++++++
 src/intersections/intersections.h          | 10 +++
 src/shapes/edge.h                          |  6 ++
 src/shapes/point.h                         |  5 ++
 src/shapes/triangle.cpp                    |  7 ++
 src/shapes/triangle.h                      | 10 +++
 src/shapes/triangle_edges.cpp              |  5 ++
 src/shapes/triangle_edges.h                |  6 ++
 src/static_vector/static_vector.h          |  7 ++
 src/triangle.h                             | 15 ----
 src/triangulation/triangulation.h          |  1 +
 src/union.cpp                              | 26 ++++---
 src/union.h                                |  0
 tests/simple_triangle_tests.cpp            |  5 --
 tests/unit_tests/simple_triangle_tests.cpp | 14 ++++
 18 files changed, 200 insertions(+), 32 deletions(-)
 create mode 100644 src/contourize/contourize.cpp
 create mode 100644 src/intersections/intersections.cpp
 create mode 100644 src/intersections/intersections.h
 create mode 100644 src/shapes/edge.h
 create mode 100644 src/shapes/point.h
 create mode 100644 src/shapes/triangle.cpp
 create mode 100644 src/shapes/triangle.h
 create mode 100644 src/shapes/triangle_edges.cpp
 create mode 100644 src/shapes/triangle_edges.h
 create mode 100644 src/static_vector/static_vector.h
 delete mode 100644 src/triangle.h
 create mode 100644 src/triangulation/triangulation.h
 create mode 100644 src/union.h
 delete mode 100644 tests/simple_triangle_tests.cpp
 create mode 100644 tests/unit_tests/simple_triangle_tests.cpp

diff --git a/.gitignore b/.gitignore
index c795b05..6d7270f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
-build
\ No newline at end of file
+build
+.vscode/c_cpp_properties.json
+.vscode/launch.json
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ecd91b8..751c960 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,9 +20,14 @@ project(intersection)
 
 add_executable(
 	tests
-	tests/simple_triangle_tests.cpp
+	tests/unit_tests/simple_triangle_tests.cpp
+	src/intersections/intersections.cpp
+	src/shapes/triangle.cpp
+	src/shapes/triangle_edges.cpp
 )
 
+include_directories(src)
+
 target_link_libraries(
 	tests
   GTest::gtest_main
diff --git a/src/contourize/contourize.cpp b/src/contourize/contourize.cpp
new file mode 100644
index 0000000..1b70df0
--- /dev/null
+++ b/src/contourize/contourize.cpp
@@ -0,0 +1,23 @@
+#include <shapes/triangle.h>
+#include <shapes/edge.h>
+#include <shapes/triangle_edges.h>
+#include <vector>
+
+bool positiveSide(Edge e, Point p) {
+    float h = e.p1.y - e.p2.y;
+    float g = e.p1.x - e.p2.x; 
+    return -h * (p.x - e.p1.x) + g * (p.y - e.p1.y) >= 0;
+}
+
+bool pointInTriangle(Point p, Triangle t) {
+    // all tests must be positive
+    auto edges = TriangleEdges(t);
+
+    return positiveSide(edges.e1, p) &&
+    positiveSide(edges.e2, p) &&
+    positiveSide(edges.e3, p);
+}
+
+void contourize(Triangle t1, Triangle t2, std::vector<Point> newIntersections) {
+
+}
\ No newline at end of file
diff --git a/src/intersections/intersections.cpp b/src/intersections/intersections.cpp
new file mode 100644
index 0000000..c6b1ec1
--- /dev/null
+++ b/src/intersections/intersections.cpp
@@ -0,0 +1,81 @@
+#include "intersections.h"
+#include <shapes/edge.h>
+#include <shapes/triangle_edges.h>
+#include <shapes/point.h>
+#include <optional>
+
+
+
+std::optional<float> getB(std::optional<float> slope, Point p) {
+    if (!slope.has_value()) {
+        return {};
+    }
+
+    return p.y - slope.value() * p.x;
+}
+
+std::optional<float> getSlope(Edge e) {
+    if (e.p2.x - e.p1.x == 0) {
+        return {};
+    }
+    return (e.p2.y - e.p1.y) / (e.p2.x - e.p1.x) ;
+}
+
+bool withinEdge(Edge e, Point p) {
+    float minX = std::min(e.p1.x, e.p2.x);
+    float maxX = std::max(e.p1.x, e.p2.x);
+
+    float minY = std::min(e.p1.y, e.p2.y);
+    float maxY = std::max(e.p1.y, e.p2.y);
+
+    return minX <= p.x && p.x <= maxX && minY <= p.y && p.y <= maxY; 
+}
+
+
+void intersection(Edge e1, Edge e2, std::vector<Point> &results) {
+    auto slope1 = getSlope(e1);
+    auto slope2 = getSlope(e2);
+
+    auto b1 = getB(slope1, e1.p1);
+    auto b2 = getB(slope2, e2.p1);
+
+
+    // ignore overlapping case
+    if (!slope1.has_value() && !slope2.has_value()) {
+        return;
+    }
+
+    if (!slope1.has_value()) {
+        results.push_back(Point{e1.p1.x, slope2.value() * e1.p1.x + b2.value()});
+        return;
+    }
+
+    if (!slope2.has_value()) {
+        results.push_back(Point{e2.p1.x, slope1.value() * e2.p1.x + b1.value()});
+        return;
+    }
+    float candX = (b2.value() - b1.value()) / (slope1.value() - slope2.value());
+    auto candPoint = Point{ candX, slope1.value() * candX + b1.value()};
+
+    if (withinEdge(e1, candPoint) && withinEdge(e2, candPoint)) {
+        results.push_back(candPoint);
+    }
+}
+void intersections(Edge e1, TriangleEdges te, std::vector<Point> &results) {
+   intersection(e1, te.e1, results);
+   intersection(e1, te.e2, results);
+   intersection(e1, te.e3, results); 
+}
+std::vector<Point> intersections(Triangle t1, Triangle t2) {
+    TriangleEdges t1Edges = TriangleEdges(t1);
+
+    TriangleEdges t2Edges = TriangleEdges(t2);
+    std::vector<Point> results;
+
+    intersections(t1Edges.e1, t2Edges, results);
+    intersections(t1Edges.e2, t2Edges, results);
+    intersections(t1Edges.e3, t2Edges, results);
+
+    return results;
+}
+
diff --git a/src/intersections/intersections.h b/src/intersections/intersections.h
new file mode 100644
index 0000000..ca089a0
--- /dev/null
+++ b/src/intersections/intersections.h
@@ -0,0 +1,10 @@
+#pragma once
+#include <vector>
+#include "../shapes/point.h"
+#include "../shapes/triangle.h"
+
+struct TrigTrigInterResults {
+    std::vector<Point> results;
+};
+
+std::vector<Point> intersections(Triangle t1, Triangle t2);
\ No newline at end of file
diff --git a/src/shapes/edge.h b/src/shapes/edge.h
new file mode 100644
index 0000000..22c0da3
--- /dev/null
+++ b/src/shapes/edge.h
@@ -0,0 +1,6 @@
+#pragma once
+#include "point.h"
+
+struct Edge {
+	Point p1, p2;
+};
\ No newline at end of file
diff --git a/src/shapes/point.h b/src/shapes/point.h
new file mode 100644
index 0000000..0e55134
--- /dev/null
+++ b/src/shapes/point.h
@@ -0,0 +1,5 @@
+#pragma once
+
+struct Point {
+	float x, y;
+};
\ No newline at end of file
diff --git a/src/shapes/triangle.cpp b/src/shapes/triangle.cpp
new file mode 100644
index 0000000..7f46643
--- /dev/null
+++ b/src/shapes/triangle.cpp
@@ -0,0 +1,7 @@
+#include "triangle.h"
+
+bool Triangle::neighbours(Triangle &other) {
+    return false;
+}
+
+Triangle::Triangle(Point p1, Point p2, Point p3, int depth) : p1{p1}, p2{p2}, p3{p3}, depth{depth} {}
\ No newline at end of file
diff --git a/src/shapes/triangle.h b/src/shapes/triangle.h
new file mode 100644
index 0000000..1d1d298
--- /dev/null
+++ b/src/shapes/triangle.h
@@ -0,0 +1,10 @@
+#pragma once
+#include "point.h"
+
+// points specified clockwise
+struct Triangle {
+	Point p1, p2, p3;
+	int depth;
+	bool neighbours(Triangle &other);
+	Triangle(Point p1, Point p2, Point p3, int depth);
+};
diff --git a/src/shapes/triangle_edges.cpp b/src/shapes/triangle_edges.cpp
new file mode 100644
index 0000000..c5b5614
--- /dev/null
+++ b/src/shapes/triangle_edges.cpp
@@ -0,0 +1,5 @@
+#include "triangle_edges.h"
+#include "triangle.h"
+
+TriangleEdges::TriangleEdges(const Triangle &t) : e1{Edge{t.p1, t.p2}}, e2{Edge{t.p2, t.p3}}, e3{Edge{t.p3, t.p1}}{
+}
\ No newline at end of file
diff --git a/src/shapes/triangle_edges.h b/src/shapes/triangle_edges.h
new file mode 100644
index 0000000..d0afc10
--- /dev/null
+++ b/src/shapes/triangle_edges.h
@@ -0,0 +1,6 @@
+#include "edge.h"
+struct Triangle;
+struct TriangleEdges {
+    Edge e1, e2, e3;
+    TriangleEdges(const Triangle &t);
+};
diff --git a/src/static_vector/static_vector.h b/src/static_vector/static_vector.h
new file mode 100644
index 0000000..e738609
--- /dev/null
+++ b/src/static_vector/static_vector.h
@@ -0,0 +1,7 @@
+
+template<class T>
+class StaticVector{
+
+    int maxSize;
+
+};
\ No newline at end of file
diff --git a/src/triangle.h b/src/triangle.h
deleted file mode 100644
index 8f47975..0000000
--- a/src/triangle.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#pragma once
-
-struct Point {
-	float x, y;
-};
-
-struct Edge {
-	Point p1, p2;
-};
-
-struct Triangle {
-	Point p1, p2, p3;
-	int depth;
-	// neighbours
-};
diff --git a/src/triangulation/triangulation.h b/src/triangulation/triangulation.h
new file mode 100644
index 0000000..6f70f09
--- /dev/null
+++ b/src/triangulation/triangulation.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/src/union.cpp b/src/union.cpp
index bf21feb..a90877f 100644
--- a/src/union.cpp
+++ b/src/union.cpp
@@ -1,26 +1,32 @@
-#include "triangle.h"
+#include "shapes/triangle.h"
 #include <vector>
 #include <optional>
+#include <intersections/intersections.h>
 
-std::optional<Point> intersection(Edge e1, Edge e2) {
+std::vector<Point> contourize(std::vector<Point> points) {
 
 }
 
-std::vector<Point> intersections(Triangle t1, Triangle t2) {
-
-}
-
-std::vector<Triangle> triangulate() {
-}
-
 std::vector<Triangle> unionize(Triangle t1, Triangle t2) {
 
+	// if neighbours, do nothing
+	if (t1.neighbours(t2)) {
+		return std::vector{t1, t2};
+	}
+
 	// at most 3? if infinite -> consider no intersections
 	std::vector<Point> newIntersections = intersections(t1, t2);
 
 	if (newIntersections.empty()) {
 		// either completely envelops each other, no intersections	
+		return std::vector{t1, t2};
 	}
 
-	return triangulate();
+	std::vector<Point> contour = contourize();
+
+	return triangulate(contour);
 }
+
+void unionize(Triangle soup) {
+
+}
\ No newline at end of file
diff --git a/src/union.h b/src/union.h
new file mode 100644
index 0000000..e69de29
diff --git a/tests/simple_triangle_tests.cpp b/tests/simple_triangle_tests.cpp
deleted file mode 100644
index 99f95a0..0000000
--- a/tests/simple_triangle_tests.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "gtest/gtest.h"
-
-TEST (TriangleIntersectionTests, TriangleIntersection) {
-
-}
\ No newline at end of file
diff --git a/tests/unit_tests/simple_triangle_tests.cpp b/tests/unit_tests/simple_triangle_tests.cpp
new file mode 100644
index 0000000..bb4603e
--- /dev/null
+++ b/tests/unit_tests/simple_triangle_tests.cpp
@@ -0,0 +1,14 @@
+#include "gtest/gtest.h"
+#include "../../src/shapes/triangle.h"
+#include "../../src/intersections/intersections.h"
+
+TEST (TriangleIntersectionTests, TriangleIntersection) {
+    auto t1 = Triangle(Point(0,0), Point(2,3), Point(5,0), 0);
+    auto t2 = Triangle(Point(3,1), Point(4,3), Point(6,1), 0);
+
+    std::vector<Point> results = intersections(t1, t2);
+
+    EXPECT_TRUE(results.size() == 2) << "Actual size: " << results.size();
+
+}
+
-- 
GitLab