From f8ee6fa6728903819e81f746437cd0dac4fe19af Mon Sep 17 00:00:00 2001 From: Brandon Lai-Cheong <brandon.lai-cheong@uwaterloo.ca> Date: Wed, 20 Nov 2024 16:17:57 -0500 Subject: [PATCH] Fix 1 --- CMakeLists.txt | 1 + include/intersections.h | 3 ++- include/triangle.h | 2 +- include/triangulation.h | 4 ++-- src/debug_utilities/mostly_equal.cpp | 22 +++++++++++++++++++ src/shapes/point.cpp | 4 +--- src/shapes/triangle.cpp | 8 +------ src/union.cpp | 4 ++-- src/utilities/intersections.cpp | 14 ++++++++++-- src/utilities/triangulation.cpp | 10 ++++----- tests/union_tests.cpp | 26 ++++++++++++++--------- tests/unit_tests/ear_removal_tests.cpp | 6 +++--- tests/unit_tests/split_triangle_tests.cpp | 15 ++++++++++--- tests/unit_tests/triangulation_tests.cpp | 2 +- 14 files changed, 81 insertions(+), 40 deletions(-) create mode 100644 src/debug_utilities/mostly_equal.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fc6666d..e486617 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ project(intersection) add_executable( tests tests/unit_tests/split_triangle_tests.cpp + src/debug_utilities/mostly_equal.cpp tests/unit_tests/simple_triangle_tests.cpp tests/unit_tests/point_in_triangle_tests.cpp tests/unit_tests/triangulation_tests.cpp diff --git a/include/intersections.h b/include/intersections.h index 375e05e..ba7490d 100644 --- a/include/intersections.h +++ b/include/intersections.h @@ -11,6 +11,7 @@ struct TrigTrigInterResults { std::vector<Point> results; }; +std::optional<Point> intersectionFirstSide(const Edge &e1, const Edge &e2); std::optional<Point> intersectionWithinEdge(const Edge &e1, const Edge &e2); std::optional<Point> intersection(const Edge &e1, const Edge &e2); @@ -20,4 +21,4 @@ bool intersect(const Triangle &t1, const Triangle &t2); std::optional<Point> intersectionWithinEdgeDirection(const Edge &e1, const Edge &e2); -std::vector<Point> intersections(const Triangle t, const Edge &line); \ No newline at end of file +std::vector<Point> intersections(const Triangle &t, const Edge &line); \ No newline at end of file diff --git a/include/triangle.h b/include/triangle.h index 5aa7227..aaf6580 100644 --- a/include/triangle.h +++ b/include/triangle.h @@ -9,7 +9,7 @@ struct Triangle int depth; int id; bool neighbours(const Triangle &other) const; - Triangle(const Point &p1, const Point &p2, const Point &p3, int depth, int id = 0); + Triangle(const Point &p1, const Point &p2, const Point &p3, int depth = 0, int id = 0); bool pointInTriangle(const Point &p) const; Point nextPoint(int pointIndex) const; bool operator==(const Triangle &other) const; diff --git a/include/triangulation.h b/include/triangulation.h index 670cb6f..39153ae 100644 --- a/include/triangulation.h +++ b/include/triangulation.h @@ -6,8 +6,8 @@ class PointList; struct Point; -std::optional<Triangle> removeEar(int &index, PointList &pointList, const std::vector<Point> &allPoints); +std::optional<Triangle> removeEar(int &index, PointList &pointList, const std::vector<Point> &allPoints, int depth, int id); -std::vector<Triangle> triangulate(std::vector<Point> points); +std::vector<Triangle> triangulate(std::vector<Point> points, int depth, int id); std::vector<Triangle> triangulate(Triangle t1, Triangle t2); \ No newline at end of file diff --git a/src/debug_utilities/mostly_equal.cpp b/src/debug_utilities/mostly_equal.cpp new file mode 100644 index 0000000..63f9d12 --- /dev/null +++ b/src/debug_utilities/mostly_equal.cpp @@ -0,0 +1,22 @@ +#include <stdlib.h> +#include <point.h> +#include <triangle.h> + +bool mostlyEqual(float a, float b) +{ + return abs(a - b) < 0.0001; +} + +bool mostlyEqual(const Point &a, const Point &b) +{ + return mostlyEqual(a.x, b.x) && mostlyEqual(a.y, b.y); +} + +// mostly equal +bool Triangle::operator==(const Triangle &other) const { + return mostlyEqual(points[0], other.points[0]) && + mostlyEqual(points[1], other.points[1]) && + mostlyEqual(points[2], other.points[2]) && + depth == other.depth && + id == other.id; +} \ No newline at end of file diff --git a/src/shapes/point.cpp b/src/shapes/point.cpp index 5fce0d2..b071f72 100644 --- a/src/shapes/point.cpp +++ b/src/shapes/point.cpp @@ -1,8 +1,6 @@ #include "point.h" -bool mostlyEqual(float a, float b) { - return abs(a - b) < 0.0001; -} + bool Point::operator==(const Point &other) const { return (x == other.x) && (y == other.y); diff --git a/src/shapes/triangle.cpp b/src/shapes/triangle.cpp index e6d78f4..0624f8f 100644 --- a/src/shapes/triangle.cpp +++ b/src/shapes/triangle.cpp @@ -2,13 +2,7 @@ #include "triangle_edges.h" #include "edge.h" -bool Triangle::operator==(const Triangle &other) const { - return points[0] == other.points[0] && - points[1] == other.points[1] && - points[2] == other.points[2] && - depth == other.depth && - id == other.id; -} + bool Triangle::neighbours(const Triangle &other) const { return false; diff --git a/src/union.cpp b/src/union.cpp index 42be88b..f76a723 100644 --- a/src/union.cpp +++ b/src/union.cpp @@ -21,13 +21,13 @@ std::vector<Triangle> unionizeTopAndBottom(const Triangle &top, const Triangle & for (int i = 0; i < NB_TRIANGLE_SIDES; i++) { const Edge &e = topEdges.edges[i]; - auto shapes = splitTriangle(Triangle(relv[0], relv[1], relv[2], bot.depth, bot.id), e); + auto shapes = splitTriangle(Triangle(relv[0], relv[1], relv[2]), e); // split triangle if exists // currently relevant triangles // add these to result if (!shapes[0].empty()) { - std::vector<Triangle> relvTriangles = triangulate(shapes[0]); + std::vector<Triangle> relvTriangles = triangulate(shapes[0], bot.depth, bot.id); result.insert(result.end(), relvTriangles.begin(), relvTriangles.end()); } // future relevant triangles diff --git a/src/utilities/intersections.cpp b/src/utilities/intersections.cpp index bac5b21..270cb3f 100644 --- a/src/utilities/intersections.cpp +++ b/src/utilities/intersections.cpp @@ -56,6 +56,16 @@ std::optional<Point> intersectionWithinEdge(const Edge &e1, const Edge &e2) return {}; } +// intersection with first edge being considered infinite in length +std::optional<Point> intersectionFirstSide(const Edge &e1, const Edge &e2) { + auto candPoint = intersection(e1, e2); + + if (candPoint.has_value() && withinEdge(e2, candPoint.value())) { + return candPoint; + } + return {}; +} + // returns intersection with e1 being extended infinitly in its direction std::optional<Point> intersectionWithinEdgeDirection(const Edge &e1, const Edge &e2) { @@ -153,13 +163,13 @@ std::vector<Point> intersections(const Triangle &t1, const Triangle &t2) return results; } -std::vector<Point> intersections(const Triangle t, const Edge &line) +std::vector<Point> intersections(const Triangle &t, const Edge &line) { std::vector<Point> result; TriangleEdges es{t}; for (int i = 0; i < NB_TRIANGLE_SIDES; i++) { - auto cand = intersectionWithinEdge(es.edges[i], line); + auto cand = intersectionFirstSide(line, es.edges[i]); if (cand.has_value()) { result.push_back(cand.value()); diff --git a/src/utilities/triangulation.cpp b/src/utilities/triangulation.cpp index bc3ab8c..539517b 100644 --- a/src/utilities/triangulation.cpp +++ b/src/utilities/triangulation.cpp @@ -19,7 +19,7 @@ bool isAnEar(Triangle triangle, const std::vector<Point> &points) { } -std::optional<Triangle> removeEar(int &index, PointList &pointList, const std::vector<Point> &allPoints) { +std::optional<Triangle> removeEar(int &index, PointList &pointList, const std::vector<Point> &allPoints,int depth, int id) { PointNode &p = pointList.points[index]; const int next = p.next(); const int prev = p.prev(); @@ -28,7 +28,7 @@ std::optional<Triangle> removeEar(int &index, PointList &pointList, const std::v const PointNode &nextNode = pointList.points[next]; const PointNode &prevNode = pointList.points[prev]; - Triangle candidate = Triangle{p.p, nextNode.p, prevNode.p, 0}; + Triangle candidate = Triangle{p.p, nextNode.p, prevNode.p, depth, id}; if (orientation(p.p, nextNode.p, prevNode.p) == Counterclockwise && isAnEar(candidate, allPoints)) { @@ -44,14 +44,14 @@ std::optional<Triangle> removeEar(int &index, PointList &pointList, const std::v -std::vector<Triangle> triangulate(std::vector<Point> points) { +std::vector<Triangle> triangulate(std::vector<Point> points, int depth, int id) { std::vector<Triangle> result; PointList polygon = PointList(points); int i = 0; while (polygon.getSize() >= 4) { - std::optional<Triangle> t = removeEar(i, polygon, points); + std::optional<Triangle> t = removeEar(i, polygon, points, depth, id); if (t.has_value()) { result.push_back(t.value()); } @@ -61,7 +61,7 @@ std::vector<Triangle> triangulate(std::vector<Point> points) { const int next = curr.next(); const int prev = curr.prev(); - Triangle last {curr.p, polygon.points[next].p, polygon.points[prev].p, 0}; + Triangle last {curr.p, polygon.points[next].p, polygon.points[prev].p, depth, id}; result.push_back(last); diff --git a/tests/union_tests.cpp b/tests/union_tests.cpp index 6502b66..8f209c2 100644 --- a/tests/union_tests.cpp +++ b/tests/union_tests.cpp @@ -15,17 +15,17 @@ TEST(UnionTrivialTests, NotTouching) TEST(UnionTests, TwoIntersections) { - 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}, 1); + auto t1 = Triangle(Point{0, 0}, Point{5, 0}, Point{2, 3}, 0, 1); + auto t2 = Triangle(Point{3, 1}, Point{6, 1}, Point{4, 3}, 1, 2); auto ts = unionize(t1, t2); EXPECT_TRUE(ts.size() == 3); std::vector<Triangle> expected{ - Triangle({6,1}, {4,3}, {4,1}, 1, 0), - Triangle({4,3}, {3.33333,1.66667}, {4,1}, 1,0), - Triangle({0,0}, {5,0}, {2,3}, 0, 0)}; + Triangle({6,1}, {4,3}, {4,1}, 1, 2), + Triangle({4,3}, {3.33333,1.66667}, {4,1}, 1,2), + Triangle({0,0}, {5,0}, {2,3}, 0, 1)}; EXPECT_EQ(ts, expected); } @@ -55,20 +55,26 @@ TEST(UnionTests, SharesPointTest) TEST(UnionTests, FoldTriangleTest) { - Triangle bottom = Triangle({0, 5}, {3, 2}, {5, 3}, 1, 1); - Triangle top = Triangle({0.1, 9}, {5, 5}, {2, 4}, 2, 2); + Triangle top = Triangle({0, 5}, {3, 2}, {5, 3}, 1, 1); + Triangle bottom = Triangle({0.1, 9}, {2, 4}, {5,5}, 2, 2); auto results = unionize(bottom, top); - std::vector<Triangle> expected_results_1; + std::vector<Triangle> expected_results_1 = { + Triangle({0.1, 9}, {1.91038, 4.23585}, {5,5}, 2, 2), + Triangle({1.91038,4.23585}, {2.27273,4.09091}, {5, 5}, 2, 2), + Triangle({0,5}, {3,2}, {5,3}, 1, 1) + }; EXPECT_EQ(results, expected_results_1); - bottom.depth = 3; + top.depth = 3; results = unionize(bottom, top); - std::vector<Triangle> expected_results_2; + std::vector<Triangle> expected_results_2 = { + + }; EXPECT_EQ(results, expected_results_2); } diff --git a/tests/unit_tests/ear_removal_tests.cpp b/tests/unit_tests/ear_removal_tests.cpp index 478161d..ed567b8 100644 --- a/tests/unit_tests/ear_removal_tests.cpp +++ b/tests/unit_tests/ear_removal_tests.cpp @@ -12,11 +12,11 @@ TEST(EarRemovalTests, SingleEarRemoval) { PointList pointList = PointList(polygon); int index = 0; - auto t = removeEar(index, pointList, polygon); + auto t = removeEar(index, pointList, polygon, 0,0); EXPECT_FALSE(t.has_value()); EXPECT_TRUE(true); - auto t2 = removeEar(index, pointList, polygon); + auto t2 = removeEar(index, pointList, polygon,0,0); - auto t3 = removeEar(index, pointList, polygon); + auto t3 = removeEar(index, pointList, polygon,0,0); } \ No newline at end of file diff --git a/tests/unit_tests/split_triangle_tests.cpp b/tests/unit_tests/split_triangle_tests.cpp index 762ad39..1586dff 100644 --- a/tests/unit_tests/split_triangle_tests.cpp +++ b/tests/unit_tests/split_triangle_tests.cpp @@ -4,7 +4,7 @@ #include <edge.h> TEST(SplitTriangleTests, NormalCase) { - Triangle t = Triangle({0,0}, {0,5}, {2,3}, 1, 1); + Triangle t = Triangle({0,0}, {5,0}, {2,3}, 1, 1); Edge e{{4,3}, {3,1}}; auto results = splitTriangle(t, e); @@ -14,8 +14,8 @@ TEST(SplitTriangleTests, NormalCase) { auto pos = results[0]; auto neg = results[1]; - std::vector<Point> expected_pos = {}; - std::vector<Point> expected_neg = {}; + std::vector<Point> expected_pos = {{0,0}, {2,3}}; + std::vector<Point> expected_neg = {{5,0}}; EXPECT_EQ(pos, expected_pos); EXPECT_EQ(neg, expected_neg); } @@ -28,4 +28,13 @@ TEST(SplitTriangleTests, NormalCase2) { auto pos = results[0]; EXPECT_TRUE(pos.size() > 1); +} + +TEST(SplitTriangleTests, InvisibleIntersection) { + Edge e {{0.1,9}, {2,4}}; + Triangle t({0,5}, {3,2}, {5,5}); + + auto results = splitTriangle(t,e); + + EXPECT_TRUE(results[1].size() > 2); } \ No newline at end of file diff --git a/tests/unit_tests/triangulation_tests.cpp b/tests/unit_tests/triangulation_tests.cpp index 0e48222..65493fb 100644 --- a/tests/unit_tests/triangulation_tests.cpp +++ b/tests/unit_tests/triangulation_tests.cpp @@ -8,6 +8,6 @@ TEST(TriangulationTests, Page3Example) { {175, 77}, {131, 72}, {111, 113}, {72, 43}, {26, 55}, {29, 100}}; - auto t = triangulate(polygon); + auto t = triangulate(polygon, 0, 0); EXPECT_TRUE(t.size() > 0); } \ No newline at end of file -- GitLab