This commit is contained in:
Matthias Koefferlein 2023-08-12 16:21:10 +02:00
parent c93e490968
commit 14f8c1a61b
6 changed files with 252 additions and 20 deletions

View File

@ -134,6 +134,20 @@ TriangleEdge::TriangleEdge (Vertex *v1, Vertex *v2)
v2->m_edges.push_back (this);
}
void
TriangleEdge::set_left (Triangle *t)
{
tl_assert (left () == 0);
mp_left = t;
}
void
TriangleEdge::set_right (Triangle *t)
{
tl_assert (right () == 0);
mp_right = t;
}
Triangle *
TriangleEdge::other (const Triangle *t) const
{

View File

@ -167,8 +167,6 @@ public:
Triangle *left () const { return const_cast<Triangle *> (mp_left.get ()); }
Triangle *right () const { return const_cast<Triangle *> (mp_right.get ()); }
void set_left (Triangle *t) { mp_left = t; }
void set_right (Triangle *t) { mp_right = t; }
TriangleIterator begin_triangles () const
{
@ -382,6 +380,8 @@ public:
bool has_triangle (const Triangle *t) const;
private:
friend class Triangle;
Vertex *mp_v1, *mp_v2;
tl::weak_ptr<Triangle> mp_left, mp_right;
size_t m_level;
@ -390,6 +390,9 @@ private:
// no copying
TriangleEdge &operator= (const TriangleEdge &);
TriangleEdge (const TriangleEdge &);
void set_left (Triangle *t);
void set_right (Triangle *t);
};
/**

View File

@ -22,3 +22,171 @@
#include "dbTriangles.h"
namespace db
{
Triangles::Triangles ()
: m_is_constrained (false)
{
// .. nothing yet ..
}
Triangles::~Triangles ()
{
while (! mp_triangles.empty ()) {
remove (mp_triangles.front ());
}
tl_assert (mp_edges.empty ());
}
db::Vertex *
Triangles::create_vertex (double x, double y)
{
m_vertex_heap.push_back (db::Vertex (x, y));
return &m_vertex_heap.back ();
}
db::Vertex *
Triangles::create_vertex (const db::DPoint &pt)
{
m_vertex_heap.push_back (pt);
return &m_vertex_heap.back ();
}
db::TriangleEdge *
Triangles::create_edge (db::Vertex *v1, db::Vertex *v2)
{
db::TriangleEdge *res = new db::TriangleEdge (v1, v2);
mp_edges.push_back (res);
return res;
}
db::Triangle *
Triangles::create_triangle (TriangleEdge *e1, TriangleEdge *e2, TriangleEdge *e3)
{
db::Triangle *res = new db::Triangle (e1, e2, e3);
mp_triangles.push_back (res);
return res;
}
void
Triangles::remove (db::Triangle *tri)
{
db::TriangleEdge *edges [3];
for (int i = 0; i < 3; ++i) {
edges [i] = tri->edge (i);
}
delete tri;
// clean up edges we do no longer need
for (int i = 0; i < 3; ++i) {
if (edges [i]->left () == 0 && edges [i]->right () == 0) {
delete edges [i];
}
}
}
void
Triangles::init_box (const db::DBox &box)
{
double xmin = box.left (), xmax = box.right ();
double ymin = box.bottom (), ymax = box.top ();
db::Vertex *vbl = create_vertex (xmin, ymin);
db::Vertex *vtl = create_vertex (xmin, ymax);
db::Vertex *vbr = create_vertex (xmax, ymin);
db::Vertex *vtr = create_vertex (xmax, ymax);
db::TriangleEdge *sl = create_edge (vbl, vtl);
db::TriangleEdge *sd = create_edge (vtl, vbr);
db::TriangleEdge *sb = create_edge (vbr, vbl);
db::TriangleEdge *sr = create_edge (vbr, vtr);
db::TriangleEdge *st = create_edge (vtr, vtl);
create_triangle (sl, sd, sb);
create_triangle (sd, sr, st);
}
std::string
Triangles::to_string ()
{
}
db::DBox
Triangles::bbox () const
{
db::DBox box;
for (auto t = mp_triangles.begin (); t != mp_triangles.end (); ++t) {
for (int i = 0; i < 3; ++i) {
box += *t->vertex (i);
}
}
return box;
}
bool
Triangles::check (bool check_delaunay) const
{
}
std::vector<db::Vertex *>
Triangles::find_points_around (const db::Vertex *vertex, double radius)
{
}
db::Vertex *
Triangles::insert_point (const db::DPoint &point, std::vector<db::Triangle *> *new_triangles)
{
}
db::Vertex *
Triangles::insert (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles)
{
}
void
Triangles::remove (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles)
{
}
std::vector<db::Vertex *>
Triangles::find_touching (const db::DBox &box)
{
}
std::vector<db::Vertex *>
Triangles::find_inside_circle (const db::DPoint &center, double radius)
{
}
void
Triangles::remove_outside_vertex (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles)
{
}
void
Triangles::remove_inside_vertex (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles)
{
}
std::vector<db::Triangle *>
Triangles::fill_concave_corners (const std::vector<db::TriangleEdge> &edges)
{
}
}

View File

@ -26,12 +26,53 @@
#define HDR_dbTriangles
#include "dbCommon.h"
#include "dbTriangle.h"
#include "dbBox.h"
#include "tlObjectCollection.h"
namespace db
{
class DB_PUBLIC Triangles
{
public:
Triangles ();
~Triangles ();
void init_box (const db::DBox &box);
std::string to_string ();
db::DBox bbox () const;
bool check (bool check_delaunay = true) const;
std::vector<db::Vertex *> find_points_around (const db::Vertex *vertex, double radius);
db::Vertex *insert_point (const db::DPoint &point, std::vector<db::Triangle *> *new_triangles = 0);
db::Vertex *insert (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles = 0);
void remove (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles = 0);
private:
tl::shared_collection<db::Triangle> mp_triangles;
tl::weak_collection<db::TriangleEdge> mp_edges;
std::list<db::Vertex> m_vertex_heap;
bool m_is_constrained;
db::Vertex *create_vertex (double x, double y);
db::Vertex *create_vertex (const db::DPoint &pt);
db::TriangleEdge *create_edge (db::Vertex *v1, db::Vertex *v2);
db::Triangle *create_triangle (db::TriangleEdge *e1, db::TriangleEdge *e2, db::TriangleEdge *e3);
void remove (db::Triangle *tri);
// NOTE: these functions are SLOW and intended to test purposes only
std::vector<db::Vertex *> find_touching (const db::DBox &box);
std::vector<db::Vertex *> find_inside_circle (const db::DPoint &center, double radius);
void remove_outside_vertex (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles = 0);
void remove_inside_vertex (db::Vertex *vertex, std::vector<db::Triangle *> *new_triangles = 0);
std::vector<db::Triangle *> fill_concave_corners (const std::vector<db::TriangleEdge> &edges);
};
}

View File

@ -247,27 +247,30 @@ TEST(Triangle_contains)
db::TriangleEdge s2 (&v2, &v3);
db::TriangleEdge s3 (&v3, &v1);
db::Triangle tri (&s1, &s2, &s3);
EXPECT_EQ (tri.contains (db::DPoint (0, 0)), 0);
EXPECT_EQ (tri.contains (db::DPoint (-1, -2)), -1);
EXPECT_EQ (tri.contains (db::DPoint (0.5, 1)), 0);
EXPECT_EQ (tri.contains (db::DPoint (0.5, 2)), -1);
EXPECT_EQ (tri.contains (db::DPoint (2.5, 1)), -1);
EXPECT_EQ (tri.contains (db::DPoint (1, -1)), -1);
EXPECT_EQ (tri.contains (db::DPoint (1, 1)), 1);
{
db::Triangle tri (&s1, &s2, &s3);
EXPECT_EQ (tri.contains (db::DPoint (0, 0)), 0);
EXPECT_EQ (tri.contains (db::DPoint (-1, -2)), -1);
EXPECT_EQ (tri.contains (db::DPoint (0.5, 1)), 0);
EXPECT_EQ (tri.contains (db::DPoint (0.5, 2)), -1);
EXPECT_EQ (tri.contains (db::DPoint (2.5, 1)), -1);
EXPECT_EQ (tri.contains (db::DPoint (1, -1)), -1);
EXPECT_EQ (tri.contains (db::DPoint (1, 1)), 1);
}
s1.reverse ();
s2.reverse ();
s3.reverse ();
db::Triangle tri2 (&s3, &s2, &s1);
EXPECT_EQ (tri2.contains(db::DPoint(0, 0)), 0);
EXPECT_EQ (tri2.contains(db::DPoint(0.5, 1)), 0);
EXPECT_EQ (tri2.contains(db::DPoint(0.5, 2)), -1);
EXPECT_EQ (tri2.contains(db::DPoint(2.5, 1)), -1);
EXPECT_EQ (tri2.contains(db::DPoint(1, -1)), -1);
EXPECT_EQ (tri2.contains(db::DPoint(1, 1)), 1);
{
db::Triangle tri2 (&s3, &s2, &s1);
EXPECT_EQ (tri2.contains(db::DPoint(0, 0)), 0);
EXPECT_EQ (tri2.contains(db::DPoint(0.5, 1)), 0);
EXPECT_EQ (tri2.contains(db::DPoint(0.5, 2)), -1);
EXPECT_EQ (tri2.contains(db::DPoint(2.5, 1)), -1);
EXPECT_EQ (tri2.contains(db::DPoint(1, -1)), -1);
EXPECT_EQ (tri2.contains(db::DPoint(1, 1)), 1);
}
}
TEST(Triangle_circumcircle)
@ -445,8 +448,8 @@ TEST(TriangleEdge_can_flip)
db::TriangleEdge s5 (&v3, &v4);
db::Triangle t1 (&s1, &s2, &s3);
db::Triangle t2 (&s3, &s4, &s5);
s3.set_left (&t1);
s3.set_right (&t2);
EXPECT_EQ (s3.left () == &t2, true);
EXPECT_EQ (s3.right () == &t1, true);
EXPECT_EQ (s3.can_flip(), false);
v1.set_x (0.5);
EXPECT_EQ (s3.can_flip(), true);

View File

@ -26,5 +26,8 @@
TEST(1)
{
db::Triangles tris;
tris.init_box (db::DBox (1, 0, 5, 4));
EXPECT_EQ (tris.bbox ().to_string (), "(1,0;5,4)");
}