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