diff --git a/.gitignore b/.gitignore index c795b054e5ade51b7031abab1581a5b7e2d2f5ba..6d7270f82d1cd707caf4df63c42211684a949cd5 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 ecd91b8772dfb3ee49e097ed65f106647b0f8b32..751c960c22fd50a8ce6e1f7ed60d08ebf9575288 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 0000000000000000000000000000000000000000..1b70df007d586493d6950b5600e67d4af331435c --- /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 0000000000000000000000000000000000000000..c6b1ec18d7c668d106df70f6f12b16a74f804f24 --- /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 0000000000000000000000000000000000000000..ca089a03a1e43d3277efffe481da7c664e926cc7 --- /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 0000000000000000000000000000000000000000..22c0da354b30742275c217ccc5a5bb0dba79120f --- /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 0000000000000000000000000000000000000000..0e55134aa3248dd257aa408de3a145b583cb3756 --- /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 0000000000000000000000000000000000000000..7f46643a92a4af6f222a5ca29d641f0308b3ac9b --- /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 0000000000000000000000000000000000000000..1d1d2984b80342bbc5b10d6f9222812296a3a3e3 --- /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 0000000000000000000000000000000000000000..c5b5614a1529515315308c167dc6d3a9079e5711 --- /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 0000000000000000000000000000000000000000..d0afc10effe9ff2a3bd89b0583059c00515fcc89 --- /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 0000000000000000000000000000000000000000..e7386090766f159cd4c8fd55c9403a2b7ec9fb7e --- /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 8f479759cca3933d4192894d9c8365e60ec8a003..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..6f70f09beec2219624baeca92e2cd7deaa104fb4 --- /dev/null +++ b/src/triangulation/triangulation.h @@ -0,0 +1 @@ +#pragma once diff --git a/src/union.cpp b/src/union.cpp index bf21feb181117b8f9b12c901f9c8802d69e48794..a90877f1ee7432ea334a44b2317db447906971aa 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 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/simple_triangle_tests.cpp b/tests/simple_triangle_tests.cpp deleted file mode 100644 index 99f95a03f5d918e282703fc75f94a3fad1273240..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..bb4603ea6f86ef1d700414344dd79badbf6896b5 --- /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(); + +} +