LIBRCSC Docs
Documentation for HELIOS's BASE LIBRCSC library for RoboCup 2D Simulation League.
All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
delaunay_triangulation.h
Go to the documentation of this file.
1// -*-c++-*-
2
8/*
9 *Copyright:
10
11 Copyright (C) Hidehisa AKIYAMA
12
13 This code is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 3 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26
27 *EndCopyright:
28 */
29
31
32#ifndef RCSC_GEOM_DELAUNAY_TRIANGULATION_H
33#define RCSC_GEOM_DELAUNAY_TRIANGULATION_H
34
35#include <rcsc/geom/rect_2d.h>
36#include <rcsc/geom/vector_2d.h>
37
38#include <algorithm>
39#include <unordered_map>
40#include <vector>
41#include <array>
42
43namespace rcsc {
44
50public:
51
52 static const double EPSILON;
53
55
60 NOT_CONTAINED,
61 CONTAINED,
62 ONLINE,
63 SAME_VERTEX,
64 };
65
67
71 class Vertex {
72 private:
73 int M_id;
74 Vector2D M_pos;
75
76 public:
81 : M_id( 0 )
82 { }
83
88 explicit
89 Vertex( const int id )
90 : M_id( id )
91 { }
92
96 virtual
98 { }
99
105 Vertex( const int id,
106 const Vector2D & p )
107 : M_id( id )
108 , M_pos( p )
109 { }
110
117 Vertex( const int id,
118 const double x,
119 const double y )
120 : M_id( id )
121 , M_pos( x, y )
122 { }
123
129 Vertex & assign( const int id,
130 const Vector2D & p )
131 {
132 M_id = id;
133 M_pos = p;
134 return *this;
135 }
136
143 Vertex & assign( const int id,
144 const double x,
145 const double y )
146 {
147 M_id = id;
148 M_pos.assign( x, y );
149 return *this;
150 }
151
156 int id() const
157 {
158 return M_id;
159 }
160
165 const
166 Vector2D & pos() const
167 {
168 return M_pos;
169 }
170 };
171
173
174 class Edge;
175 class Triangle;
176
177 typedef Edge* EdgePtr;
179
181
184 class Edge {
185 private:
186 const int M_id;
187 const Vertex * M_vertices[2];
188 TrianglePtr M_triangles[2];
189 public:
190
197 Edge( const int id,
198 const Vertex * v0,
199 const Vertex * v1 )
200 : M_id( id )
201 {
202 //std::cout << "Edge() id_" << id << " v0 " << v0 << " v1 " << v1
203 // << std::endl;
204 M_vertices[0] = v0;
205 M_vertices[1] = v1;
206 std::fill_n( M_triangles, 2, nullptr );
207 }
208
213 { }
214
221 {
222 if ( M_triangles[0] == tri )
223 {
224 //std::cout << "Edge::removeTriangle() edge_id_" << M_id
225 // << " remove tri_0 " << tri->id() << " "
226 // << tri << std::endl;
227 M_triangles[0] = nullptr;
228 }
229 if ( M_triangles[1] == tri )
230 {
231 //std::cout << "Edge::removeTriangle() edge_id_" << M_id
232 // << " remove tri_1 " << tri->id() << " "
233 // << tri << std::endl;
234 M_triangles[1] = nullptr;
235 }
236 }
237
248 {
249 if ( M_triangles[0] == tri ) return;
250 if ( M_triangles[1] == tri ) return;
251
252 if ( ! M_triangles[0] )
253 {
254 //std::cout << "Edge::setTriangle() edge_id_" << M_id
255 // << " set tri_0 " << tri->id() << " "
256 // << tri << std::endl;
257 M_triangles[0] = tri;
258 }
259 else if ( ! M_triangles[1] )
260 {
261 //std::cout << "Edge::setTriangle() edge_id_" << M_id
262 // << " set tri_1 " << tri->id() << " "
263 // << tri << std::endl;
264 M_triangles[1] = tri;
265 }
266 }
267
272 int id() const
273 {
274 return M_id;
275 }
276
282 const
283 Vertex * vertex( const std::size_t i ) const
284 {
285 return M_vertices[i];
286 }
287
293 Triangle * triangle( const std::size_t i ) const
294 {
295 return M_triangles[i];
296 }
297
303 bool hasVertex( const Vertex * v ) const
304 {
305 return ( M_vertices[0] == v
306 || M_vertices[1] == v );
307 }
308
309 };
310
312
315 class Triangle {
316 private:
317 int M_id;
318
320 std::array< const Vertex *, 3 > M_vertices;
322 std::array< EdgePtr, 3 > M_edges;
323
324 Vector2D M_circumcenter;
325 double M_circumradius;
326
327 Vector2D M_voronoi_vertex;
328
329 // not used
330 Triangle() = delete;
331 public:
332
342 Triangle( const int id,
343 EdgePtr e0,
344 EdgePtr e1,
345 EdgePtr e2 );
346
351 {
352 M_edges[0]->removeTriangle( this );
353 M_edges[1]->removeTriangle( this );
354 M_edges[2]->removeTriangle( this );
355 }
356
361
366 int id() const
367 {
368 return M_id;
369 }
370
376 const
377 Vertex * vertex( std::size_t i ) const
378 {
379 return M_vertices[i];
380 }
381
387 Edge * edge( std::size_t i ) const
388 {
389 return M_edges[i];
390 }
391
396 const
398 {
399 return M_circumcenter;
400 }
401
406 double circumradius() const
407 {
408 return M_circumradius;
409 }
410
415 const Vector2D & voronoiVertex() const
416 {
417 return M_voronoi_vertex;
418 }
419
425 bool contains( const Vector2D & pos ) const
426 {
427 return pos.dist2( M_circumcenter ) < M_circumradius * M_circumradius;
428 }
429
435 bool hasVertex( const Vertex * v ) const
436 {
437 return ( v == M_vertices[0]
438 || v == M_vertices[1]
439 || v == M_vertices[2] );
440 }
441
447 bool hasEdge( const EdgePtr e ) const
448 {
449 return ( M_edges[0] == e
450 || M_edges[1] == e
451 || M_edges[2] == e );
452 }
453
460 const
462 const Vertex * v2 ) const
463 {
464 for ( std::size_t i = 0; i < 3; ++i )
465 {
466 if ( M_vertices[i] != v1
467 && M_vertices[i] != v2 )
468 {
469 return M_vertices[i];
470 }
471 }
472 return nullptr;
473 }
474
480 const
481 Vertex * getVertexExclude( const Edge * edge ) const
482 {
483 return getVertexExclude( edge->vertex( 0 ),
484 edge->vertex( 1 ) );
485 }
486
494 const Vertex * v2 ) const
495 {
496 for ( std::size_t i = 0; i < 3; ++i )
497 {
498 if ( M_edges[i]->hasVertex( v1 )
499 && M_edges[i]->hasVertex( v2 ) )
500 {
501 return M_edges[i];
502 }
503 }
504 return nullptr;
505 }
506
512 Edge * getEdgeExclude( const Vertex * v ) const
513 {
514 for ( std::size_t i = 0; i < 3; ++i )
515 {
516 if ( ! M_edges[i]->hasVertex( v ) )
517 {
518 return M_edges[i];
519 }
520 }
521 return nullptr;
522 }
523
524 };
525
527
528 typedef std::vector< Vertex > VertexCont;
529 typedef std::unordered_map< int, EdgePtr > EdgeCont;
530 typedef std::unordered_map< int, TrianglePtr > TriangleCont;
531
532private:
533
535 int M_edge_count;
537 int M_tri_count;
538
540 Vertex M_initial_vertex[3];
541
543 EdgePtr M_initial_edge[3];
544
546 VertexCont M_vertices;
547
549 EdgeCont M_edges;
550
552 TriangleCont M_triangles;
553
554 // not used
555 DelaunayTriangulation & operator=( const DelaunayTriangulation & ) = delete;
556
557public:
558
563
570 explicit
572 {
573 //std::cout << "create with rect" << std::endl;
574 createInitialTriangle( region );
575 }
576
581
587 void init( const Rect2D & region )
588 {
589 clear();
590 createInitialTriangle( region );
591 }
592
596 void clear();
597
602
607 const
609 {
610 return M_vertices;
611 }
612
617 const
618 EdgeCont & edges() const
619 {
620 return M_edges;
621 }
622
627 const
629 {
630 return M_triangles;
631 }
632
639 int addVertex( const double x,
640 const double y );
641
647 int addVertex( const Vector2D & p )
648 {
649 return addVertex( p.x, p.y );
650 }
651
656 void addVertices( const std::vector< Vector2D > & v );
657
663 const
664 Vertex * getVertex( const int id ) const;
665
669 void compute();
670
675
681 const
682 Triangle * findTriangleContains( const Vector2D & pos ) const;
683
689 const
690 Vertex * findNearestVertex( const Vector2D & pos ) const;
691
692private:
693
698 void createInitialTriangle( const Rect2D & region );
699
703 void createInitialTriangle();
704
708 void removeInitialVertices();
709
715 bool updateContainedVertex( const Vertex * vertex,
716 const TrianglePtr tri );
717
724 bool updateOnlineVertex( const Vertex * vertex,
725 const TrianglePtr tri );
726
735 bool legalizeEdge( TrianglePtr new_tri,
736 const Vertex * new_vertex,
737 EdgePtr old_edge );
738
746 TrianglePtr * sol ) const;
747
752 void removeEdge( int id )
753 {
754 EdgeCont::iterator it = M_edges.find( id );
755 if ( it != M_edges.end() )
756 {
757 delete it->second;
758 M_edges.erase( it );
759 }
760 }
761
766 void removeEdge( Edge * edge )
767 {
768 if ( edge )
769 {
770 removeEdge( edge->id() );
771 }
772 }
773
778 void removeTriangle( int id )
779 {
780 TriangleCont::iterator it = M_triangles.find( id );
781 if ( it != M_triangles.end() )
782 {
783 //std::cout << "remove triangle " << id
784 // << it->second->vertex( 0 )->pos()
785 // << it->second->vertex( 1 )->pos()
786 // << it->second->vertex( 2 )->pos()
787 // << std::endl;
788 delete it->second;
789 M_triangles.erase( it );
790 }
791 }
792
797 void removeTriangle( TrianglePtr tri )
798 {
799 if ( tri )
800 {
801 removeTriangle( tri->id() );
802 }
803 }
804
811 EdgePtr createEdge( const Vertex * v0,
812 const Vertex * v1 )
813 {
814 EdgePtr ptr = new Edge( M_edge_count++, v0, v1 );
815 M_edges.insert( EdgeCont::value_type( ptr->id(), ptr ) );
816 return ptr;
817 }
818
826 TrianglePtr createTriangle( Edge * e0,
827 Edge * e1,
828 Edge * e2 )
829 {
830 // triangle is set to edges in the constructor of Triangle
831 TrianglePtr ptr = new Triangle( M_tri_count++, e0, e1, e2 );
832 M_triangles.insert( TriangleCont::value_type( ptr->id(), ptr ) );
833 return ptr;
834 }
835
836};
837
838}
839
840#endif
triangle's edge data.
Definition: delaunay_triangulation.h:184
Triangle * triangle(const std::size_t i) const
get the raw pointer to the triangle that this edge belongs to
Definition: delaunay_triangulation.h:293
int id() const
get Id number of this edge
Definition: delaunay_triangulation.h:272
const Vertex * vertex(const std::size_t i) const
get the raw pointer to the vertex that this edge has
Definition: delaunay_triangulation.h:283
void setTriangle(TrianglePtr tri)
set the triangle that this edge belongs to.
Definition: delaunay_triangulation.h:247
bool hasVertex(const Vertex *v) const
check if this edge has the specified vertex or not.
Definition: delaunay_triangulation.h:303
~Edge()
nothing to do
Definition: delaunay_triangulation.h:212
Edge(const int id, const Vertex *v0, const Vertex *v1)
create edge with two vertices. vertices must not be NULL.
Definition: delaunay_triangulation.h:197
void removeTriangle(TrianglePtr tri)
remove pointer to the triangle that this edge belongs to. This edge is NOT removed.
Definition: delaunay_triangulation.h:220
triangle data
Definition: delaunay_triangulation.h:315
Edge * getEdgeExclude(const Vertex *v) const
get the pointer to the edge that does not have the specified vertex.
Definition: delaunay_triangulation.h:512
void updateVoronoiVertex()
update the voronoi vertex point (intersection of perpendicular bisectors)
Edge * edge(std::size_t i) const
get the raw pointer to the edge that this triangle has
Definition: delaunay_triangulation.h:387
~Triangle()
remove this triangle from all edges.
Definition: delaunay_triangulation.h:350
Edge * getEdgeInclude(const Vertex *v1, const Vertex *v2) const
get the pointer to the edge that has the specified vertices.
Definition: delaunay_triangulation.h:493
const Vertex * vertex(std::size_t i) const
get the raw pointer to the vertex that this triangle has
Definition: delaunay_triangulation.h:377
bool contains(const Vector2D &pos) const
check if circumcircle contains the specified point
Definition: delaunay_triangulation.h:425
bool hasVertex(const Vertex *v) const
check if this triangle has the specified vertex.
Definition: delaunay_triangulation.h:435
const Vector2D & voronoiVertex() const
get the voronoi vertex point
Definition: delaunay_triangulation.h:415
Triangle(const int id, EdgePtr e0, EdgePtr e1, EdgePtr e2)
create triangle with index and edges
const Vector2D & circumcenter() const
get the circumcenter point of this triangle
Definition: delaunay_triangulation.h:397
const Vertex * getVertexExclude(const Vertex *v1, const Vertex *v2) const
get the pointer to the vertex that is different from the specified vertices.
Definition: delaunay_triangulation.h:461
const Vertex * getVertexExclude(const Edge *edge) const
get the pointer to the vertex that does not belong to the specified edge.
Definition: delaunay_triangulation.h:481
int id() const
get the Id of this triangle
Definition: delaunay_triangulation.h:366
bool hasEdge(const EdgePtr e) const
check if this triangle has the specified edge.
Definition: delaunay_triangulation.h:447
double circumradius() const
get the radius of the circumcircle of this triangle
Definition: delaunay_triangulation.h:406
triangle's vertex data. This is handled as kernel point for the Voronoi diagram..
Definition: delaunay_triangulation.h:71
Vertex(const int id)
create vertex with Id
Definition: delaunay_triangulation.h:89
Vertex(const int id, const double x, const double y)
create vertex with Id & coordinates
Definition: delaunay_triangulation.h:117
Vertex()
create vertex with Id number 0
Definition: delaunay_triangulation.h:80
int id() const
get the Id of this vertex
Definition: delaunay_triangulation.h:156
Vertex & assign(const int id, const double x, const double y)
assign data
Definition: delaunay_triangulation.h:143
Vertex(const int id, const Vector2D &p)
create vertex with Id & coordinates
Definition: delaunay_triangulation.h:105
const Vector2D & pos() const
get the coordinates of the kernel point
Definition: delaunay_triangulation.h:166
virtual ~Vertex()
nothing to do
Definition: delaunay_triangulation.h:97
Vertex & assign(const int id, const Vector2D &p)
assign data
Definition: delaunay_triangulation.h:129
Delaunay triangulation.
Definition: delaunay_triangulation.h:49
const VertexCont & vertices() const
get vertices
Definition: delaunay_triangulation.h:608
std::unordered_map< int, EdgePtr > EdgeCont
edge pointer container type
Definition: delaunay_triangulation.h:529
const TriangleCont & triangles() const
get triangle set
Definition: delaunay_triangulation.h:628
void clear()
clear all vertices and all computed results.
void addVertices(const std::vector< Vector2D > &v)
set vertices.
void compute()
compute the Delaunay Triangulation
Edge * EdgePtr
alias of Edge pointer
Definition: delaunay_triangulation.h:177
static const double EPSILON
tolerance threshold
Definition: delaunay_triangulation.h:52
const EdgeCont & edges() const
get edge set
Definition: delaunay_triangulation.h:618
void updateVoronoiVertex()
calculate voronoi vertex point for each triangle
void clearResults()
clear all computed results
DelaunayTriangulation(const Rect2D &region)
construct with considerable rectangle region
Definition: delaunay_triangulation.h:571
int addVertex(const Vector2D &p)
add new vertex
Definition: delaunay_triangulation.h:647
const Vertex * getVertex(const int id) const
get the const pointer to vertex specified by Id number.
const Triangle * findTriangleContains(const Vector2D &pos) const
find triangle that contains pos from the computed triangle set.
std::vector< Vertex > VertexCont
vertex container type
Definition: delaunay_triangulation.h:528
const Vertex * findNearestVertex(const Vector2D &pos) const
find the vertex nearest to the specified point
void init(const Rect2D &region)
initialize with target field rectangle data. All data are cleared. Initial triangle is crated.
Definition: delaunay_triangulation.h:587
int addVertex(const double x, const double y)
add new vertex
DelaunayTriangulation()=default
nothing to do
std::unordered_map< int, TrianglePtr > TriangleCont
triangle pointer container type
Definition: delaunay_triangulation.h:530
ContainedType
containment type in triangles
Definition: delaunay_triangulation.h:59
Triangle * TrianglePtr
alias of Triangle pointer
Definition: delaunay_triangulation.h:178
2D rectangle regin class.
Definition: rect_2d.h:59
2D point vector class
Definition: vector_2d.h:46
Vector2D & assign(const double xx, const double yy)
assign XY value directly.
Definition: vector_2d.h:100
double y
Y coordinate.
Definition: vector_2d.h:64
double dist2(const Vector2D &p) const
get the squared distance from this to 'p'.
Definition: vector_2d.h:347
double x
X coordinate.
Definition: vector_2d.h:63
2D rectangle region Header File.
2d vector class Header File.