Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • shlomist/unionized-triangles
  • blaicheo/unionized-triangles-2
2 results
Show changes
Showing
with 377 additions and 238 deletions
......@@ -3,9 +3,7 @@
#include <point.h>
std::ostream &operator<<(std::ostream &os, const Triangle &t) {
return os << "Triangle: " << t.id
<< ", " << "Depth: " << t.depth
<< " {" << t.points[0] << ", " << t.points[1] << ", " << t.points[2] << "}";
return os << "Triangle" << "(" << t.points[0] << ", " << t.points[1] << ", " << t.points[2] << ", " << t.mainTriangleId << ")";
}
/*
std::ostream &operator<<(std::ostream &os, const std::vector<Triangle> &triangles) {
......
#include <shift_triangle.h>
#include <triangle.h>
#include <constants.h>
void shiftZ(Triangle &t, float z) {
for (int i =0; i < NB_TRIANGLE_SIDES; i++) {
t.points[i].z += z;
}
}
\ No newline at end of file
......@@ -3,9 +3,23 @@
bool Point::operator==(const Point &other) const {
return (x == other.x) && (y == other.y);
return (x == other.x) && (y == other.y) && (z == other.z);
}
std::ostream &operator<<(std::ostream &os, Point const &p) {
return os << "(" << p.x << "," << p.y << ")";
return os << "{" << p.x << "," << p.y << "," << p.z << "}";
}
Point Point::operator-() const {
return {-x, -y,-z};
}
Point Point::operator+(const Point &other) const {
return {x + other.x, y + other.y, z + other.z};
}
Point Point::operator-(const Point &other) const {
return *this + (- other);
}
#include "triangle.h"
#include "triangle_edges.h"
#include "edge.h"
#include <triangle_fragment_id_assigner.h>
Triangle::Triangle(const Point &p1, const Point &p2, const Point &p3, int depth, int id, std::vector<int> neighbours) : points{p1,p2,p3}, depth{depth}, id{id}, neighbours{neighbours} {}
Triangle::Triangle(const Point &p1, const Point &p2, const Point &p3, int mainTriangleId, std::shared_ptr<std::vector<int>> neighbours = {}) :
points{p1, p2, p3}, mainTriangleId{mainTriangleId}, fragmentId{TriangleFragmentIdAssigner::getInstance().generateUniqueId()}, neighbours{neighbours} {}
bool Triangle::pointInTriangle(const Point &p) const {
Triangle::Triangle(const Point &p1, const Point &p2, const Point &p3, int mainTriangleId, const std::vector<int> neighbours) :
points{p1, p2, p3}, mainTriangleId{mainTriangleId}, fragmentId{TriangleFragmentIdAssigner::getInstance().generateUniqueId()}, neighbours{make_shared<std::vector<int>>(neighbours)} {}
bool Triangle::pointInTriangle(const Point &p) const
{
// all tests must be positive
auto edges = TriangleEdges(*this);
for (int i = 0; i < NB_TRIANGLE_SIDES; i++) {
if (edges.edges[i].positiveSide(p)) {
for (int i = 0; i < NB_TRIANGLE_SIDES; i++)
{
if (edges.edges[i].positiveSide(p))
{
return false;
}
}
return true;
}
int nextPoint(int pointIndex) {
int nextPoint(int pointIndex)
{
return (pointIndex + 1) % 3;
}
......@@ -6,13 +6,18 @@
#include <triangle_edges.h>
#include <intersections.h>
#include <split_triangle.h>
#include <triangulation.h>
#include <convex_triangulation.h>
#include <orientation.h>
std::vector<Triangle> unionizeTopAndBottom(const Triangle &top, const Triangle &bot)
{
// degenerate line / point case
if (orientation(top) == Collinear) {
return {bot, top};
}
std::vector<Triangle> result;
std::list<Point> intr;
TriangleEdges topEdges = TriangleEdges(top);
// keep track of relevant triangles
......@@ -21,13 +26,16 @@ std::vector<Triangle> unionizeTopAndBottom(const Triangle &top, const Triangle &
for (int i = 0; i < NB_TRIANGLE_SIDES; i++)
{
const Edge &e = topEdges.edges[i];
// index 0: On the "outside" of the edge
// index 1: On the "inside" of the edge
auto shapes = splitShape(relv, e);
// split triangle if exists
// currently relevant triangles
// add these to result
if (!shapes[0].empty())
{
std::vector<Triangle> relvTriangles = triangulate(shapes[0], bot.depth, bot.id);
std::vector<Triangle> relvTriangles = convexTriangulation(shapes[0], bot.mainTriangleId, bot.neighbours);
result.insert(result.end(), relvTriangles.begin(), relvTriangles.end());
}
// future relevant triangles
......@@ -40,14 +48,14 @@ std::vector<Triangle> unionizeTopAndBottom(const Triangle &top, const Triangle &
std::vector<Triangle> unionize(const Triangle &t1, const Triangle &t2)
{
if (std::find(t1.neighbours.begin(), t1.neighbours.end(), t2.id) != t1.neighbours.end()) {
return {t1, t2};
}
if (intersections(t1, t2).empty())
{
if (t1.mainTriangleId == t2.mainTriangleId) {
return {t1, t2};
}
if (t1.depth < t2.depth)
if (std::find(t1.neighbours->begin(), t1.neighbours->end(), t2.mainTriangleId) != t1.neighbours->end()) {
return {t1, t2};
}
if (t1.points[0].z < t2.points[0].z)
{
return unionizeTopAndBottom(t1, t2);
}
......
#include <vector>
#include <triangle.h>
std::vector<Triangle> completeTriangles() {
//
}
\ No newline at end of file
......@@ -3,12 +3,20 @@
#include <orientation.h>
#include <list>
const char* ContourizeException::what() const throw() {
return "Infinite Loop detected";
}
bool isCounterClockwiseForAll(const Point &previous, const Point &candidate, const std::vector<Point> & points) {
for (const auto &point : points) {
if (previous == point || candidate == point) {
continue;
}
auto o = orientation(previous, candidate, point);
if (o == Collinear) {
continue;
}
if (o != Counterclockwise) {
return false;
}
......@@ -21,20 +29,37 @@ std::vector<Point> contourize(const std::vector<Point> &points) {
return points;
}
std::vector<Point> result;
Point previous = points[0];
result.push_back(previous);
std::list<Point> candidates(points.begin() + 1, points.end());
while (!candidates.empty()) {
const int size = candidates.size();
// infinite loop detection
int seen = 0;
while (candidates.size() > 1) {
// detect infinite loop
if (seen >= candidates.size()) {
throw ContourizeException();
}
if (isCounterClockwiseForAll(previous, candidates.front(), points)) {
previous = candidates.front();
candidates.pop_front();
result.push_back(previous);
result.push_back(previous);
seen = 0;
} else {
candidates.push_back(candidates.front());
candidates.pop_front();
seen++;
}
}
result.push_back(candidates.front());
return result;
}
#include <convex_triangulation.h>
#include <orientation.h>
std::vector<Triangle> convexTriangulation(const std::vector<Point> &points, int depth, int triangleId) {
// filters out degenerate triangles
void appendResults(std::vector<Triangle> &results, const Triangle &t) {
if (orientation(t) == Collinear) {
return;
}
results.push_back(t);
}
std::vector<Triangle> convexTriangulation(const std::vector<Point> &points, int triangleId, std::shared_ptr<std::vector<int>> neighbours) {
const int size = points.size();
if (size < 3) {
return std::vector<Triangle>{};
}
const Triangle t1 = Triangle(points[0], points[1], points[2], depth, triangleId);
std::vector<Triangle> results = {t1};
const Triangle t1 = Triangle(points[0], points[1], points[2], triangleId, neighbours);
std::vector<Triangle> results;
appendResults(results, t1);
Point first = points[0];
for (int i = size - 1; i >= 3; i--) {
results.push_back(Triangle(first, points[2], points[i], depth, triangleId));
const Triangle t = Triangle(first, points[2], points[i], triangleId, neighbours);
appendResults(results, t);
first = points[i];
}
return results;
}
#include <interpolate_z.h>
#include <limits>
#include <point.h>
#include <edge.h>
#include <cmath>
float dist2D(const Point &p) {
return sqrt(p.x * p.x + p.y * p.y);
}
float interpolateZ(const Edge &e, const Point &p) {
const float p1Dist = dist2D(e.p1);
const float p2Dist = dist2D(e.p2);
const float pDist = dist2D(p);
if (p1Dist - p2Dist == 0) {
return e.p1.z;
}
const float m = (e.p1.z - e.p2.z) / (p1Dist - p2Dist);
const float b = e.p1.z - p1Dist * m;
return m * pDist + b;
}
......@@ -4,6 +4,7 @@
#include <triangle.h>
#include <constants.h>
#include <edge.h>
#include <interpolate_z.h>
std::optional<float> getB(std::optional<float> slope, Point p)
{
......@@ -61,6 +62,8 @@ std::optional<Point> intersectionFirstSide(const Edge &e1, const Edge &e2) {
auto candPoint = intersection(e1, e2);
if (candPoint.has_value() && withinEdge(e2, candPoint.value())) {
float z = interpolateZ(e2, candPoint.value());
candPoint.value().z = z;
return candPoint;
}
return {};
......@@ -138,7 +141,6 @@ std::optional<Point> intersection(const Edge &e1, const Edge &e2)
{
return {};
}
return candPoint;
}
void intersections(const Edge &e1, const TriangleEdges &te, std::vector<Point> &results)
......@@ -176,4 +178,4 @@ std::vector<Point> intersections(const std::vector<Point> &points, const Edge &l
}
}
return result;
}
\ No newline at end of file
}
#include "orientation.h"
#include <point.h>
#include <triangle.h>
float edgeValue(const Point &p1, const Point &p2) {
return (p2.x - p1.x) * (p2.y + p1.y);
......@@ -12,4 +13,9 @@ Orientation orientation(const Point &p1, const Point &p2, const Point &p3) {
}
return (val > 0) ? Clockwise : Counterclockwise;
}
Orientation orientation(const Triangle &t) {
return orientation(t.points[0], t.points[1], t.points[2]);
}
\ No newline at end of file
#include "triangulation.h"
#include <list>
#include <point.h>
#include <triangle.h>
#include <optional>
#include <pointList.h>
#include <orientation.h>
bool isAnEar(Triangle triangle, const std::vector<Point> &points) {
for (const Point &p: points) {
if (triangle.pointInTriangle(p)) {
return false;
}
}
return true;
}
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();
const PointNode &nextNode = pointList.points[next];
const PointNode &prevNode = pointList.points[prev];
Triangle candidate = Triangle{p.p, nextNode.p, prevNode.p, depth, id};
if (orientation(p.p, nextNode.p, prevNode.p) == Counterclockwise && isAnEar(candidate, allPoints)) {
pointList.remove(index);
index = next;
return candidate;
}
index = next;
return {};
}
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, depth, id);
if (t.has_value()) {
result.push_back(t.value());
}
}
const PointNode curr = polygon.points[i];
const int next = curr.next();
const int prev = curr.prev();
Triangle last {curr.p, polygon.points[next].p, polygon.points[prev].p, depth, id};
result.push_back(last);
return result;
}
\ No newline at end of file
#include <gtest/gtest.h>
#include <union.h>
#include <triangle.h>
#include <orientation.h>
#include "union_tests.h"
TEST(UnionEdgeTests, TriangleVertexOnEdge) {
Triangle t1 = Triangle({}, {}, {}, 1, 1);
Triangle t2 = Triangle({}, {}, {}, 2, 2);
auto result = unionize(t1, t2);
INSTANTIATE_TEST_SUITE_P(EdgeUnionTests, InstantiateUnionTests, testing::Values(
// Point on top of triangle
UnionParams{Triangle({0, 0, 4}, {5, 0, 4}, {2, 3, 4}, 1), Triangle({1, 1, 0}, {1, 1, 0}, {1, 1, 0}, 2), {Triangle({0, 0, 4}, {5, 0, 4}, {2, 3, 4}, 1), Triangle({1, 1, 0}, {1, 1, 0}, {1, 1, 0}, 2)}},
// Point on edge of triangle
UnionParams{Triangle({0, 0, 6}, {5, 0, 6}, {2, 3, 6}, 1), Triangle({0, 2, 3}, {0, 2, 3}, {0, 2, 3}, 2), {Triangle({0, 0, 6}, {5, 0, 6}, {2, 3, 6}, 1), Triangle({0, 2, 3}, {0, 2, 3}, {0, 2, 3}, 2)}},
// Point on vertex of triangle
UnionParams{Triangle({0, 0, 2}, {5,0,2}, {2,3,2}, 1), Triangle({0,0,0}, {0,0,0}, {0,0,0}, 2), {Triangle({0, 0, 2}, {5,0,2}, {2,3,2}, 1), Triangle({0,0,0}, {0,0,0}, {0,0,0}, 2)}},
// Line and Triangle
UnionParams{Triangle({0,0,5}, {5,0,5}, {2,3,5}, 1), Triangle({0,0,0}, {1,1,0}, {6,6,0}, 2), {Triangle({0,0,5}, {5,0,5}, {2,3,5}, 1), Triangle({0,0,0}, {1,1,0}, {6,6,0}, 2)}}
));
TEST(UnionEdgeTests, TriangleVertexOnEdge)
{
Triangle t1 = Triangle({}, {}, {}, 1);
Triangle t2 = Triangle({}, {}, {}, 2);
auto result = unionize(t1, t2);
}
TEST(UnionEdgeTests, TriangleEdgeLength0) {
Triangle t1 = Triangle({1,1}, {2,2}, {3,3}, 1, 1);
Triangle t2 = Triangle({}, {}, {}, 2, 2);
TEST(UnionEdgeTests, TriangleIsPoint)
{
Triangle t1 = Triangle({1, 1, 2}, {2, 2, 2}, {3, 3, 2}, 1);
Triangle t2 = Triangle({2, 2, 1}, {2, 2, 1}, {2, 2, 1}, 2);
auto results = unionize(t1, t2);
std::vector<Triangle> expected = {
Triangle({1, 1, 2}, {2, 2, 2}, {3, 3, 2}, 1),
Triangle({2, 2, 1}, {2, 2, 1}, {2, 2, 1}, 2)};
EXPECT_EQ(results, expected);
}
TEST(UnionEdgeTests, TriangleOnSide) {
Triangle t1 = Triangle({}, {}, {}, 1, 1);
Triangle t2 = Triangle({}, {}, {}, 2, 2);
TEST(UnionEdgeTests, TriangleOnSide)
{
Triangle t1 = Triangle({0, 0, 1}, {0, 5, 1}, {2, 3, 1}, 1);
Triangle t2 = Triangle({0, 1}, {1, 1}, {0, 3}, 2);
auto results = unionize(t1, t2);
std::vector<Triangle> expected = {
Triangle({0,0,1}, {0.666667,1,1}, {0,1,1}, 1),
Triangle({0,5,1}, {0,3,1}, {0.857143,1.28571,1}, 1),
Triangle({0,5,1}, {0.857143,1.28571,1}, {2,3,1}, 1),
Triangle({0,1,0}, {1,1,0}, {0,3,0}, 2)
};
EXPECT_EQ(results, expected);
}
#include <gtest/gtest.h>
#include <quad_tree.h>
/*
TEST (QuadTreeTest, OverlappingTriangles) {
TEST(QuadTreeTests, SimplePointQueryTest) {
QuadTree q({{10,10}, {0,0}});
QuadTree q{Box{0, 10, 0, 10}};
auto t1 = Triangle(Point{0,0}, Point{5,0}, Point{2,3}, 1);
auto t2 = Triangle(Point{0,0}, Point{5,0}, Point{2,3}, 2);
auto t3 = Triangle(Point{0,0}, Point{5,0}, Point{2,3}, 3);
auto t4 = Triangle(Point{0,0}, Point{5,0}, Point{2,3}, 4);
auto t5 = Triangle(Point{0,0}, Point{5,0}, Point{2,3}, 5);
Triangle t({0,0}, {5,0}, {2,3}, 42);
q.addTriangle(t);
Point p{1,1};
int id = q.pointIntersection(p);
EXPECT_EQ(id, t.mainTriangleId);
}
TEST (QuadTreeTests, NotInQueryPointTest) {
QuadTree q({{10,10}, {0,0}});
Triangle t({0,0}, {5,0}, {2,3});
Point p{9,9};
int id = q.pointIntersection(p);
EXPECT_EQ(id, POINT_NOT_IN_QUADTREE);
}
TEST (QuadTreeTests, OverlapTest) {
QuadTree q({{10,10}, {0,0}});
Triangle t1({0, 0, 0}, {5, 0, 0}, {2, 3, 0}, 1);
Triangle t2({3, 1, 1}, {6, 1, 1}, {4, 3, 1}, 2);
q.addTriangle(t1);
q.addTriangle(t2);
q.addTriangle(t3);
q.addTriangle(t4);
q.addTriangle(t5);
EXPECT_EQ(q.pointIntersection(Point{1,1}), 1);
Point p{1,1};
int id = q.pointIntersection(p);
EXPECT_EQ(id, t1.mainTriangleId);
}
TEST (QuadTreeTests, NonOverlappingTest) {
QuadTree q({{10,10}, {0,0}});
Triangle t1({0, 0, 0}, {5, 0, 0}, {2, 3, 0}, 1);
Triangle t2{{6, 0, 1}, {10, 0, 1}, {7, 5, 1}, 2};
q.addTriangle(t1);
q.addTriangle(t2);
}
*/
TEST (QuadTreeTest, SingleInsertion) {
QuadTree q{Box{0, 10, 0, 10}};
auto t1 = Triangle(Point{0,0}, Point{5,0}, Point{2,3}, 0);
TEST (QuadTreeTests, VisibleSurfaceTestNonOverlapping) {
auto t2 = Triangle(Point{3,1}, Point{6,1}, Point{4,3}, 0);
QuadTree q({{10,10}, {0,0}});
Triangle t1({0, 0, 0}, {5, 0, 0}, {2, 3, 0}, 1);
Triangle t2{{6, 0, 1}, {10, 0, 1}, {7, 5, 1}, 2};
q.addTriangle(t1);
q.addTriangle(t2);
EXPECT_TRUE(true);
auto surface = q.visibleSurface();
std::vector<Triangle> expected_surface {{{6,0,1}, {10, 0, 1}, {7, 5, 1}, 2}, {{0,0,0}, {5,0,0},{2,3,0}, 1}};
EXPECT_EQ(surface, expected_surface);
}
TEST (QuadTreeTest, PointOnTriangleQueryTest) {
QuadTree q{Box{0, 10, 0, 10}};
TEST (QuadTreeTests, NoVisibleSurfaceTest) {
QuadTree q({{1,1}, {0,0}});
auto surface = q.visibleSurface();
EXPECT_EQ(surface, std::vector<Triangle>{});
}
auto t1 = Triangle(Point{0,0}, Point{5,0}, Point{2,3}, 1, 1);
TEST (QuadTreeTests, FiveTrianglesTest) {
auto t2 = Triangle(Point{3,1}, Point{6,1}, Point{4,3}, 2, 2);
QuadTree q({{1,1}, {0,0}});
q.addTriangle(t1);
Triangle t1{{0,0,0}, {0,0,0}, {0,0,0}, 1};
Triangle t2{{0,0,0}, {0,0,0}, {0,0,0}, 1};
Triangle t3{{0,0,0}, {0,0,0}, {0,0,0}, 1};
Triangle t4{{0,0,0}, {0,0,0}, {0,0,0}, 1};
}
TEST (QuadTreeTests, DegenerateTrianglesTest) {
QuadTree q({{1,1}, {0,0}});
Triangle t1{{0,0,0}, {0,0,0}, {0,0,0}, 1};
Triangle t2{{0.2, 0.1, 1}, {0.2, 0.1, 1}, {0.3, 0.2, 1}, 2};
Triangle t3{{1,0,0}, {1,0,0}, {0,0,0}, 3};
q.addTriangle(t3);
q.addTriangle(t2);
q.addTriangle(t1);
auto surface = q.visibleSurface();
EXPECT_EQ(q.pointIntersection(Point{1,1}), 1);
EXPECT_EQ(q.pointIntersection(Point{5,1.5}), 2);
EXPECT_EQ(q.pointIntersection(Point{3.5, 1.5}), 1);
EXPECT_EQ(q.pointIntersection(Point{-1,-1}), POINT_NOT_IN_QUADTREE);
std::vector<Triangle> expected_surface {t1, t3, t2};
EXPECT_EQ(surface, expected_surface);
}
TEST (QuadTreeTests, StackingPointsTest) {
}
TEST (QuadTreeTests, TriangleCompletelyCoversOthers) {
QuadTree q({{1,1}, {0,0}});
Triangle t1{{0,0.1,10}, {0.234, 0.3, 9}, {0.1, 0.5, 9}, 1};
Triangle cover{{-100,-100,0}, {100,-1000,0}, {25, 50,0}, 100};
q.addTriangle(t1);
q.addTriangle(cover);
std::vector<Triangle> expected {cover};
EXPECT_EQ(q.visibleSurface(), expected);
}
\ No newline at end of file
#include <gtest/gtest.h>
#include <triangle.h>
#include <union.h>
class RandomizedUnionTests {
public testing::TestWithParam<>
};
float triangleArea() {
}
TEST_P(RandomizedUnionTests, RandomTest)
{
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 = {
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);
}
\ No newline at end of file
......@@ -3,8 +3,8 @@
#include <union.h>
TEST (UnionNeighbourTests, NeighbourTest) {
Triangle t1 = Triangle({}, {}, {}, 1, 1, {2});
Triangle t2 = Triangle({}, {}, {}, 2, 2, {1});
Triangle t1 = Triangle({}, {}, {}, 1, {2});
Triangle t2 = Triangle({}, {}, {}, 2, {1});
auto results = unionize(t1, t2);
std::vector<Triangle> expected ={t1, t2} ;
......
......@@ -2,6 +2,13 @@
#include <union.h>
#include <triangle.h>
#include <orientation.h>
#include <shift_triangle.h>
#include "union_tests.h"
std::ostream &operator<<(std::ostream &os, const UnionParams &u) {
os << u.t1 << "|" << u.t2;
return os;
}
TEST(UnionTrivialTests, NotTouching)
{
......@@ -16,123 +23,132 @@ TEST(UnionTrivialTests, NotTouching)
TEST(UnionTests, TwoIntersections)
{
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 t1 = Triangle(Point{0, 0, 0}, Point{5, 0, 0}, Point{2, 3, 0}, 1);
auto t2 = Triangle(Point{3, 1, 1}, Point{6, 1, 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, 2),
Triangle({4,3}, {3.33333,1.66667}, {4,1}, 1,2),
Triangle({0,0}, {5,0}, {2,3}, 0, 1)};
Triangle({6,1,1}, {4,3,1}, {3.333333,1.66666,1}, 2),
Triangle({6,1,1}, {3.33333,1.66667,1}, {4,1,1},2),
Triangle({0,0}, {5,0}, {2,3}, 1)};
EXPECT_EQ(ts, expected);
}
// Edge Case
/*
TEST(UnionTests, SharesPointTest)
{
// Case 1 t1 covers t2
Triangle bottom = Triangle({0, 5}, {3, 2}, {5, 3}, 1, 1);
Triangle top = Triangle({0.1, 7}, {5, 3}, {3.2, 9}, 2, 2);
Triangle top = Triangle({0, 5}, {3, 2}, {5, 3}, 1);
Triangle bottom = Triangle({0.1, 7, 5}, {5, 3,5}, {3.2, 9,5}, 2);
auto results = unionize(bottom, top);
std::vector<Triangle> expected_results_1;
std::vector<Triangle> expected_results_1 = {
Triangle({0.1, 7, 5}, {5, 3,5}, {3.2, 9,5}, 2),
Triangle({0, 5}, {3, 2}, {5, 3}, 1)
};
EXPECT_EQ(results, expected_results_1);
// Case 2 t2 covers t1
bottom.depth = 3;
shiftZ(top, 10);
results = unionize(bottom, top);
std::vector<Triangle> expected_results_2;
std::vector<Triangle> expected_results_2 {
Triangle({0, 5, 10}, {3, 2, 10}, {5, 3, 10}, 1),
Triangle({0.1, 7, 5}, {5, 3,5}, {3.2, 9,5}, 2)
};
EXPECT_EQ(results, expected_results_2);
}*/
}
TEST(UnionTests, FoldTriangleTest)
{
Triangle top = Triangle({0, 5}, {3, 2}, {5, 3}, 1, 1);
Triangle bottom = Triangle({0.1, 9}, {2, 4}, {5,5}, 2, 2);
Triangle top = Triangle({0, 5}, {3, 2}, {5, 3}, 1);
Triangle bottom = Triangle({0.1, 9,1}, {2, 4,1}, {5,5,1}, 2);
auto results = unionize(bottom, top);
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)
Triangle({0.1,9,1}, {1.91038,4.23585,1}, {2.27273,4.09091,1}, 2),
Triangle({0.1,9,1}, {2.27273,4.09091,1}, {5,5,1}, 2),
Triangle({0,5,0}, {3,2,0}, {5,3,0}, 1)
};
EXPECT_EQ(results, expected_results_1);
top.depth = 3;
shiftZ(top, 3);
results = unionize(bottom, top);
std::vector<Triangle> expected_results_2 = {
Triangle({0,5}, {2.6129, 2.3871}, {1.91038, 4.23585}, 3, 1),
Triangle({3,2}, {5, 3}, {2.6129, 2.3871}, 3, 1),
Triangle({5,3}, {2.27273, 4.09091}, {2.6129, 2.3871}, 3, 1),
Triangle({2.27273,4.09091}, {2, 4}, {2.6129, 2.3871}, 3, 1),
Triangle({0.1,9}, {2, 4}, {5, 5}, 2, 2)
Triangle({0,5,3}, {2.6129,2.3871,3}, {1.91038,4.23585,3}, 1),
Triangle({3,2,3}, {5,3,3}, {2.27273,4.09091,3}, 1),
Triangle({3,2,3}, {2.27273,4.09091,3}, {2.6129,2.3871,3}, 1),
Triangle({2.6129,2.3871,3}, {2.27273,4.09091,3}, {2,4,3}, 1),
Triangle({0.1,9,1}, {2,4,1}, {5,5,1}, 2)
};
EXPECT_EQ(results, expected_results_2);
}
/*
TEST(UnionTests, IceCreamTest)
{
Triangle bottom = Triangle({0, 5}, {3, 2}, {5, 3}, 2, 1);
Triangle top = Triangle({-1, 5}, {2, 4}, {5, 7}, 1, 2);
auto results = unionize(bottom, top);
std::vector<Triangle> expected_results_1;
EXPECT_EQ(results, expected_results_1);
top.depth = 3;
results = unionize(bottom, top);
std::vector<Triangle> expected_results_2;
EXPECT_EQ(results, expected_results_2);
}*/
TEST(UnionTests, StarTest)
{
Triangle bottom = Triangle({0, 3}, {5, 3}, {2.5, 6}, 1, 1);
Triangle top = Triangle({0, 5}, {2, 0}, {5, 5}, 2, 2);
Triangle top = Triangle({0, 3,0}, {5, 3,0}, {2.5, 6,0}, 1);
Triangle bot = Triangle({0, 5, 1}, {2, 0, 1}, {5, 5, 1}, 2);
ASSERT_EQ(orientation(bottom.points[0], bottom.points[1], bottom.points[2]), Counterclockwise);
ASSERT_EQ(orientation(top.points[0], top.points[1], top.points[2]), Counterclockwise);
ASSERT_EQ(orientation(bot.points[0], bot.points[1], bot.points[2]), Counterclockwise);
auto results = unionize(bottom, top);
auto results = unionize(top, bot);
std::vector<Triangle> expected_results_1 = {
Triangle({2,0}, {3.8, 3}, {0.8, 3}, 2, 2),
Triangle({5,5}, {3.33333, 5}, {4.30233, 3.83721}, 2, 2),
Triangle({0,5}, {0.540541, 3.64865}, {1.66667, 5}, 2, 2),
Triangle({0, 3}, {5, 3}, {2.5, 6}, 1, 1)
Triangle({2,0,1}, {3.8, 3,1}, {0.8, 3, 1}, 2),
Triangle({5,5,1}, {3.33333, 5, 1}, {4.30233, 3.83721, 1}, 2),
Triangle({0,5,1}, {0.540541, 3.64865, 1}, {1.66667, 5, 1}, 2),
Triangle({0, 3}, {5, 3}, {2.5, 6}, 1)
};
EXPECT_EQ(results, expected_results_1);
bottom.depth = 3;
shiftZ(top, 3);
results = unionize(bottom, top);
results = unionize(top, bot);
std::vector<Triangle> expected_results_2 = {
Triangle({0,3}, {0.8,3}, {0.540541,3.64865}, 3, 1),
Triangle({5,3}, {4.30233,3.83721}, {3.8,3}, 3, 1),
Triangle({2.5,6}, {1.66667,5}, {3.33333,5}, 3, 1),
Triangle({0,5}, {2,0}, {5,5}, 2, 2)
Triangle({0,3,3}, {0.8,3,3}, {0.540541,3.64865,3}, 1),
Triangle({5,3,3}, {4.30233,3.83721,3}, {3.8,3,3}, 1),
Triangle({2.5,6,3}, {1.66667,5,3}, {3.33333,5,3}, 1),
Triangle({0,5, 1}, {2,0,1}, {5,5,1}, 2)
};
EXPECT_EQ(results, expected_results_2);
}
TEST_P(InstantiateUnionTests, UnionTest)
{
const Triangle &t1 = GetParam().t1;
const Triangle &t2 = GetParam().t2;
auto expected = GetParam().expected;
ASSERT_NE(orientation(t1), Clockwise);
ASSERT_NE(orientation(t2), Clockwise);
auto result = unionize(t1, t2);
EXPECT_EQ(result, expected);
}
INSTANTIATE_TEST_SUITE_P(ParameterizedUnionTests, InstantiateUnionTests, testing::Values(
UnionParams{Triangle({0, 0, 0}, {5, 0, 0}, {2, 3, 0}, 1), Triangle(Point{3, 1, 10}, Point{6, 1, 2}, Point{4, 3, 1}, 2),
{Triangle({6,1,2}, {4,3,1}, {3.333333,1.66666,7.23542}, 2),
Triangle({6,1,2}, {3.33333,1.66667,7.23542}, {4,1,7.3680},2),
Triangle({0,0}, {5,0}, {2,3}, 1)}}, UnionParams{Triangle({0,0.1,10}, {0.234, 0.3, 9}, {0.1, 0.5, 9}, 1), Triangle({-100, -100, 0}, {100, -100, 0}, {25, 50, 0}, 2), {Triangle({-100, -100}, {100, -100}, {25, 50}, 2)}}
));
\ No newline at end of file
#pragma once
#include <triangle.h>
struct UnionParams
{
Triangle t1;
Triangle t2;
std::vector<Triangle> expected;
};
class InstantiateUnionTests : public testing::TestWithParam<UnionParams>{};
std::ostream &operator<<(std::ostream &os, const UnionParams &u);
......@@ -4,14 +4,19 @@
#include <intersections.h>
TEST(ContourizeTest, Simple) {
std::vector<Point> points{{6,1}, {4,3}, {4, 1}, {3.3333, 1.6666}};
std::vector<Point> points{{0,0}, {5,0}, {2, 3}};
auto result = contourize(points);
std::vector<Point> expected{{4,1}, {3.3333,1.6666}, {4,3}, {6,1}};
std::vector<Point> expected{{0,0}, {5,0}, {2, 3}};
EXPECT_EQ(result, expected);
}
TEST (ContourizeTest, Collinear) {
std::vector<Point> points {{2,3,5}, {0,0,5}, {2.5,2.5,5}, {-0,0,5}};
auto result = contourize(points);
}
TEST(ContourizeTest, Triangle) {
std::vector<Point> points{{3,1}, {4,1}, {3.33333, 1.6666}};
......@@ -30,4 +35,4 @@ TEST(ContourizeTest, TestCase3) {
std::vector<Point> expected{{3,1}, {4,1}, {3.33333, 1.6666}};
EXPECT_EQ(result, expected);
}*/
\ No newline at end of file
}*/
......@@ -14,12 +14,12 @@ TEST(ConvexTriangulationTests, Simple) {
p1, p2, p3, p4, p5
};
auto results = convexTriangulation(points, 2, 2);
auto results = convexTriangulation(points, 2, std::make_shared<std::vector<int>>());
std::vector<Triangle> expected_result {
Triangle(p1, p2, p3, 2, 2),
Triangle(p1, p3, p5, 2, 2),
Triangle(p5, p3, p4, 2, 2)
Triangle(p1, p2, p3, 2),
Triangle(p1, p3, p5, 2),
Triangle(p5, p3, p4, 2)
};
EXPECT_EQ(results, expected_result);
......@@ -33,8 +33,8 @@ TEST(ConvexTriangulationTests, TrivialTriangle) {
{1.5, 2}
};
auto results = convexTriangulation(points, 1, 1);
Triangle expected_triangle = Triangle({0,0}, {2,0}, {1.5, 2}, 1, 1);
auto results = convexTriangulation(points, 1, std::make_shared<std::vector<int>>());
Triangle expected_triangle = Triangle({0,0}, {2,0}, {1.5, 2}, 1);
EXPECT_EQ(results.size(), 1);
EXPECT_EQ(results[0], expected_triangle);
......