00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <stdarg.h>
00030 #include <assert.h>
00031 #include <math.h>
00032 #include <limits.h>
00033 #include <float.h>
00034 #include <string.h>
00035 #include <errno.h>
00036 #include "nan.h"
00037 #include "delaunay.h"
00038
00039 #define BUFSIZE 1024
00040
00041 #define EPSILON 1.0e-8
00042
00043 int nn_verbose = 0;
00044 int nn_test_vertice = -1;
00045 NN_RULE nn_rule = SIBSON;
00046
00047 #include "version.h"
00048
00049 void nn_quit( char* format, ... )
00050 {
00051 va_list args;
00052
00053 fflush( stdout );
00054
00055
00056 fprintf( stderr, "error: nn: " );
00057 va_start( args, format );
00058 vfprintf( stderr, format, args );
00059 va_end( args );
00060
00061 exit( 1 );
00062 }
00063
00064 int circle_build( circle* c, point* p1, point* p2, point* p3 )
00065 {
00066 double x1sq = p1->x * p1->x;
00067 double x2sq = p2->x * p2->x;
00068 double x3sq = p3->x * p3->x;
00069 double y1sq = p1->y * p1->y;
00070 double y2sq = p2->y * p2->y;
00071 double y3sq = p3->y * p3->y;
00072 double t1 = x3sq - x2sq + y3sq - y2sq;
00073 double t2 = x1sq - x3sq + y1sq - y3sq;
00074 double t3 = x2sq - x1sq + y2sq - y1sq;
00075 double D = ( p1->x * ( p2->y - p3->y ) + p2->x * ( p3->y - p1->y ) + p3->x * ( p1->y - p2->y ) ) * 2.0;
00076
00077 if ( D == 0.0 )
00078 return 0;
00079
00080 c->x = ( p1->y * t1 + p2->y * t2 + p3->y * t3 ) / D;
00081 c->y = -( p1->x * t1 + p2->x * t2 + p3->x * t3 ) / D;
00082 c->r = hypot( c->x - p1->x, c->y - p1->y );
00083
00084 return 1;
00085 }
00086
00087
00088
00089
00090
00091
00092
00093
00094 int circle_contains( circle* c, point* p )
00095 {
00096 return hypot( c->x - p->x, c->y - p->y ) <= c->r * ( 1.0 + EPSILON );
00097 }
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 void points_thin( int* pn, point** ppoints, int nx, int ny )
00111 {
00112 int n = *pn;
00113 point * points = *ppoints;
00114 double xmin = DBL_MAX;
00115 double xmax = -DBL_MAX;
00116 double ymin = DBL_MAX;
00117 double ymax = -DBL_MAX;
00118 int nxy = nx * ny;
00119 double * sumx = calloc( nxy, sizeof ( double ) );
00120 double * sumy = calloc( nxy, sizeof ( double ) );
00121 double * sumz = calloc( nxy, sizeof ( double ) );
00122 int * count = calloc( nxy, sizeof ( int ) );
00123 double stepx = 0.0;
00124 double stepy = 0.0;
00125 int nnew = 0;
00126 point * pointsnew = NULL;
00127 int i, j, ii;
00128
00129 if ( nn_verbose )
00130 fprintf( stderr, "thinned: %d points -> ", *pn );
00131
00132 if ( nx < 1 || ny < 1 )
00133 {
00134 free( points );
00135 *ppoints = NULL;
00136 *pn = 0;
00137 if ( nn_verbose )
00138 fprintf( stderr, "0 points" );
00139 free( sumx );
00140 free( sumy );
00141 free( sumz );
00142 free( count );
00143 return;
00144 }
00145
00146 for ( ii = 0; ii < n; ++ii )
00147 {
00148 point* p = &points[ii];
00149
00150 if ( p->x < xmin )
00151 xmin = p->x;
00152 if ( p->x > xmax )
00153 xmax = p->x;
00154 if ( p->y < ymin )
00155 ymin = p->y;
00156 if ( p->y > ymax )
00157 ymax = p->y;
00158 }
00159
00160 stepx = ( nx > 1 ) ? ( xmax - xmin ) / nx : 0.0;
00161 stepy = ( ny > 1 ) ? ( ymax - ymin ) / ny : 0.0;
00162
00163 for ( ii = 0; ii < n; ++ii )
00164 {
00165 point* p = &points[ii];
00166 int index;
00167
00168
00169
00170
00171
00172
00173 i = ( nx == 1 ) ? 0 : ( p->x - xmin ) / stepx;
00174 j = ( ny == 1 ) ? 0 : ( p->y - ymin ) / stepy;
00175
00176 if ( i == nx )
00177 i--;
00178 if ( j == ny )
00179 j--;
00180 index = i + j * nx;
00181 sumx[index] += p->x;
00182 sumy[index] += p->y;
00183 sumz[index] += p->z;
00184 count[index]++;
00185 }
00186
00187 for ( j = 0; j < ny; ++j )
00188 {
00189 for ( i = 0; i < nx; ++i )
00190 {
00191 int index = i + j * nx;
00192
00193 if ( count[index] > 0 )
00194 nnew++;
00195 }
00196 }
00197
00198 pointsnew = malloc( nnew * sizeof ( point ) );
00199
00200 ii = 0;
00201 for ( j = 0; j < ny; ++j )
00202 {
00203 for ( i = 0; i < nx; ++i )
00204 {
00205 int index = i + j * nx;
00206 int nn = count[index];
00207
00208 if ( nn > 0 )
00209 {
00210 point* p = &pointsnew[ii];
00211
00212 p->x = sumx[index] / nn;
00213 p->y = sumy[index] / nn;
00214 p->z = sumz[index] / nn;
00215 ii++;
00216 }
00217 }
00218 }
00219
00220 if ( nn_verbose )
00221 fprintf( stderr, "%d points\n", nnew );
00222
00223 free( sumx );
00224 free( sumy );
00225 free( sumz );
00226 free( count );
00227
00228 free( points );
00229 *ppoints = pointsnew;
00230 *pn = nnew;
00231 }
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 void points_generate1( int nin, point pin[], int nx, int ny, double zoom, int* nout, point** pout )
00246 {
00247 double xmin = DBL_MAX;
00248 double xmax = -DBL_MAX;
00249 double ymin = DBL_MAX;
00250 double ymax = -DBL_MAX;
00251 double stepx, stepy;
00252 double x0, xx, yy;
00253 int i, j, ii;
00254
00255 if ( nx < 1 || ny < 1 )
00256 {
00257 *pout = NULL;
00258 *nout = 0;
00259 return;
00260 }
00261
00262 for ( ii = 0; ii < nin; ++ii )
00263 {
00264 point* p = &pin[ii];
00265
00266 if ( p->x < xmin )
00267 xmin = p->x;
00268 if ( p->x > xmax )
00269 xmax = p->x;
00270 if ( p->y < ymin )
00271 ymin = p->y;
00272 if ( p->y > ymax )
00273 ymax = p->y;
00274 }
00275
00276 if ( isnan( zoom ) || zoom <= 0.0 )
00277 zoom = 1.0;
00278
00279 if ( zoom != 1.0 )
00280 {
00281 double xdiff2 = ( xmax - xmin ) / 2.0;
00282 double ydiff2 = ( ymax - ymin ) / 2.0;
00283 double xav = ( xmax + xmin ) / 2.0;
00284 double yav = ( ymax + ymin ) / 2.0;
00285
00286 xmin = xav - xdiff2 * zoom;
00287 xmax = xav + xdiff2 * zoom;
00288 ymin = yav - ydiff2 * zoom;
00289 ymax = yav + ydiff2 * zoom;
00290 }
00291
00292 *nout = nx * ny;
00293 *pout = malloc( *nout * sizeof ( point ) );
00294
00295 stepx = ( nx > 1 ) ? ( xmax - xmin ) / ( nx - 1 ) : 0.0;
00296 stepy = ( ny > 1 ) ? ( ymax - ymin ) / ( ny - 1 ) : 0.0;
00297 x0 = ( nx > 1 ) ? xmin : ( xmin + xmax ) / 2.0;
00298 yy = ( ny > 1 ) ? ymin : ( ymin + ymax ) / 2.0;
00299
00300 ii = 0;
00301 for ( j = 0; j < ny; ++j )
00302 {
00303 xx = x0;
00304 for ( i = 0; i < nx; ++i )
00305 {
00306 point* p = &( *pout )[ii];
00307
00308 p->x = xx;
00309 p->y = yy;
00310 xx += stepx;
00311 ii++;
00312 }
00313 yy += stepy;
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 void points_generate2( double xmin, double xmax, double ymin, double ymax, int nx, int ny, int* nout, point** pout )
00331 {
00332 double stepx, stepy;
00333 double x0, xx, yy;
00334 int i, j, ii;
00335
00336 if ( nx < 1 || ny < 1 )
00337 {
00338 *pout = NULL;
00339 *nout = 0;
00340 return;
00341 }
00342
00343 *nout = nx * ny;
00344 *pout = malloc( *nout * sizeof ( point ) );
00345
00346 stepx = ( nx > 1 ) ? ( xmax - xmin ) / ( nx - 1 ) : 0.0;
00347 stepy = ( ny > 1 ) ? ( ymax - ymin ) / ( ny - 1 ) : 0.0;
00348 x0 = ( nx > 1 ) ? xmin : ( xmin + xmax ) / 2.0;
00349 yy = ( ny > 1 ) ? ymin : ( ymin + ymax ) / 2.0;
00350
00351 ii = 0;
00352 for ( j = 0; j < ny; ++j )
00353 {
00354 xx = x0;
00355 for ( i = 0; i < nx; ++i )
00356 {
00357 point* p = &( *pout )[ii];
00358
00359 p->x = xx;
00360 p->y = yy;
00361 xx += stepx;
00362 ii++;
00363 }
00364 yy += stepy;
00365 }
00366 }
00367
00368 static int str2double( char* token, double* value )
00369 {
00370 char* end = NULL;
00371
00372 if ( token == NULL )
00373 {
00374 *value = NaN;
00375 return 0;
00376 }
00377
00378 *value = strtod( token, &end );
00379
00380 if ( end == token )
00381 {
00382 *value = NaN;
00383 return 0;
00384 }
00385
00386 return 1;
00387 }
00388
00389 #define NALLOCATED_START 1024
00390
00391
00392
00393
00394
00395
00396
00397
00398 void points_read( char* fname, int dim, int* n, point** points )
00399 {
00400 FILE * f = NULL;
00401 int nallocated = NALLOCATED_START;
00402 char buf[BUFSIZE];
00403 char seps[] = " ,;\t";
00404 char * token;
00405
00406 if ( dim < 2 || dim > 3 )
00407 {
00408 *n = 0;
00409 *points = NULL;
00410 return;
00411 }
00412
00413 if ( fname == NULL )
00414 f = stdin;
00415 else
00416 {
00417 if ( strcmp( fname, "stdin" ) == 0 || strcmp( fname, "-" ) == 0 )
00418 f = stdin;
00419 else
00420 {
00421 f = fopen( fname, "r" );
00422 if ( f == NULL )
00423 nn_quit( "%s: %s\n", fname, strerror( errno ) );
00424 }
00425 }
00426
00427 *points = malloc( nallocated * sizeof ( point ) );
00428 *n = 0;
00429 while ( fgets( buf, BUFSIZE, f ) != NULL )
00430 {
00431 point* p;
00432
00433 if ( *n == nallocated )
00434 {
00435 nallocated *= 2;
00436 *points = realloc( *points, nallocated * sizeof ( point ) );
00437 }
00438
00439 p = &( *points )[*n];
00440
00441 if ( buf[0] == '#' )
00442 continue;
00443 if ( ( token = strtok( buf, seps ) ) == NULL )
00444 continue;
00445 if ( !str2double( token, &p->x ) )
00446 continue;
00447 if ( ( token = strtok( NULL, seps ) ) == NULL )
00448 continue;
00449 if ( !str2double( token, &p->y ) )
00450 continue;
00451 if ( dim == 2 )
00452 p->z = NaN;
00453 else
00454 {
00455 if ( ( token = strtok( NULL, seps ) ) == NULL )
00456 continue;
00457 if ( !str2double( token, &p->z ) )
00458 continue;
00459 }
00460 ( *n )++;
00461 }
00462
00463 if ( *n == 0 )
00464 {
00465 free( *points );
00466 *points = NULL;
00467 }
00468 else
00469 *points = realloc( *points, *n * sizeof ( point ) );
00470
00471 if ( f != stdin )
00472 if ( fclose( f ) != 0 )
00473 nn_quit( "%s: %s\n", fname, strerror( errno ) );
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483 double points_scaletosquare( int n, point* points )
00484 {
00485 double xmin, ymin, xmax, ymax;
00486 double k;
00487 int i;
00488
00489 if ( n <= 0 )
00490 return NaN;
00491
00492 xmin = xmax = points[0].x;
00493 ymin = ymax = points[0].y;
00494
00495 for ( i = 1; i < n; ++i )
00496 {
00497 point* p = &points[i];
00498
00499 if ( p->x < xmin )
00500 xmin = p->x;
00501 else if ( p->x > xmax )
00502 xmax = p->x;
00503 if ( p->y < ymin )
00504 ymin = p->y;
00505 else if ( p->y > ymax )
00506 ymax = p->y;
00507 }
00508
00509 if ( xmin == xmax || ymin == ymax )
00510 return NaN;
00511 else
00512 k = ( ymax - ymin ) / ( xmax - xmin );
00513
00514 for ( i = 0; i < n; ++i )
00515 points[i].y /= k;
00516
00517 return k;
00518 }
00519
00520
00521
00522
00523
00524
00525
00526 void points_scale( int n, point* points, double k )
00527 {
00528 int i;
00529
00530 for ( i = 0; i < n; ++i )
00531 points[i].y /= k;
00532 }