Add function IsDelaunay to check if results are valid

This commit is contained in:
Jan Niklas Hasse 2019-02-21 14:42:20 +01:00
parent 96b08ee75c
commit 0898bb217d
3 changed files with 89 additions and 12 deletions

View File

@ -389,4 +389,21 @@ bool Triangle::IsCounterClockwise() const
0;
}
bool IsDelaunay(const std::vector<p2t::Triangle*>& triangles)
{
for (const auto triangle : triangles) {
for (const auto other : triangles) {
if (triangle == other) {
continue;
}
for (int i = 0; i < 3; ++i) {
if (triangle->CircumcicleContains(*other->GetPoint(i))) {
return false;
}
}
}
}
return true;
}
}

View File

@ -324,6 +324,9 @@ inline void Triangle::IsInterior(bool b)
interior_ = b;
}
/// Is this set a valid delaunay triangulation?
bool IsDelaunay(const std::vector<p2t::Triangle*>&);
}
#endif

View File

@ -2,18 +2,75 @@
#define BOOST_TEST_MODULE Poly2triTest
#include <boost/test/unit_test.hpp>
#include <poly2tri/poly2tri.h>
#include <fstream>
#include <iostream>
BOOST_AUTO_TEST_CASE(BasicTest) {
BOOST_AUTO_TEST_CASE(BasicTest)
{
std::vector<p2t::Point*> polyline{
new p2t::Point(0, 0), new p2t::Point(1, 0), new p2t::Point(1, 1),
new p2t::Point(0, 0),
new p2t::Point(1, 0),
new p2t::Point(1, 1),
};
p2t::CDT cdt{polyline};
p2t::CDT cdt{ polyline };
cdt.Triangulate();
const auto result = cdt.GetTriangles();
assert(result.size() == 1);
BOOST_REQUIRE_EQUAL(result.size(), 1);
BOOST_CHECK_EQUAL(*result[0]->GetPoint(0), *polyline[0]);
BOOST_CHECK_EQUAL(*result[0]->GetPoint(1), *polyline[1]);
BOOST_CHECK_EQUAL(*result[0]->GetPoint(2), *polyline[2]);
result[0]->DebugPrint();
BOOST_CHECK(p2t::IsDelaunay(result));
for (const auto p : polyline) {
delete p;
}
}
BOOST_AUTO_TEST_CASE(QuadTest)
{
std::vector<p2t::Point*> polyline{ new p2t::Point(0, 0), new p2t::Point(0, 1),
new p2t::Point(1, 1), new p2t::Point(1, 0) };
p2t::CDT cdt{ polyline };
cdt.Triangulate();
const auto result = cdt.GetTriangles();
BOOST_REQUIRE_EQUAL(result.size(), 2);
BOOST_CHECK(p2t::IsDelaunay(result));
for (const auto p : polyline) {
delete p;
}
}
BOOST_AUTO_TEST_CASE(TestbedFilesTest)
{
for (const auto& filename : { "custom.dat", "diamond.dat", "star.dat", "test.dat" }) {
std::vector<p2t::Point*> polyline;
// Load pointset from file
// Parse and tokenize data file
std::string line;
std::ifstream myfile(std::string("../testbed/data/") + filename);
if (!myfile.is_open()) {
myfile.open(std::string("testbed/data/") + filename);
}
BOOST_REQUIRE(myfile.is_open());
while (!myfile.eof()) {
getline(myfile, line);
if (line.empty()) {
break;
}
std::istringstream iss(line);
std::vector<std::string> tokens;
copy(std::istream_iterator<std::string>(iss), std::istream_iterator<std::string>(),
std::back_inserter<std::vector<std::string>>(tokens));
double x = std::stod(tokens[0]);
double y = std::stod(tokens[1]);
polyline.push_back(new p2t::Point(x, y));
}
p2t::CDT cdt{ polyline };
cdt.Triangulate();
const auto result = cdt.GetTriangles();
BOOST_REQUIRE(result.size() * 3 > polyline.size());
BOOST_CHECK_MESSAGE(p2t::IsDelaunay(result), filename + std::to_string(polyline.size()));
for (const auto p : polyline) {
delete p;
}
}
}