Triangles: some cleanup

This commit is contained in:
Matthias Koefferlein 2023-08-19 19:24:56 +02:00
parent 18a3c53c2d
commit dfe6699ef9
5 changed files with 161 additions and 134 deletions

View File

@ -76,7 +76,7 @@ public:
/** /**
* @brief Returns 1 is the point is inside the circle, 0 if on the circle and -1 if outside * @brief Returns 1 is the point is inside the circle, 0 if on the circle and -1 if outside
* @@@ TODO: Move to db::DPoint * TODO: Move to db::DPoint
*/ */
static int in_circle (const db::DPoint &point, const db::DPoint &center, double radius); static int in_circle (const db::DPoint &point, const db::DPoint &center, double radius);
@ -159,6 +159,7 @@ public:
}; };
TriangleEdge (); TriangleEdge ();
TriangleEdge (Vertex *v1, Vertex *v2);
Vertex *v1 () const { return mp_v1; } Vertex *v1 () const { return mp_v1; }
Vertex *v2 () const { return mp_v2; } Vertex *v2 () const { return mp_v2; }
@ -166,11 +167,7 @@ public:
void reverse () void reverse ()
{ {
std::swap (mp_v1, mp_v2); std::swap (mp_v1, mp_v2);
std::swap (mp_left, mp_right);
Triangle *l = mp_left;
Triangle *r = mp_right;
mp_left = r;
mp_right = l;
} }
Triangle *left () const { return mp_left; } Triangle *left () const { return mp_left; }
@ -209,7 +206,7 @@ public:
* @brief Returns the distance of the given point to the edge * @brief Returns the distance of the given point to the edge
* *
* The distance is the minimum distance of the point to one point from the edge. * The distance is the minimum distance of the point to one point from the edge.
* @@@ TODO: Move to db::DEdge * TODO: Move to db::DEdge
*/ */
static double distance (const db::DEdge &e, const db::DPoint &p); static double distance (const db::DEdge &e, const db::DPoint &p);
@ -228,7 +225,7 @@ public:
* *
* "crosses" is true, if both edges share at least one point which is not an endpoint * "crosses" is true, if both edges share at least one point which is not an endpoint
* of one of the edges. * of one of the edges.
* @@@ TODO: Move to db::DEdge * TODO: Move to db::DEdge
*/ */
static bool crosses (const db::DEdge &e, const db::DEdge &other); static bool crosses (const db::DEdge &e, const db::DEdge &other);
@ -257,7 +254,7 @@ public:
/** /**
* @brief Returns a value indicating whether this edge crosses the other one * @brief Returns a value indicating whether this edge crosses the other one
* "crosses" is true, if both edges share at least one point. * "crosses" is true, if both edges share at least one point.
* @@@ TODO: Move to db::DEdge * TODO: Move to db::DEdge
*/ */
static bool crosses_including (const db::DEdge &e, const db::DEdge &other); static bool crosses_including (const db::DEdge &e, const db::DEdge &other);
@ -281,7 +278,7 @@ public:
/** /**
* @brief Gets the intersection point * @brief Gets the intersection point
* @@@ TODO: Move to db::DEdge * TODO: Move to db::DEdge
*/ */
static db::DPoint intersection_point (const db::DEdge &e, const DEdge &other); static db::DPoint intersection_point (const db::DEdge &e, const DEdge &other);
@ -303,7 +300,7 @@ public:
/** /**
* @brief Returns a value indicating whether the point is on the edge * @brief Returns a value indicating whether the point is on the edge
* @@@ TODO: Move to db::DEdge * TODO: Move to db::DEdge
*/ */
static bool point_on (const db::DEdge &edge, const db::DPoint &point); static bool point_on (const db::DEdge &edge, const db::DPoint &point);
@ -319,7 +316,7 @@ public:
* @brief Gets the side the point is on * @brief Gets the side the point is on
* *
* -1 is for "left", 0 is "on" and +1 is "right" * -1 is for "left", 0 is "on" and +1 is "right"
* @@@ TODO: correct to same definition as db::Edge (negative) * TODO: correct to same definition as db::Edge (negative)
*/ */
static int side_of (const db::DEdge &e, const db::DPoint &point) static int side_of (const db::DEdge &e, const db::DPoint &point)
{ {
@ -330,7 +327,7 @@ public:
* @brief Gets the side the point is on * @brief Gets the side the point is on
* *
* -1 is for "left", 0 is "on" and +1 is "right" * -1 is for "left", 0 is "on" and +1 is "right"
* @@@ TODO: correct to same definition as db::Edge (negative) * TODO: correct to same definition as db::Edge (negative)
*/ */
int side_of (const db::DPoint &p) const int side_of (const db::DPoint &p) const
{ {
@ -390,10 +387,7 @@ public:
*/ */
bool has_triangle (const Triangle *t) const; bool has_triangle (const Triangle *t) const;
// --- exposed for test purposes only --- protected:
TriangleEdge (Vertex *v1, Vertex *v2);
void unlink (); void unlink ();
void link (); void link ();

View File

@ -42,7 +42,7 @@ Triangles::Triangles ()
Triangles::~Triangles () Triangles::~Triangles ()
{ {
while (! mp_triangles.empty ()) { while (! mp_triangles.empty ()) {
remove (mp_triangles.begin ().operator-> ()); remove_triangle (mp_triangles.begin ().operator-> ());
} }
} }
@ -89,7 +89,7 @@ Triangles::create_triangle (TriangleEdge *e1, TriangleEdge *e2, TriangleEdge *e3
} }
void void
Triangles::remove (db::Triangle *tri) Triangles::remove_triangle (db::Triangle *tri)
{ {
db::TriangleEdge *edges [3]; db::TriangleEdge *edges [3];
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
@ -627,7 +627,7 @@ Triangles::split_triangle (db::Triangle *t, db::Vertex *vertex, std::list<tl::we
new_triangles.push_back (new_triangle); new_triangles.push_back (new_triangle);
} }
remove (t); remove_triangle (t);
fix_triangles (new_triangles, new_edges, new_triangles_out); fix_triangles (new_triangles, new_edges, new_triangles_out);
} }
@ -670,7 +670,7 @@ Triangles::split_triangles_on_edge (const std::vector<db::Triangle *> &tris, db:
} }
for (auto t = tris.begin (); t != tris.end (); ++t) { for (auto t = tris.begin (); t != tris.end (); ++t) {
remove (*t); remove_triangle (*t);
} }
std::vector<db::TriangleEdge *> fixed_edges; std::vector<db::TriangleEdge *> fixed_edges;
@ -738,7 +738,7 @@ Triangles::remove_outside_vertex (db::Vertex *vertex, std::list<tl::weak_ptr<db:
auto new_triangles = fill_concave_corners (outer_edges); auto new_triangles = fill_concave_corners (outer_edges);
for (auto t = to_remove.begin (); t != to_remove.end (); ++t) { for (auto t = to_remove.begin (); t != to_remove.end (); ++t) {
remove (*t); remove_triangle (*t);
} }
fix_triangles (new_triangles, std::vector<db::TriangleEdge *> (), new_triangles_out); fix_triangles (new_triangles, std::vector<db::TriangleEdge *> (), new_triangles_out);
@ -831,7 +831,7 @@ Triangles::remove_inside_vertex (db::Vertex *vertex, std::list<tl::weak_ptr<db::
for (auto t = to_remove.begin (); t != to_remove.end (); ++t) { for (auto t = to_remove.begin (); t != to_remove.end (); ++t) {
triangles_to_fix.erase (*t); triangles_to_fix.erase (*t);
remove (*t); remove_triangle (*t);
} }
if (new_triangles_out) { if (new_triangles_out) {
@ -890,7 +890,7 @@ Triangles::fix_triangles (const std::vector<db::Triangle *> &tris, const std::ve
} }
++m_flips; ++m_flips;
tl_assert (! is_illegal_edge (s12)); // @@@ remove later! tl_assert (! is_illegal_edge (s12)); // TODO: remove later!
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
db::TriangleEdge *s1 = t1->edge (i); db::TriangleEdge *s1 = t1->edge (i);
@ -963,8 +963,8 @@ Triangles::flip (TriangleEdge *edge)
db::Triangle *t2_new = create_triangle (s_new, t1_sext2, t2_sext2); db::Triangle *t2_new = create_triangle (s_new, t1_sext2, t2_sext2);
t2_new->set_outside (outside); t2_new->set_outside (outside);
remove (t1); remove_triangle (t1);
remove (t2); remove_triangle (t2);
return std::make_pair (std::make_pair (t1_new, t2_new), s_new); return std::make_pair (std::make_pair (t1_new, t2_new), s_new);
} }
@ -1292,8 +1292,8 @@ Triangles::join_edges (std::vector<db::TriangleEdge *> &edges)
t2->unlink (); t2->unlink ();
db::Triangle *tri = create_triangle (tedge1, tedge2, new_edge); db::Triangle *tri = create_triangle (tedge1, tedge2, new_edge);
tri->set_outside (t1->is_outside ()); tri->set_outside (t1->is_outside ());
remove (t1); remove_triangle (t1);
remove (t2); remove_triangle (t2);
} }
edges [i - 1] = new_edge; edges [i - 1] = new_edge;
@ -1398,7 +1398,7 @@ Triangles::remove_outside_triangles ()
} }
for (auto t = to_remove.begin (); t != to_remove.end (); ++t) { for (auto t = to_remove.begin (); t != to_remove.end (); ++t) {
remove (*t); remove_triangle (*t);
} }
} }
@ -1494,8 +1494,8 @@ Triangles::triangulate (const db::Region &region, const TriangulateParameters &p
new_triangles.push_back (t.operator-> ()); new_triangles.push_back (t.operator-> ());
} }
// @@@ TODO: break if iteration gets stuck // TODO: break if iteration gets stuck
while (nloop < parameters.max_iterations) { // @@@ while (nloop < parameters.max_iterations) {
++nloop; ++nloop;
if (tl::verbosity () >= parameters.base_verbosity + 10) { if (tl::verbosity () >= parameters.base_verbosity + 10) {

View File

@ -154,9 +154,23 @@ public:
*/ */
void triangulate (const db::Region &region, const TriangulateParameters &parameters, double dbu = 1.0); void triangulate (const db::Region &region, const TriangulateParameters &parameters, double dbu = 1.0);
/**
* @brief Statistics: number of flips (fixing)
*/
size_t flips () const
{
return m_flips;
}
// -- exposed for testing purposes -- /**
* @brief Statistics: number of hops (searching)
*/
size_t hops () const
{
return m_hops;
}
protected:
/** /**
* @brief Checks the triangle graph for consistency * @brief Checks the triangle graph for consistency
* This method is for testing purposes mainly. * This method is for testing purposes mainly.
@ -262,22 +276,6 @@ public:
*/ */
static bool is_illegal_edge (db::TriangleEdge *edge); static bool is_illegal_edge (db::TriangleEdge *edge);
/**
* @brief Statistics: number of flips (fixing)
*/
size_t flips () const
{
return m_flips;
}
/**
* @brief Statistics: number of hops (searching)
*/
size_t hops () const
{
return m_hops;
}
// NOTE: these functions are SLOW and intended to test purposes only // NOTE: these functions are SLOW and intended to test purposes only
std::vector<db::Vertex *> find_touching (const db::DBox &box) const; std::vector<db::Vertex *> find_touching (const db::DBox &box) const;
std::vector<db::Vertex *> find_inside_circle (const db::DPoint &center, double radius) const; std::vector<db::Vertex *> find_inside_circle (const db::DPoint &center, double radius) const;
@ -296,7 +294,7 @@ private:
db::Vertex *create_vertex (const db::DPoint &pt); db::Vertex *create_vertex (const db::DPoint &pt);
db::TriangleEdge *create_edge (db::Vertex *v1, db::Vertex *v2); db::TriangleEdge *create_edge (db::Vertex *v1, db::Vertex *v2);
db::Triangle *create_triangle (db::TriangleEdge *e1, db::TriangleEdge *e2, db::TriangleEdge *e3); db::Triangle *create_triangle (db::TriangleEdge *e1, db::TriangleEdge *e2, db::TriangleEdge *e3);
void remove (db::Triangle *tri); void remove_triangle (db::Triangle *tri);
void remove_outside_vertex (db::Vertex *vertex, std::list<tl::weak_ptr<db::Triangle> > *new_triangles = 0); void remove_outside_vertex (db::Vertex *vertex, std::list<tl::weak_ptr<db::Triangle> > *new_triangles = 0);
void remove_inside_vertex (db::Vertex *vertex, std::list<tl::weak_ptr<db::Triangle> > *new_triangles_out = 0); void remove_inside_vertex (db::Vertex *vertex, std::list<tl::weak_ptr<db::Triangle> > *new_triangles_out = 0);

View File

@ -26,6 +26,19 @@
#include <list> #include <list>
class TestableTriangleEdge
: public db::TriangleEdge
{
public:
using db::TriangleEdge::TriangleEdge;
using db::TriangleEdge::link;
using db::TriangleEdge::unlink;
TestableTriangleEdge (db::Vertex *v1, db::Vertex *v2)
: db::TriangleEdge (v1, v2)
{ }
};
// Tests for Vertex class // Tests for Vertex class
TEST(Vertex_basic) TEST(Vertex_basic)
@ -76,13 +89,13 @@ TEST(Vertex_edge_registration)
db::Vertex v2 (1, 2); db::Vertex v2 (1, 2);
db::Vertex v3 (2, 1); db::Vertex v3 (2, 1);
std::unique_ptr<db::TriangleEdge> e1 (new db::TriangleEdge (&v1, &v2)); std::unique_ptr<TestableTriangleEdge> e1 (new TestableTriangleEdge (&v1, &v2));
e1->link (); e1->link ();
EXPECT_EQ (edges_from_vertex (v1), "((0, 0), (1, 2))"); EXPECT_EQ (edges_from_vertex (v1), "((0, 0), (1, 2))");
EXPECT_EQ (edges_from_vertex (v2), "((0, 0), (1, 2))"); EXPECT_EQ (edges_from_vertex (v2), "((0, 0), (1, 2))");
EXPECT_EQ (edges_from_vertex (v3), ""); EXPECT_EQ (edges_from_vertex (v3), "");
std::unique_ptr<db::TriangleEdge> e2 (new db::TriangleEdge (&v2, &v3)); std::unique_ptr<TestableTriangleEdge> e2 (new TestableTriangleEdge (&v2, &v3));
e2->link (); e2->link ();
EXPECT_EQ (edges_from_vertex (v1), "((0, 0), (1, 2))"); EXPECT_EQ (edges_from_vertex (v1), "((0, 0), (1, 2))");
EXPECT_EQ (edges_from_vertex (v2), "((0, 0), (1, 2)), ((1, 2), (2, 1))"); EXPECT_EQ (edges_from_vertex (v2), "((0, 0), (1, 2)), ((1, 2), (2, 1))");
@ -109,11 +122,11 @@ TEST(Vertex_triangles)
db::Vertex v4 (-1, 2); db::Vertex v4 (-1, 2);
EXPECT_EQ (triangles_from_vertex (v1), ""); EXPECT_EQ (triangles_from_vertex (v1), "");
std::unique_ptr<db::TriangleEdge> e1 (new db::TriangleEdge (&v1, &v2)); std::unique_ptr<TestableTriangleEdge> e1 (new TestableTriangleEdge (&v1, &v2));
e1->link (); e1->link ();
std::unique_ptr<db::TriangleEdge> e2 (new db::TriangleEdge (&v2, &v3)); std::unique_ptr<TestableTriangleEdge> e2 (new TestableTriangleEdge (&v2, &v3));
e2->link (); e2->link ();
std::unique_ptr<db::TriangleEdge> e3 (new db::TriangleEdge (&v3, &v1)); std::unique_ptr<TestableTriangleEdge> e3 (new TestableTriangleEdge (&v3, &v1));
e3->link (); e3->link ();
std::unique_ptr<db::Triangle> tri (new db::Triangle (e1.get (), e2.get (), e3.get ())); std::unique_ptr<db::Triangle> tri (new db::Triangle (e1.get (), e2.get (), e3.get ()));
@ -121,9 +134,9 @@ TEST(Vertex_triangles)
EXPECT_EQ (triangles_from_vertex (v2), "((0, 0), (1, 2), (2, 1))"); EXPECT_EQ (triangles_from_vertex (v2), "((0, 0), (1, 2), (2, 1))");
EXPECT_EQ (triangles_from_vertex (v3), "((0, 0), (1, 2), (2, 1))"); EXPECT_EQ (triangles_from_vertex (v3), "((0, 0), (1, 2), (2, 1))");
std::unique_ptr<db::TriangleEdge> e4 (new db::TriangleEdge (&v1, &v4)); std::unique_ptr<TestableTriangleEdge> e4 (new TestableTriangleEdge (&v1, &v4));
e4->link (); e4->link ();
std::unique_ptr<db::TriangleEdge> e5 (new db::TriangleEdge (&v2, &v4)); std::unique_ptr<TestableTriangleEdge> e5 (new TestableTriangleEdge (&v2, &v4));
e5->link (); e5->link ();
std::unique_ptr<db::Triangle> tri2 (new db::Triangle (e1.get (), e4.get (), e5.get ())); std::unique_ptr<db::Triangle> tri2 (new db::Triangle (e1.get (), e4.get (), e5.get ()));
EXPECT_EQ (triangles_from_vertex (v1), "((0, 0), (-1, 2), (1, 2)), ((0, 0), (1, 2), (2, 1))"); EXPECT_EQ (triangles_from_vertex (v1), "((0, 0), (-1, 2), (1, 2)), ((0, 0), (1, 2), (2, 1))");
@ -146,9 +159,9 @@ TEST(Triangle_basic)
db::Vertex v2 (1, 2); db::Vertex v2 (1, 2);
db::Vertex v3 (2, 1); db::Vertex v3 (2, 1);
db::TriangleEdge s1 (&v1, &v2); TestableTriangleEdge s1 (&v1, &v2);
db::TriangleEdge s2 (&v2, &v3); TestableTriangleEdge s2 (&v2, &v3);
db::TriangleEdge s3 (&v3, &v1); TestableTriangleEdge s3 (&v3, &v1);
EXPECT_EQ (s1.v1 () == &v1, true); EXPECT_EQ (s1.v1 () == &v1, true);
EXPECT_EQ (s2.v2 () == &v3, true); EXPECT_EQ (s2.v2 () == &v3, true);
@ -161,9 +174,9 @@ TEST(Triangle_basic)
EXPECT_EQ (tri.edge (3) == &s1, true); EXPECT_EQ (tri.edge (3) == &s1, true);
// ordering // ordering
db::TriangleEdge s11 (&v1, &v2); TestableTriangleEdge s11 (&v1, &v2);
db::TriangleEdge s12 (&v3, &v2); TestableTriangleEdge s12 (&v3, &v2);
db::TriangleEdge s13 (&v1, &v3); TestableTriangleEdge s13 (&v1, &v3);
db::Triangle tri2 (&s11, &s12, &s13); db::Triangle tri2 (&s11, &s12, &s13);
EXPECT_EQ (tri2.to_string (), "((0, 0), (1, 2), (2, 1))"); EXPECT_EQ (tri2.to_string (), "((0, 0), (1, 2), (2, 1))");
@ -194,9 +207,9 @@ TEST(Triangle_find_segment_with)
db::Vertex v2 (1, 2); db::Vertex v2 (1, 2);
db::Vertex v3 (2, 1); db::Vertex v3 (2, 1);
db::TriangleEdge s1 (&v1, &v2); TestableTriangleEdge s1 (&v1, &v2);
db::TriangleEdge s2 (&v2, &v3); TestableTriangleEdge s2 (&v2, &v3);
db::TriangleEdge s3 (&v3, &v1); TestableTriangleEdge s3 (&v3, &v1);
db::Triangle tri (&s1, &s2, &s3); db::Triangle tri (&s1, &s2, &s3);
@ -210,9 +223,9 @@ TEST(Triangle_ext_vertex)
db::Vertex v2 (1, 2); db::Vertex v2 (1, 2);
db::Vertex v3 (2, 1); db::Vertex v3 (2, 1);
db::TriangleEdge s1 (&v1, &v2); TestableTriangleEdge s1 (&v1, &v2);
db::TriangleEdge s2 (&v2, &v3); TestableTriangleEdge s2 (&v2, &v3);
db::TriangleEdge s3 (&v3, &v1); TestableTriangleEdge s3 (&v3, &v1);
db::Triangle tri (&s1, &s2, &s3); db::Triangle tri (&s1, &s2, &s3);
@ -226,9 +239,9 @@ TEST(Triangle_opposite_vertex)
db::Vertex v2 (1, 2); db::Vertex v2 (1, 2);
db::Vertex v3 (2, 1); db::Vertex v3 (2, 1);
db::TriangleEdge s1 (&v1, &v2); TestableTriangleEdge s1 (&v1, &v2);
db::TriangleEdge s2 (&v2, &v3); TestableTriangleEdge s2 (&v2, &v3);
db::TriangleEdge s3 (&v3, &v1); TestableTriangleEdge s3 (&v3, &v1);
db::Triangle tri (&s1, &s2, &s3); db::Triangle tri (&s1, &s2, &s3);
@ -242,9 +255,9 @@ TEST(Triangle_opposite_edge)
db::Vertex v2 (1, 2); db::Vertex v2 (1, 2);
db::Vertex v3 (2, 1); db::Vertex v3 (2, 1);
db::TriangleEdge s1 (&v1, &v2); TestableTriangleEdge s1 (&v1, &v2);
db::TriangleEdge s2 (&v2, &v3); TestableTriangleEdge s2 (&v2, &v3);
db::TriangleEdge s3 (&v3, &v1); TestableTriangleEdge s3 (&v3, &v1);
db::Triangle tri (&s1, &s2, &s3); db::Triangle tri (&s1, &s2, &s3);
@ -258,9 +271,9 @@ TEST(Triangle_contains)
db::Vertex v2 (1, 2); db::Vertex v2 (1, 2);
db::Vertex v3 (2, 1); db::Vertex v3 (2, 1);
db::TriangleEdge s1 (&v1, &v2); TestableTriangleEdge s1 (&v1, &v2);
db::TriangleEdge s2 (&v2, &v3); TestableTriangleEdge s2 (&v2, &v3);
db::TriangleEdge s3 (&v3, &v1); TestableTriangleEdge s3 (&v3, &v1);
{ {
db::Triangle tri (&s1, &s2, &s3); db::Triangle tri (&s1, &s2, &s3);
@ -294,9 +307,9 @@ TEST(Triangle_circumcircle)
db::Vertex v2 (1, 2); db::Vertex v2 (1, 2);
db::Vertex v3 (2, 1); db::Vertex v3 (2, 1);
db::TriangleEdge s1 (&v1, &v2); TestableTriangleEdge s1 (&v1, &v2);
db::TriangleEdge s2 (&v2, &v3); TestableTriangleEdge s2 (&v2, &v3);
db::TriangleEdge s3 (&v3, &v1); TestableTriangleEdge s3 (&v3, &v1);
db::Triangle tri (&s1, &s2, &s3); db::Triangle tri (&s1, &s2, &s3);
@ -321,7 +334,7 @@ TEST(TriangleEdge_basic)
db::Vertex v1; db::Vertex v1;
db::Vertex v2 (1, 0.5); db::Vertex v2 (1, 0.5);
db::TriangleEdge edge (&v1, &v2); TestableTriangleEdge edge (&v1, &v2);
EXPECT_EQ (edge.to_string (), "((0, 0), (1, 0.5))"); EXPECT_EQ (edge.to_string (), "((0, 0), (1, 0.5))");
EXPECT_EQ (edge.is_segment (), false); EXPECT_EQ (edge.is_segment (), false);
@ -343,14 +356,14 @@ TEST(TriangleEdge_triangles)
db::Vertex v3 (2, 1); db::Vertex v3 (2, 1);
db::Vertex v4 (-1, 2); db::Vertex v4 (-1, 2);
std::unique_ptr<db::TriangleEdge> e1 (new db::TriangleEdge (&v1, &v2)); std::unique_ptr<TestableTriangleEdge> e1 (new TestableTriangleEdge (&v1, &v2));
std::unique_ptr<db::TriangleEdge> e2 (new db::TriangleEdge (&v2, &v3)); std::unique_ptr<TestableTriangleEdge> e2 (new TestableTriangleEdge (&v2, &v3));
std::unique_ptr<db::TriangleEdge> e3 (new db::TriangleEdge (&v3, &v1)); std::unique_ptr<TestableTriangleEdge> e3 (new TestableTriangleEdge (&v3, &v1));
std::unique_ptr<db::Triangle> tri (new db::Triangle (e1.get (), e2.get (), e3.get ())); std::unique_ptr<db::Triangle> tri (new db::Triangle (e1.get (), e2.get (), e3.get ()));
std::unique_ptr<db::TriangleEdge> e4 (new db::TriangleEdge (&v1, &v4)); std::unique_ptr<TestableTriangleEdge> e4 (new TestableTriangleEdge (&v1, &v4));
std::unique_ptr<db::TriangleEdge> e5 (new db::TriangleEdge (&v2, &v4)); std::unique_ptr<TestableTriangleEdge> e5 (new TestableTriangleEdge (&v2, &v4));
std::unique_ptr<db::Triangle> tri2 (new db::Triangle (e1.get (), e4.get (), e5.get ())); std::unique_ptr<db::Triangle> tri2 (new db::Triangle (e1.get (), e4.get (), e5.get ()));
EXPECT_EQ (e1->is_outside (), false); EXPECT_EQ (e1->is_outside (), false);
@ -382,7 +395,7 @@ TEST(TriangleEdge_side_of)
db::Vertex v1; db::Vertex v1;
db::Vertex v2 (1, 0.5); db::Vertex v2 (1, 0.5);
db::TriangleEdge edge (&v1, &v2); TestableTriangleEdge edge (&v1, &v2);
EXPECT_EQ (edge.to_string (), "((0, 0), (1, 0.5))"); EXPECT_EQ (edge.to_string (), "((0, 0), (1, 0.5))");
EXPECT_EQ (edge.side_of (db::Vertex (0, 0)), 0) EXPECT_EQ (edge.side_of (db::Vertex (0, 0)), 0)
@ -394,7 +407,7 @@ TEST(TriangleEdge_side_of)
db::Vertex v3 (1, 0); db::Vertex v3 (1, 0);
db::Vertex v4 (0, 1); db::Vertex v4 (0, 1);
db::TriangleEdge edge2 (&v3, &v4); TestableTriangleEdge edge2 (&v3, &v4);
EXPECT_EQ (edge2.side_of (db::Vertex(0.2, 0.2)), -1); EXPECT_EQ (edge2.side_of (db::Vertex(0.2, 0.2)), -1);
} }
@ -417,26 +430,26 @@ TEST(TriangleEdge_crosses)
{ {
VertexHeap heap; VertexHeap heap;
db::TriangleEdge s1 (heap.make_vertex (0, 0), heap.make_vertex (1, 0.5)); TestableTriangleEdge s1 (heap.make_vertex (0, 0), heap.make_vertex (1, 0.5));
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, -0.5), heap.make_vertex(1, -0.5))), false); EXPECT_EQ (s1.crosses (TestableTriangleEdge (heap.make_vertex (-1, -0.5), heap.make_vertex(1, -0.5))), false);
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0), heap.make_vertex(1, 0))), false); // only cuts EXPECT_EQ (s1.crosses (TestableTriangleEdge (heap.make_vertex (-1, 0), heap.make_vertex(1, 0))), false); // only cuts
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.5), heap.make_vertex(1, 0.5))), false); EXPECT_EQ (s1.crosses (TestableTriangleEdge (heap.make_vertex (-1, 0.5), heap.make_vertex(1, 0.5))), false);
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.5), heap.make_vertex(2, 0.5))), false); EXPECT_EQ (s1.crosses (TestableTriangleEdge (heap.make_vertex (-1, 0.5), heap.make_vertex(2, 0.5))), false);
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.25), heap.make_vertex(2, 0.25))), true); EXPECT_EQ (s1.crosses (TestableTriangleEdge (heap.make_vertex (-1, 0.25), heap.make_vertex(2, 0.25))), true);
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.5), heap.make_vertex(-0.1, 0.5))), false); EXPECT_EQ (s1.crosses (TestableTriangleEdge (heap.make_vertex (-1, 0.5), heap.make_vertex(-0.1, 0.5))), false);
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 0.6), heap.make_vertex(0, 0.6))), false); EXPECT_EQ (s1.crosses (TestableTriangleEdge (heap.make_vertex (-1, 0.6), heap.make_vertex(0, 0.6))), false);
EXPECT_EQ (s1.crosses (db::TriangleEdge (heap.make_vertex (-1, 1), heap.make_vertex(1, 1))), false); EXPECT_EQ (s1.crosses (TestableTriangleEdge (heap.make_vertex (-1, 1), heap.make_vertex(1, 1))), false);
EXPECT_EQ (s1.crosses_including (db::TriangleEdge (heap.make_vertex (-1, -0.5), heap.make_vertex(1, -0.5))), false); EXPECT_EQ (s1.crosses_including (TestableTriangleEdge (heap.make_vertex (-1, -0.5), heap.make_vertex(1, -0.5))), false);
EXPECT_EQ (s1.crosses_including (db::TriangleEdge (heap.make_vertex (-1, 0), heap.make_vertex(1, 0))), true); // only cuts EXPECT_EQ (s1.crosses_including (TestableTriangleEdge (heap.make_vertex (-1, 0), heap.make_vertex(1, 0))), true); // only cuts
EXPECT_EQ (s1.crosses_including (db::TriangleEdge (heap.make_vertex (-1, 0.25), heap.make_vertex(2, 0.25))), true); EXPECT_EQ (s1.crosses_including (TestableTriangleEdge (heap.make_vertex (-1, 0.25), heap.make_vertex(2, 0.25))), true);
} }
TEST(TriangleEdge_point_on) TEST(TriangleEdge_point_on)
{ {
VertexHeap heap; VertexHeap heap;
db::TriangleEdge s1 (heap.make_vertex (0, 0), heap.make_vertex (1, 0.5)); TestableTriangleEdge s1 (heap.make_vertex (0, 0), heap.make_vertex (1, 0.5));
EXPECT_EQ (s1.point_on (db::DPoint (0, 0)), false); // endpoints are not "on" EXPECT_EQ (s1.point_on (db::DPoint (0, 0)), false); // endpoints are not "on"
EXPECT_EQ (s1.point_on (db::DPoint (0, -0.5)), false); EXPECT_EQ (s1.point_on (db::DPoint (0, -0.5)), false);
EXPECT_EQ (s1.point_on (db::DPoint (0.5, 0)), false); EXPECT_EQ (s1.point_on (db::DPoint (0.5, 0)), false);
@ -450,8 +463,8 @@ TEST(TriangleEdge_intersection_point)
{ {
VertexHeap heap; VertexHeap heap;
db::TriangleEdge s1 (heap.make_vertex (0, 0), heap.make_vertex (1, 0.5)); TestableTriangleEdge s1 (heap.make_vertex (0, 0), heap.make_vertex (1, 0.5));
EXPECT_EQ (s1.intersection_point (db::TriangleEdge (heap.make_vertex (-1, 0.25), heap.make_vertex (2, 0.25))).to_string (), "0.5,0.25"); EXPECT_EQ (s1.intersection_point (TestableTriangleEdge (heap.make_vertex (-1, 0.25), heap.make_vertex (2, 0.25))).to_string (), "0.5,0.25");
} }
TEST(TriangleEdge_can_flip) TEST(TriangleEdge_can_flip)
@ -460,11 +473,11 @@ TEST(TriangleEdge_can_flip)
db::Vertex v2 (0, 0); db::Vertex v2 (0, 0);
db::Vertex v3 (1, 0); db::Vertex v3 (1, 0);
db::Vertex v4 (0.5, 1); db::Vertex v4 (0.5, 1);
db::TriangleEdge s1 (&v1, &v2); TestableTriangleEdge s1 (&v1, &v2);
db::TriangleEdge s2 (&v1, &v3); TestableTriangleEdge s2 (&v1, &v3);
db::TriangleEdge s3 (&v2, &v3); TestableTriangleEdge s3 (&v2, &v3);
db::TriangleEdge s4 (&v2, &v4); TestableTriangleEdge s4 (&v2, &v4);
db::TriangleEdge s5 (&v3, &v4); TestableTriangleEdge s5 (&v3, &v4);
db::Triangle t1 (&s1, &s2, &s3); db::Triangle t1 (&s1, &s2, &s3);
db::Triangle t2 (&s3, &s4, &s5); db::Triangle t2 (&s3, &s4, &s5);
EXPECT_EQ (s3.left () == &t2, true); EXPECT_EQ (s3.left () == &t2, true);
@ -485,7 +498,7 @@ TEST(TriangleEdge_distance)
db::Vertex v1 (0, 0); db::Vertex v1 (0, 0);
db::Vertex v2 (1, 0); db::Vertex v2 (1, 0);
db::TriangleEdge seg (&v1, &v2); TestableTriangleEdge seg (&v1, &v2);
EXPECT_EQ (seg.distance (db::DPoint (0, 0)), 0); EXPECT_EQ (seg.distance (db::DPoint (0, 0)), 0);
EXPECT_EQ (seg.distance (db::DPoint (0, 1)), 1); EXPECT_EQ (seg.distance (db::DPoint (0, 1)), 1);
EXPECT_EQ (seg.distance (db::DPoint (1, 2)), 2); EXPECT_EQ (seg.distance (db::DPoint (1, 2)), 2);

View File

@ -32,9 +32,31 @@
#include <cstdlib> #include <cstdlib>
#include <cmath> #include <cmath>
class TestableTriangles
: public db::Triangles
{
public:
using db::Triangles::Triangles;
using db::Triangles::check;
using db::Triangles::dump;
using db::Triangles::flip;
using db::Triangles::insert_point;
using db::Triangles::search_edges_crossing;
using db::Triangles::find_edge_for_points;
using db::Triangles::find_points_around;
using db::Triangles::find_inside_circle;
using db::Triangles::create_constrained_delaunay;
using db::Triangles::is_illegal_edge;
using db::Triangles::find_vertex_for_point;
using db::Triangles::remove;
using db::Triangles::ensure_edge;
using db::Triangles::constrain;
using db::Triangles::remove_outside_triangles;
};
TEST(basic) TEST(basic)
{ {
db::Triangles tris; TestableTriangles tris;
tris.init_box (db::DBox (1, 0, 5, 4)); tris.init_box (db::DBox (1, 0, 5, 4));
EXPECT_EQ (tris.bbox ().to_string (), "(1,0;5,4)"); EXPECT_EQ (tris.bbox ().to_string (), "(1,0;5,4)");
@ -45,7 +67,7 @@ TEST(basic)
TEST(flip) TEST(flip)
{ {
db::Triangles tris; TestableTriangles tris;
tris.init_box (db::DBox (0, 0, 1, 1)); tris.init_box (db::DBox (0, 0, 1, 1));
EXPECT_EQ (tris.to_string (), "((0, 0), (0, 1), (1, 0)), ((0, 1), (1, 1), (1, 0))"); EXPECT_EQ (tris.to_string (), "((0, 0), (0, 1), (1, 0)), ((0, 1), (1, 1), (1, 0))");
@ -66,7 +88,7 @@ TEST(flip)
TEST(insert) TEST(insert)
{ {
db::Triangles tris; TestableTriangles tris;
tris.init_box (db::DBox (0, 0, 1, 1)); tris.init_box (db::DBox (0, 0, 1, 1));
tris.insert_point (0.2, 0.2); tris.insert_point (0.2, 0.2);
@ -76,7 +98,7 @@ TEST(insert)
TEST(split_segment) TEST(split_segment)
{ {
db::Triangles tris; TestableTriangles tris;
tris.init_box (db::DBox (0, 0, 1, 1)); tris.init_box (db::DBox (0, 0, 1, 1));
tris.insert_point (0.5, 0.5); tris.insert_point (0.5, 0.5);
@ -86,7 +108,7 @@ TEST(split_segment)
TEST(insert_vertex_twice) TEST(insert_vertex_twice)
{ {
db::Triangles tris; TestableTriangles tris;
tris.init_box (db::DBox (0, 0, 1, 1)); tris.init_box (db::DBox (0, 0, 1, 1));
tris.insert_point (0.5, 0.5); tris.insert_point (0.5, 0.5);
@ -98,7 +120,7 @@ TEST(insert_vertex_twice)
TEST(insert_vertex_convex) TEST(insert_vertex_convex)
{ {
db::Triangles tris; TestableTriangles tris;
tris.insert_point (0.2, 0.2); tris.insert_point (0.2, 0.2);
tris.insert_point (0.2, 0.8); tris.insert_point (0.2, 0.8);
tris.insert_point (0.6, 0.5); tris.insert_point (0.6, 0.5);
@ -110,7 +132,7 @@ TEST(insert_vertex_convex)
TEST(insert_vertex_convex2) TEST(insert_vertex_convex2)
{ {
db::Triangles tris; TestableTriangles tris;
tris.insert_point (0.25, 0.1); tris.insert_point (0.25, 0.1);
tris.insert_point (0.1, 0.4); tris.insert_point (0.1, 0.4);
tris.insert_point (0.4, 0.15); tris.insert_point (0.4, 0.15);
@ -121,7 +143,7 @@ TEST(insert_vertex_convex2)
TEST(insert_vertex_convex3) TEST(insert_vertex_convex3)
{ {
db::Triangles tris; TestableTriangles tris;
tris.insert_point (0.25, 0.5); tris.insert_point (0.25, 0.5);
tris.insert_point (0.25, 0.55); tris.insert_point (0.25, 0.55);
tris.insert_point (0.15, 0.8); tris.insert_point (0.15, 0.8);
@ -132,7 +154,7 @@ TEST(insert_vertex_convex3)
TEST(search_edges_crossing) TEST(search_edges_crossing)
{ {
db::Triangles tris; TestableTriangles tris;
db::Vertex *v1 = tris.insert_point (0.2, 0.2); db::Vertex *v1 = tris.insert_point (0.2, 0.2);
db::Vertex *v2 = tris.insert_point (0.2, 0.8); db::Vertex *v2 = tris.insert_point (0.2, 0.8);
db::Vertex *v3 = tris.insert_point (0.6, 0.5); db::Vertex *v3 = tris.insert_point (0.6, 0.5);
@ -169,7 +191,7 @@ TEST(illegal_edge1)
db::Triangle t2 (&ee1, &e2, &ee2); db::Triangle t2 (&ee1, &e2, &ee2);
EXPECT_EQ (db::Triangles::is_illegal_edge (&e2), true); EXPECT_EQ (TestableTriangles::is_illegal_edge (&e2), true);
} }
{ {
@ -185,7 +207,7 @@ TEST(illegal_edge1)
db::Triangle t2 (&ee1, &ee2, &e1); db::Triangle t2 (&ee1, &ee2, &e1);
EXPECT_EQ (db::Triangles::is_illegal_edge (&e2), false); EXPECT_EQ (TestableTriangles::is_illegal_edge (&e2), false);
} }
} }
@ -209,7 +231,7 @@ TEST(illegal_edge2)
db::Triangle t2 (&ee1, &ee2, &e2); db::Triangle t2 (&ee1, &ee2, &e2);
EXPECT_EQ (db::Triangles::is_illegal_edge (&e2), false); EXPECT_EQ (TestableTriangles::is_illegal_edge (&e2), false);
} }
{ {
@ -225,7 +247,7 @@ TEST(illegal_edge2)
db::Triangle t2 (&ee1, &ee2, &e1); db::Triangle t2 (&ee1, &ee2, &e1);
EXPECT_EQ (db::Triangles::is_illegal_edge (&e1), false); EXPECT_EQ (TestableTriangles::is_illegal_edge (&e1), false);
} }
} }
@ -249,7 +271,7 @@ TEST(insert_many)
{ {
srand (0); srand (0);
db::Triangles tris; TestableTriangles tris;
double res = 65536.0; double res = 65536.0;
db::DBox bbox; db::DBox bbox;
@ -274,7 +296,7 @@ TEST(heavy_insert)
srand (l); srand (l);
tl::info << "." << tl::noendl; tl::info << "." << tl::noendl;
db::Triangles tris; TestableTriangles tris;
double res = 128.0; double res = 128.0;
unsigned int n = rand () % 190 + 10; unsigned int n = rand () % 190 + 10;
@ -330,7 +352,7 @@ TEST(heavy_remove)
srand (l); srand (l);
tl::info << "." << tl::noendl; tl::info << "." << tl::noendl;
db::Triangles tris; TestableTriangles tris;
double res = 128.0; double res = 128.0;
unsigned int n = rand () % 190 + 10; unsigned int n = rand () % 190 + 10;
@ -379,7 +401,7 @@ TEST(ensure_edge)
{ {
srand (0); srand (0);
db::Triangles tris; TestableTriangles tris;
double res = 128.0; double res = 128.0;
db::DEdge ee[] = { db::DEdge ee[] = {
@ -445,7 +467,7 @@ TEST(constrain)
{ {
srand (0); srand (0);
db::Triangles tris; TestableTriangles tris;
double res = 128.0; double res = 128.0;
db::DEdge ee[] = { db::DEdge ee[] = {
@ -509,7 +531,7 @@ TEST(heavy_constrain)
srand (l); srand (l);
tl::info << "." << tl::noendl; tl::info << "." << tl::noendl;
db::Triangles tris; TestableTriangles tris;
double res = 128.0; double res = 128.0;
db::DEdge ee[] = { db::DEdge ee[] = {
@ -579,7 +601,7 @@ TEST(heavy_find_point_around)
srand (l); srand (l);
tl::info << "." << tl::noendl; tl::info << "." << tl::noendl;
db::Triangles tris; TestableTriangles tris;
double res = 128.0; double res = 128.0;
unsigned int n = rand () % 190 + 10; unsigned int n = rand () % 190 + 10;
@ -626,7 +648,7 @@ TEST(create_constrained_delaunay)
r -= r2; r -= r2;
db::Triangles tri; TestableTriangles tri;
tri.create_constrained_delaunay (r); tri.create_constrained_delaunay (r);
tri.remove_outside_triangles (); tri.remove_outside_triangles ();
@ -657,7 +679,7 @@ TEST(triangulate)
param.min_b = 1.2; param.min_b = 1.2;
param.max_area = 1.0; param.max_area = 1.0;
db::Triangles tri; TestableTriangles tri;
tri.triangulate (r, param, 0.001); tri.triangulate (r, param, 0.001);
EXPECT_EQ (tri.check (), true); EXPECT_EQ (tri.check (), true);
@ -773,7 +795,7 @@ TEST(triangulate2)
param.max_area = 0.1; param.max_area = 0.1;
param.min_length = 0.001; param.min_length = 0.001;
db::Triangles tri; TestableTriangles tri;
tri.triangulate (r, param, dbu); tri.triangulate (r, param, dbu);
EXPECT_EQ (tri.check (false), true); EXPECT_EQ (tri.check (false), true);
@ -831,13 +853,13 @@ TEST(triangulate3)
param.min_b = 1.0; param.min_b = 1.0;
param.max_area = 0.01; param.max_area = 0.01;
db::Triangles tri; TestableTriangles tri;
tri.triangulate (rg, param, dbu); tri.triangulate (rg, param, dbu);
EXPECT_EQ (tri.check (false), true); EXPECT_EQ (tri.check (false), true);
// for debugging: // for debugging:
tri.dump ("debug.gds"); // tri.dump ("debug.gds");
for (auto t = tri.begin (); t != tri.end (); ++t) { for (auto t = tri.begin (); t != tri.end (); ++t) {
EXPECT_LE (t->area (), param.max_area); EXPECT_LE (t->area (), param.max_area);