00001
00002
00003
00004
00005
00006
00007
00008
#include <stdlib.h>
00009
00010
#include "DelaunayMeshGenerator.h"
00011
#include "geometry.h"
00012
00013
#include <qdatetime.h>
00014
00015
00016
extern char* __delaunay_lib_version;
00017
00018
00019
00020 DelaunayMeshGenerator::DelaunayMeshGenerator(
const QString& filename,
bool verbose)
00021 : QXmlDefaultHandler(), _verbose(verbose)
00022 {
00023
#ifdef _DEBUG_
00024
fprintf(stderr,
"<DelaunayMeshGenerator::DelaunayMeshGenerator()>\n");
00025
#endif
00026
00027 reset();
00028 QFile xmlfile(filename);
00029 open(xmlfile);
00030
00031
00032
#ifdef _DEBUG_
00033
fprintf(stderr,
"numer of vertices : %d \n", _vertices.count() );
00034 fprintf(stderr,
"</DelaunayMeshGenerator::DelaunayMeshGenerator()>\n");
00035
#endif
00036
00037 }
00038
00039
00040
00041 DelaunayMeshGenerator::DelaunayMeshGenerator(QIODevice& iodevice,
bool verbose)
00042 : QXmlDefaultHandler(), _verbose(verbose)
00043 {
00044 reset();
00045 open(iodevice);
00046 }
00047
00048
00049
00050
00051
void
00052 DelaunayMeshGenerator::reset()
00053 {
00054 _mesh = 0;
00055 _count_ID = 1;
00056 }
00057
00058
00059
00060 DelaunayMeshGenerator::~DelaunayMeshGenerator()
00061 {
00062
00063
00064
00065 _edges.setAutoDelete(
true);
00066 _active_edges.setAutoDelete(
true);
00067
00068
00069
00070
if(_mesh != 0)
00071
delete _mesh;
00072 }
00073
00074
00075
00076
void
00077 DelaunayMeshGenerator::add_vertex(
Vertex* v)
00078 {
00079
#ifdef _DEBUG_
00080
fprintf(stderr,
"<DelaunayMeshGenerator::addVertex()>\n");
00081
#endif
00082
00083 _vertices.append(v);
00084
00085
#ifdef _DEBUG_
00086
fprintf(stderr,
"</DelaunayMeshGenerator::addVertex()>\n");
00087
#endif
00088
00089 }
00090
00091
00092
00093
void
00094 DelaunayMeshGenerator::generate()
00095 {
00096
#ifdef _DEBUG_
00097
fprintf(stderr,
"<DelaunayMeshGenerator::generate()>\n");
00098
#endif
00099
00100 init();
00101
00102
#ifdef _DEBUG_
00103
fprintf(stderr,
"[DelaunayMeshGenerator::generate()] bbox (%f/%f)-(%f/%f) \n",
00104 minX, minY, maxX, maxY );
00105
#endif
00106
00107 _active_edges = _edges;
00108 _active_vertices = _vertices;
00109
00110
Vertex* new_vertex = 0;
00111
00112
00113
int count = 0;
00114
00115
00116
while(!_active_edges.isEmpty()) {
00117
00118
Edge* edge = _active_edges.take(0);
00119
00120
00121
00122
00123
00124
00125
00126
00127
if(_verbose) {
00128 count++;
00129
if(count % 100 == 0) {
00130 fprintf(stderr,
"number of active vertices = %d \n", _active_vertices.count() );
00131 }
00132 }
00133
00134 ((
Vertex*) edge->
vertex(0))->grad -= 1;
00135 ((
Vertex*) edge->
vertex(1))->grad -= 1;
00136
00137 box_minX = minX;
00138 box_maxX = maxX;
00139 box_minY = minY;
00140 box_maxY = maxY;
00141
00142 new_vertex = 0;
00143 u_alt = 1e15;
00144
00145
00146 QPtrListIterator<Vertex> it(_active_vertices);
00147
00148
Vertex* vertex;
00149
00150
while( (vertex = it.current()) != 0 ) {
00151
00152 ++it;
00153
00154
#ifdef _DEBUG_
00155
fprintf(stderr,
"check vertex [%s] (%d active vertices) \n",
00156 vertex->get_ID().latin1(), _active_vertices.count() );
00157
#endif
00158
00159
00160
if(vertex == edge->
vertex(0) || vertex == edge->
vertex(1) ) {
00161
#ifdef _DEBUG_
00162
fprintf(stderr,
"continue [%s] (1) \n", vertex->get_ID().latin1() );
00163
#endif
00164
continue;
00165 }
00166
00167
00168
if(vertex->
x() < box_minX || vertex->
x() > box_maxX ||
00169 vertex->
y() < box_minY || vertex->
y() > box_maxY ) {
00170
00171
#ifdef _DEBUG_
00172
fprintf(stderr,
"continue [%s] (2) \n", vertex->
ID().latin1() );
00173
#endif
00174
00175
continue;
00176
00177 }
00178
00179
00180
if(
geometry::area(edge->
vertex(0),
00181 edge->
vertex(1),
00182 vertex ) <= CEps ) {
00183
#ifdef _DEBUG_
00184
fprintf(stderr,
"continue [%s] (3) \n", vertex->
ID().latin1() );
00185
#endif
00186
continue;
00187 }
00188
00189
00190
00191
if( test_intersection(vertex, edge->
vertex(0)) ) {
00192
#ifdef _DEBUG_
00193
fprintf(stderr,
"continue [%s] (4) \n", vertex->
ID().latin1() );
00194
#endif
00195
continue;
00196 }
00197
00198
00199
00200
if( test_intersection(edge->
vertex(1), vertex) ) {
00201
00202
#ifdef _DEBUG_
00203
fprintf(stderr,
"continue [%s] (5) \n", vertex->
ID().latin1() );
00204
#endif
00205
continue;
00206
00207 }
00208
00209
00210
if( is_voronoi_triangle(edge, vertex) )
00211 new_vertex = vertex;
00212
00213
00214 }
00215
00216
if(new_vertex != 0) {
00217 create_triangle(edge, new_vertex);
00218 }
else {
00219 fprintf(stderr,
"ERROR : newpoint = null! \n");
00220 exit(1);
00221 }
00222
00223 }
00224
00225
00226
00227
00228
00229
00230
#ifdef _DEBUG_
00231
fprintf(stderr,
"</DelaunayMeshGenerator::generate()>\n");
00232
#endif
00233
00234 }
00235
00236
00237
00238
void
00239 DelaunayMeshGenerator::create_triangle(
Edge* basisedge,
Vertex* vertex)
00240 {
00241
#ifdef _DEBUG_
00242
fprintf(stderr,
"</DelaunayMeshGenerator::createTriangle()>\n");
00243 fprintf(stderr,
"[/DelaunayMeshGenerator::createTriangle()] basisedge [%s]-[%s], vertex [%s]\n",
00244 basisedge->
vertex(0)->
ID().latin1(),
00245 basisedge->
vertex(1)->
ID().latin1(),
00246 vertex->
ID().latin1() );
00247
#endif
00248
00249
00250
Triangle* tri;
00251
Edge* edge;
00252
Edge* e[2];
00253
00254 tri =
new Triangle(createID(),
00255 basisedge->
vertex(0),
00256 basisedge->
vertex(1),
00257 vertex);
00258
00259 vertex->
used =
true;
00260
00261
00262
00263
00264 e[0] = e[1] = 0;
00265
00266
00267 QPtrListIterator<Edge> it(_active_edges);
00268
00269
while( (edge = it.current()) != 0 ) {
00270
00271 ++it;
00272
00273
for(
int i=0; i<2; i++) {
00274
00275
if(vertex == edge->
vertex(i) &&
00276 basisedge->
vertex(i) == edge->
vertex((i+1)%2)) {
00277
00278 e[i] = edge;
00279
00280 ((
Vertex*) edge->vertex(0))->grad -= 1;
00281 ((
Vertex*) edge->vertex(1))->grad -= 1;
00282
00283
if(((
Vertex*) edge->vertex(0))->grad == 0 &&
00284 ((
Vertex*) edge->vertex(0))->used ==
true )
00285 _active_vertices.removeRef( ((
Vertex*) edge->vertex(0)) );
00286
00287
if(((
Vertex*) edge->vertex(1))->grad == 0 &&
00288 ((
Vertex*) edge->vertex(1))->used ==
true )
00289 _active_vertices.removeRef( ((
Vertex*) edge->vertex(1)) );
00290
00291 }
00292
00293
if(e[0] != 0 && e[1] != 0)
00294
break;
00295
00296 }
00297
00298 }
00299
00300
00301
if(e[0] == 0) {
00302
00303
#ifdef _DEBUG_
00304
fprintf(stderr,
"[DelaunayMeshGenerator::createTriangle()] create new edge \n");
00305 fprintf(stderr,
" new edge [%s][%s] \n",
00306 basisedge->
vertex(0)->
ID().latin1(),
00307 vertex->
ID().latin1() );
00308
#endif
00309
00310 e[0] =
new Edge(basisedge->
vertex(0), vertex);
00311
00312 vertex->
grad += 1;
00313 ((
Vertex*) basisedge->
vertex(0))->grad += 1;
00314
00315 _active_edges.append( e[0] );
00316
00317 }
else {
00318 _active_edges.removeRef( e[0] );
00319 }
00320
00321
00322
if(e[1] == 0) {
00323
00324
#ifdef _DEBUG_
00325
fprintf(stderr,
"[DelaunayMeshGenerator::createTriangle()] create new edge \n");
00326 fprintf(stderr,
" new edge [%s][%s] \n",
00327 vertex->
ID().latin1(),
00328 basisedge->
vertex(1)->
ID().latin1() );
00329
#endif
00330
00331 e[1] =
new Edge(vertex, basisedge->
vertex(1));
00332
00333 vertex->
grad += 1;
00334 ((
Vertex*) basisedge->
vertex(1))->grad += 1;
00335
00336 _active_edges.append( e[1] );
00337
00338 }
else {
00339 _active_edges.removeRef( e[1] );
00340 }
00341
00342
00343
00344
00345
00346 _mesh->
add_triangle(tri);
00347
00348
#ifdef _DEBUG_
00349
fprintf(stderr,
"</DelaunayMeshGenerator::createTriangle(): triangle added.\n");
00350
#endif
00351
00352
00353 }
00354
00355
00356
00357
bool
00358 DelaunayMeshGenerator::test_intersection(
Vertex* v1,
Vertex* v2)
00359 {
00360
#ifdef _DEBUG_
00361
fprintf(stderr,
"<DelaunayMeshGenerator::testIntersection(%s - %s)\n",
00362 v1->
ID().latin1(), v2->
ID().latin1() );
00363 fprintf(stderr,
" (%f/%f)-(%f/%f))>\n",
00364 v1->
x(), v1->
y(), v2->
x(), v2->
y() );
00365
#endif
00366
00367
00368
00369
00370
00371
Edge* edge;
00372
00373
geometry::line l1, l2;
00374
00375 l1.
p1.x = v1->
x();
00376 l1.
p1.y = v1->
y();
00377
00378 l1.
p2.x = v2->
x();
00379 l1.
p2.y = v2->
y();
00380
00381
00382
00383
00384
int size = _active_edges.count();
00385
00386
#ifdef _DEBUG_
00387
fprintf(stderr,
"[DelaunayMeshGenerator::testIntersection()] %d active edges\n",
00388 size );
00389
#endif
00390
00391
for(
int i=0; i<size; i++) {
00392
00393 edge = _active_edges.at(i);
00394
00395
#ifdef _DEBUG_
00396
fprintf(stderr,
"[DelaunayMeshGenerator::testIntersection()] test [%d/%d] active edge [%s]-[%s]\n",
00397 i, size,
00398 edge->
vertex(0)->
ID().latin1(),
00399 edge->
vertex(1)->
ID().latin1() );
00400 fprintf(stderr,
" edge [%s - %s] \n",
00401 edge->
vertex(0)->
ID().latin1(),
00402 edge->
vertex(1)->
ID().latin1() );
00403
#endif
00404
00405
if( edge->
vertex(0) == v1 || edge->
vertex(1) == v1 ) {
00406
continue;
00407 }
00408
00409
if( edge->
vertex(0) == v2 || edge->
vertex(1) == v2 ) {
00410
continue;
00411 }
00412
00413 l2.
p1.x = edge->
vertex(0)->
x();
00414 l2.
p1.y = edge->
vertex(0)->
y();
00415 l2.
p2.x = edge->
vertex(1)->
x();
00416 l2.
p2.y = edge->
vertex(1)->
y();
00417
00418
if(
geometry::intersect(l1,l2)) {
00419
00420
#ifdef _DEBUG_
00421
fprintf(stderr,
"<DelaunayMeshGenerator::testIntersection()> return <true>\n");
00422
#endif
00423
00424
return true;
00425
00426 }
00427
00428 }
00429
00430
#ifdef _DEBUG_
00431
fprintf(stderr,
"<DelaunayMeshGenerator::testIntersection()> return <false>\n");
00432
#endif
00433
00434
return false;
00435
00436 }
00437
00438
00439
00440
bool
00441 DelaunayMeshGenerator::is_voronoi_triangle(
Edge* edge,
Vertex* v)
00442 {
00443
double u;
00444
00445
double e2[2];
00446
00447
double xm,ym;
00448
double dx,dy;
00449
double radius;
00450
00451
00452
double x1 = edge->
vertex(0)->
x();
00453
double y1 = edge->
vertex(0)->
y();
00454
00455
double x2 = edge->
vertex(1)->
x();
00456
double y2 = edge->
vertex(1)->
y();
00457
00458
double x3 = v->
x();
00459
double y3 = v->
y();
00460
00461
00462 e2[0] = -(y2 - y1) / sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
00463 e2[1] = (x2 - x1) / sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1));
00464
00465
00466 u = ((x3 - x2)*(x3 - x1) + (y3 - y2)*(y3 - y1)) /
00467 (2.0 * (e2[0] * (x3 - x1) + e2[1] * (y3 - y1)));
00468
00469
00470
if(u_alt > u) {
00471
00472 u_alt = u;
00473
00474 xm = 0.5 * (x1 + x2) + u_alt * e2[0];
00475 ym = 0.5 * (y1 + y2) + u_alt * e2[1];
00476 dx = xm - x1;
00477 dy = ym - y1;
00478 radius = sqrt(dx*dx+dy*dy);
00479
00480 box_minX = xm - radius;
00481 box_minY = ym - radius;
00482 box_maxX = xm + radius;
00483 box_maxY = ym + radius;
00484
00485
return true;
00486
00487 }
00488
00489
return false;
00490
00491 }
00492
00493
00494
00495
void
00496 DelaunayMeshGenerator::init()
00497 {
00498 _mesh =
new Mesh();
00499
00500 minX = minY = 1e15;
00501 maxX = maxY = -1e15;
00502
00503
for(
Vertex* v = _vertices.first(); v; v = _vertices.next()) {
00504
00505 _mesh->
add_vertex(v);
00506
00507 v->
grad = 0;
00508 v->
used =
false;
00509
00510
if(minX > v->
x()) minX = v->
x();
00511
if(maxX < v->
x()) maxX = v->
x();
00512
if(minY > v->
y()) minY = v->
y();
00513
if(maxY < v->
y()) maxY = v->
y();
00514
00515 }
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
for(
Edge* e = _edges.first(); e; e = _edges.next()) {
00527
00528
for(
int i=0; i<2; i++) {
00529
Vertex* v = (
Vertex*) e->
vertex(i);
00530 v->
grad += 1;
00531 v->
used =
true;
00532 }
00533
00534 }
00535
00536 }
00537
00538
00539
00540
void
00541 DelaunayMeshGenerator::write_XML(QTextStream& cout)
00542 {
00543 cout <<
"<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
00544 cout <<
"<!-- created by delaunay mesh generator \n";
00545 cout <<
" " << __delaunay_lib_version << endl;
00546 cout <<
" " << QTime::currentTime().toString() <<
" -->\n";
00547
00548 cout <<
"<objects>\n";
00549
00550
for(
Vertex* v = _vertices.first(); v; v = _vertices.next()) {
00551 v->
write_XML(cout);
00552 }
00553
00554
for(
Edge* e = _edges.first(); e; e = _edges.next()) {
00555 e->
write_XML(cout);
00556 }
00557
00558 cout <<
"</objects>\n";
00559 }
00560
00561
00562
00563
bool
00564 DelaunayMeshGenerator::startElement(
const QString&,
const QString&,
00565
const QString& qName,
00566
const QXmlAttributes& xmlattr)
00567 {
00568
00569 QString qNameL = qName.stripWhiteSpace().lower();
00570
00571
#ifdef _DEBUG_
00572
fprintf(stderr,
"<DelaunayMeshGenerator::startElement()> elem = %s \n",
00573 qNameL.latin1() );
00574
#endif
00575
00576
if(qNameL ==
"point") {
00577
00578 QString
id = xmlattr.value(
"id");
00579 QString x = xmlattr.value(
"x");
00580 QString y = xmlattr.value(
"y");
00581
00582
Vertex* v =
new Vertex(
id, x.toDouble(), y.toDouble());
00583
00584
00585
00586 add_vertex(v);
00587
00588
return true;
00589
00590 }
00591
00592
if(qNameL ==
"edge") {
00593
00594 QString from = xmlattr.value(
"from");
00595 QString to = xmlattr.value(
"to");
00596
00597
Vertex* v1 = vertex(from);
00598
Vertex* v2 = vertex(to);
00599
00600
if(v1 == 0) {
00601 fprintf(stderr,
"<DelaunayMeshGenerator::startElement()> : ERROR = \n");
00602 fprintf(stderr,
" could not find point [%s] !!\n", from.latin1());
00603 exit(1);
00604 }
00605
00606
if(v2 == 0) {
00607 fprintf(stderr,
"<DelaunayMeshGenerator::startElement()> : ERROR = \n");
00608 fprintf(stderr,
" could not find point [%s] !!\n", to.latin1());
00609 exit(1);
00610 }
00611
00612
Edge* e =
new Edge(v1,v2);
00613
00614 add_edge(e);
00615
00616
return true;
00617
00618 }
00619
00620
return true;
00621
00622 }