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 #include "plplotP.h"
00027
00028 #ifdef WITH_CSA
00029 #include "../lib/csa/csa.h"
00030 #endif
00031 #include "../lib/csa/nan.h"
00032
00033 #ifdef HAVE_QHULL
00034 #include "../lib/nn/nn.h"
00035 #include <qhull/qhull_a.h>
00036 #endif
00037
00038
00039 static void
00040 grid_nnaidw (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00041 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg);
00042
00043 static void
00044 grid_nnli (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00045 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg,
00046 PLFLT threshold);
00047
00048 static void
00049 grid_nnidw (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00050 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg,
00051 int knn_order);
00052
00053 #ifdef WITH_CSA
00054 static void
00055 grid_csa (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00056 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg);
00057 #endif
00058
00059 #ifdef HAVE_QHULL
00060 static void
00061 grid_nni (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00062 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg,
00063 PLFLT wmin);
00064
00065 static void
00066 grid_dtli (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00067 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg);
00068 #endif
00069
00070 static void
00071 dist1(PLFLT gx, PLFLT gy, PLFLT *x, PLFLT *y, int npts, int knn_order);
00072 static void
00073 dist2(PLFLT gx, PLFLT gy, PLFLT *x, PLFLT *y, int npts);
00074
00075 #define KNN_MAX_ORDER 100
00076
00077 typedef struct pt{
00078 PLFLT dist;
00079 int item;
00080 }PT;
00081
00082 static PT items[KNN_MAX_ORDER];
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 void
00110 c_plgriddata(PLFLT *x, PLFLT *y, PLFLT *z, PLINT npts,
00111 PLFLT *xg, PLINT nptsx, PLFLT *yg, PLINT nptsy,
00112 PLFLT **zg, PLINT type, PLFLT data)
00113 {
00114 int i, j;
00115
00116 if(npts < 1 || nptsx < 1 || nptsy < 1) {
00117 plabort("plgriddata: Bad array dimensions");
00118 return;
00119 }
00120
00121
00122
00123 for (i = 0; i < nptsx - 1; i++) {
00124 if (xg[i] >= xg[i + 1]) {
00125 plabort("plgriddata: xg array must be strictly increasing");
00126 return;
00127 }
00128 }
00129 for (i = 0; i < nptsy - 1; i++) {
00130 if (yg[i] >= yg[i + 1]) {
00131 plabort("plgriddata: yg array must be strictly increasing");
00132 return;
00133 }
00134 }
00135
00136
00137 for(i=0; i<nptsx; i++)
00138 for(j=0; j<nptsy; j++)
00139 zg[i][j] = 0.;
00140
00141 switch (type) {
00142
00143 case (GRID_CSA):
00144 #ifdef WITH_CSA
00145 grid_csa(x, y, z, npts, xg, nptsx, yg, nptsy, zg);
00146 #else
00147 plwarn("plgriddata(): PLplot was configured to not use GRID_CSA.\n Reverting to GRID_NNAIDW.");
00148 grid_nnaidw(x, y, z, npts, xg, nptsx, yg, nptsy, zg);
00149 #endif
00150 break;
00151
00152 case (GRID_NNIDW):
00153 grid_nnidw(x, y, z, npts, xg, nptsx, yg, nptsy, zg, (int) data);
00154 break;
00155
00156 case (GRID_NNLI):
00157 grid_nnli(x, y, z, npts, xg, nptsx, yg, nptsy, zg, data);
00158 break;
00159
00160 case (GRID_NNAIDW):
00161 grid_nnaidw(x, y, z, npts, xg, nptsx, yg, nptsy, zg);
00162 break;
00163
00164 case (GRID_DTLI):
00165 #ifdef HAVE_QHULL
00166 grid_dtli(x, y, z, npts, xg, nptsx, yg, nptsy, zg);
00167 #else
00168 plwarn("plgriddata(): you must have the Qhull library installed to use GRID_DTLI.\n Reverting to GRID_NNAIDW.");
00169 grid_nnaidw(x, y, z, npts, xg, nptsx, yg, nptsy, zg);
00170 #endif
00171 break;
00172
00173 case (GRID_NNI):
00174 #ifdef HAVE_QHULL
00175 grid_nni(x, y, z, npts, xg, nptsx, yg, nptsy, zg, data);
00176 #else
00177 plwarn("plgriddata(): you must have the Qhull library installed to use GRID_NNI.\n Reverting to GRID_NNAIDW.");
00178 grid_nnaidw(x, y, z, npts, xg, nptsx, yg, nptsy, zg);
00179 #endif
00180 break;
00181
00182 default:
00183 plabort("plgriddata: unknown algorithm type");
00184 }
00185 }
00186
00187 #ifdef WITH_CSA
00188
00189
00190
00191
00192
00193
00194 static void
00195 grid_csa (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00196 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg)
00197 {
00198 PLFLT *xt, *yt, *zt;
00199 point *pin, *pgrid, *pt;
00200 csa* a = NULL;
00201 int i, j, nptsg;
00202
00203 if ((pin = (point *) malloc(npts * sizeof(point)))==NULL)
00204 {
00205 plexit("grid_csa: Insufficient memory");
00206 }
00207
00208 xt = x; yt = y; zt = z; pt = pin;
00209 for(i=0; i<npts; i++) {
00210 pt->x = (double) *xt++;
00211 pt->y = (double) *yt++;
00212 pt->z = (double) *zt++;
00213 pt++;
00214 }
00215
00216 nptsg = nptsx * nptsy;
00217 if ((pgrid = (point *) malloc(nptsg * sizeof(point)))==NULL)
00218 {
00219 plexit("grid_csa: Insufficient memory");
00220 }
00221
00222 yt = yg; pt = pgrid;
00223 for(j=0; j<nptsy; j++) {
00224 xt = xg;
00225 for(i=0; i<nptsx; i++) {
00226 pt->x = (double) *xt++;
00227 pt->y = (double) *yt;
00228 pt++;
00229 }
00230 yt++;
00231 }
00232
00233 a = csa_create();
00234 csa_addpoints(a, npts, pin);
00235 csa_calculatespline(a);
00236 csa_approximate_points(a, nptsg, pgrid);
00237
00238 for(i=0; i<nptsx; i++) {
00239 for(j=0; j<nptsy; j++) {
00240 pt = &pgrid[j*nptsx + i];
00241 zg[i][j] = (PLFLT) pt->z;
00242 }
00243 }
00244
00245 csa_destroy(a);
00246 free(pin);
00247 free(pgrid);
00248 }
00249 #endif
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 static void
00260 grid_nnidw (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00261 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg,
00262 int knn_order)
00263 {
00264 int i, j, k;
00265 PLFLT wi, nt;
00266
00267 if (knn_order > KNN_MAX_ORDER) {
00268 plabort("plgriddata(): GRID_NNIDW: knn_order too big");
00269 return;
00270 }
00271
00272 if (knn_order == 0) {
00273 plwarn("plgriddata(): GRID_NNIDW: knn_order must be specified with 'data' arg. Using 15");
00274 knn_order = 15;;
00275 }
00276
00277 for (i=0; i<nptsx; i++) {
00278 for (j=0; j<nptsy; j++) {
00279 dist1(xg[i], yg[j], x, y, npts, knn_order);
00280
00281 #ifdef GMS
00282
00283 md = items[0].dist;
00284 for (k=1; k<knn_order; k++)
00285 if (items[k].dist > md)
00286 md = items[k].dist;
00287 #endif
00288 zg[i][j] = 0.;
00289 nt = 0.;
00290
00291 for (k=0; k<knn_order; k++) {
00292 if(items[k].item == -1)
00293 continue;
00294 #ifdef GMS
00295 wi = (md - items[k].dist)/(md * items[k].dist);
00296 wi = wi*wi;
00297 #else
00298 wi = 1./(items[k].dist*items[k].dist);
00299 #endif
00300 zg[i][j] += wi * z[items[k].item];
00301 nt += wi;
00302 }
00303 if (nt != 0.)
00304 zg[i][j] /= nt;
00305 else
00306 zg[i][j] = NaN;
00307 }
00308 }
00309 }
00310
00311
00312
00313
00314
00315
00316
00317 static void
00318 grid_nnli (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00319 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg,
00320 PLFLT threshold)
00321 {
00322 PLFLT xx[4], yy[4], zz[4], t, A, B, C, D, d1, d2, d3, max_thick;
00323 int i, j, ii, excl, cnt, excl_item;
00324
00325 if (threshold == 0.) {
00326 plwarn("plgriddata(): GRID_NNLI: threshold must be specified with 'data' arg. Using 1.001");
00327 threshold = 1.001;
00328 } else if ( threshold > 2. || threshold < 1.) {
00329 plabort("plgriddata(): GRID_NNLI: 1. < threshold < 2.");
00330 return;
00331 }
00332
00333 for (i=0; i<nptsx; i++) {
00334 for (j=0; j<nptsy; j++) {
00335 dist1(xg[i], yg[j], x, y, npts, 3);
00336
00337
00338 for (ii=0; ii<3; ii++) {
00339 xx[ii] = x[items[ii].item];
00340 yy[ii] = y[items[ii].item];
00341 zz[ii] = z[items[ii].item];
00342 }
00343
00344 d1 = sqrt((xx[1]-xx[0])*(xx[1]-xx[0]) + (yy[1]-yy[0])*(yy[1]-yy[0]));
00345 d2 = sqrt((xx[2]-xx[1])*(xx[2]-xx[1]) + (yy[2]-yy[1])*(yy[2]-yy[1]));
00346 d3 = sqrt((xx[0]-xx[2])*(xx[0]-xx[2]) + (yy[0]-yy[2])*(yy[0]-yy[2]));
00347
00348 if (d1 == 0. || d2 == 0. || d3 == 0.) {
00349 zg[i][j] = NaN;
00350 continue;
00351 }
00352
00353
00354 if (d1 > d2) {
00355 t = d1; d1 = d2; d2 = t;
00356 }
00357
00358
00359 if (d2 > d3) {
00360 t = d2; d2 = d3; d3 = t;
00361 }
00362
00363 if ((d1+d2)/d3 < threshold) {
00364 zg[i][j] = NaN;
00365 } else {
00366
00367 A = yy[0]*(zz[1]-zz[2]) + yy[1]*(zz[2]-zz[0]) + yy[2]*(zz[0]-zz[1]);
00368 B = zz[0]*(xx[1]-xx[2]) + zz[1]*(xx[2]-xx[0]) + zz[2]*(xx[0]-xx[1]);
00369 C = xx[0]*(yy[1]-yy[2]) + xx[1]*(yy[2]-yy[0]) + xx[2]*(yy[0]-yy[1]);
00370 D = - A*xx[0] - B*yy[0] - C*zz[0];
00371
00372
00373 zg[i][j] = - xg[i]*A/C - yg[j]*B/C - D/C;
00374 }
00375 }
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 {
00388 for (i=0; i<nptsx; i++) {
00389 for (j=0; j<nptsy; j++) {
00390
00391 if (isnan(zg[i][j])) {
00392 dist1(xg[i], yg[j], x, y, npts, 4);
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 max_thick = 0.; excl_item = -1;
00407 for (excl=0; excl<4; excl++) {
00408
00409 cnt = 0;
00410 for (ii=0; ii<4; ii++) {
00411 if (ii != excl) {
00412 xx[cnt] = x[items[ii].item];
00413 yy[cnt] = y[items[ii].item];
00414 cnt++;
00415 }
00416 }
00417
00418 d1 = sqrt((xx[1]-xx[0])*(xx[1]-xx[0]) + (yy[1]-yy[0])*(yy[1]-yy[0]));
00419 d2 = sqrt((xx[2]-xx[1])*(xx[2]-xx[1]) + (yy[2]-yy[1])*(yy[2]-yy[1]));
00420 d3 = sqrt((xx[0]-xx[2])*(xx[0]-xx[2]) + (yy[0]-yy[2])*(yy[0]-yy[2]));
00421 if (d1 == 0. || d2 == 0. || d3 == 0.) continue;
00422
00423
00424 if (d1 > d2) {
00425 t = d1; d1 = d2; d2 = t;
00426 }
00427
00428 if (d2 > d3) {
00429 t = d2; d2 = d3; d3 = t;
00430 }
00431
00432 t = (d1+d2)/d3;
00433 if ( t > max_thick) {
00434 max_thick = t;
00435 excl_item = excl;
00436 }
00437 }
00438
00439 if (excl_item == -1)
00440 continue;
00441
00442
00443 cnt = 0;
00444 for (ii=0; ii<4; ii++) {
00445 if (ii != excl_item) {
00446 xx[cnt] = x[items[ii].item];
00447 yy[cnt] = y[items[ii].item];
00448 zz[cnt] = z[items[ii].item];
00449 cnt++;
00450 }
00451 }
00452
00453 A = yy[0]*(zz[1]-zz[2]) + yy[1]*(zz[2]-zz[0]) + yy[2]*(zz[0]-zz[1]);
00454 B = zz[0]*(xx[1]-xx[2]) + zz[1]*(xx[2]-xx[0]) + zz[2]*(xx[0]-xx[1]);
00455 C = xx[0]*(yy[1]-yy[2]) + xx[1]*(yy[2]-yy[0]) + xx[2]*(yy[0]-yy[1]);
00456 D = - A*xx[0] - B*yy[0] - C*zz[0];
00457
00458
00459 zg[i][j] = - xg[i]*A/C - yg[j]*B/C - D/C;
00460
00461 }
00462 }
00463 }
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472
00473
00474 static void
00475 grid_nnaidw (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00476 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg)
00477 {
00478 PLFLT d, nt;
00479 int i, j, k;
00480
00481 for (i=0; i<nptsx; i++) {
00482 for (j=0; j<nptsy; j++) {
00483 dist2(xg[i], yg[j], x, y, npts);
00484 zg[i][j] = 0.;
00485 nt = 0.;
00486 for (k=0; k<4; k++) {
00487 if (items[k].item != -1) {
00488 d = 1./(items[k].dist * items[k].dist);
00489 zg[i][j] += d * z[items[k].item];
00490 nt += d;
00491 }
00492 }
00493 if (nt == 0.)
00494 zg[i][j] = NaN;
00495 else
00496 zg[i][j] /= nt;
00497 }
00498 }
00499 }
00500
00501 #ifdef HAVE_QHULL
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513 static void
00514 grid_dtli(PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00515 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg)
00516 {
00517 point *pin, *pgrid, *pt;
00518 PLFLT *xt, *yt, *zt;
00519 int i, j, nptsg;
00520
00521 if (sizeof(realT) != sizeof(double)) {
00522 plabort("plgridata: QHull was compiled for floats instead of doubles");
00523 return;
00524 }
00525
00526 if ((pin = (point *) malloc(npts * sizeof(point)))==NULL)
00527 {
00528 plexit("grid_dtli: Insufficient memory");
00529 }
00530
00531 xt = x; yt = y; zt = z; pt = pin;
00532 for(i=0; i<npts; i++) {
00533 pt->x = (double) *xt++;
00534 pt->y = (double) *yt++;
00535 pt->z = (double) *zt++;
00536 pt++;
00537 }
00538
00539 nptsg = nptsx * nptsy;
00540
00541 if ((pgrid = (point *) malloc(nptsg * sizeof(point)))==NULL)
00542 {
00543 plexit("grid_dtli: Insufficient memory");
00544 }
00545
00546 yt = yg; pt = pgrid;
00547 for(j=0; j<nptsy; j++) {
00548 xt = xg;
00549 for(i=0; i<nptsx; i++) {
00550 pt->x = (double) *xt++;
00551 pt->y = (double) *yt;
00552 pt++;
00553 }
00554 yt++;
00555 }
00556
00557 lpi_interpolate_points(npts, pin, nptsg, pgrid);
00558 for(i=0; i<nptsx; i++) {
00559 for(j=0; j<nptsy; j++) {
00560 pt = &pgrid[j*nptsx + i];
00561 zg[i][j] = (PLFLT) pt->z;
00562 }
00563 }
00564
00565 free(pin);
00566 free(pgrid);
00567 }
00568
00569
00570
00571
00572
00573
00574
00575
00576 static void
00577 grid_nni (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00578 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg,
00579 PLFLT wmin)
00580 {
00581 PLFLT *xt, *yt, *zt;
00582 point *pin, *pgrid, *pt;
00583 int i, j, nptsg;
00584 nn_rule = NON_SIBSONIAN;
00585
00586 if (sizeof(realT) != sizeof(double)) {
00587 plabort("plgridata: QHull was compiled for floats instead of doubles");
00588 return;
00589 }
00590
00591 if (wmin == 0.) {
00592 plwarn("plgriddata(): GRID_NNI: wmin must be specified with 'data' arg. Using -PLFLT_MAX");
00593 wmin = -PLFLT_MAX;
00594 }
00595
00596 if ((pin = (point *) malloc(npts * sizeof(point)))==NULL)
00597 {
00598 plexit("plgridata: Insufficient memory");
00599 }
00600
00601 xt = x; yt = y; zt = z; pt = pin;
00602 for(i=0; i<npts; i++) {
00603 pt->x = (double) *xt++;
00604 pt->y = (double) *yt++;
00605 pt->z = (double) *zt++;
00606 pt++;
00607 }
00608
00609 nptsg = nptsx * nptsy;
00610
00611 if ((pgrid = (point *) malloc(nptsg * sizeof(point)))==NULL)
00612 {
00613 plexit("plgridata: Insufficient memory");
00614 }
00615
00616 yt = yg; pt = pgrid;
00617 for(j=0; j<nptsy; j++) {
00618 xt = xg;
00619 for(i=0; i<nptsx; i++) {
00620 pt->x = (double) *xt++;
00621 pt->y = (double) *yt;
00622 pt++;
00623 }
00624 yt++;
00625 }
00626
00627 nnpi_interpolate_points(npts, pin, wmin, nptsg, pgrid);
00628 for(i=0; i<nptsx; i++) {
00629 for(j=0; j<nptsy; j++) {
00630 pt = &pgrid[j*nptsx + i];
00631 zg[i][j] = (PLFLT) pt->z;
00632 }
00633 }
00634
00635 free(pin);
00636 free(pgrid);
00637 }
00638 #endif
00639
00640
00641
00642
00643
00644
00645 static void
00646 dist1(PLFLT gx, PLFLT gy, PLFLT *x, PLFLT *y, int npts, int knn_order)
00647 {
00648
00649 PLFLT d, max_dist;
00650 int max_slot, i, j;
00651
00652 max_dist = PLFLT_MAX;
00653 max_slot = 0;
00654
00655 for (i=0; i<knn_order; i++) {
00656 items[i].dist = PLFLT_MAX;
00657 items[i].item = -1;
00658 }
00659
00660 for (i=0; i<npts; i++) {
00661 d = ((gx - x[i])*(gx - x[i]) + (gy - y[i])*(gy - y[i]));
00662
00663 if (d < max_dist) {
00664
00665
00666
00667
00668 items[max_slot].dist = d;
00669 items[max_slot].item = i;
00670
00671
00672 max_dist = items[0].dist;
00673 max_slot = 0;
00674 for (j=1; j<knn_order; j++) {
00675 if (items[j].dist > max_dist) {
00676 max_dist = items[j].dist;
00677 max_slot = j;
00678 }
00679 }
00680 }
00681 }
00682 for (j=0; j<knn_order; j++)
00683 items[j].dist = sqrt(items[j].dist);
00684 }
00685
00686
00687
00688
00689
00690
00691 static void
00692 dist2(PLFLT gx, PLFLT gy, PLFLT *x, PLFLT *y, int npts)
00693 {
00694
00695 PLFLT d;
00696 int i, quad;
00697
00698 for (i=0; i<4; i++) {
00699 items[i].dist = PLFLT_MAX;
00700 items[i].item = -1;
00701 }
00702
00703 for (i=0; i<npts; i++) {
00704 d = ((gx - x[i])*(gx - x[i]) + (gy - y[i])*(gy - y[i]));
00705
00706
00707
00708
00709
00710 quad = 2*(x[i] > gx) + (y[i] < gy);
00711
00712
00713
00714
00715
00716 if (d < items[quad].dist) {
00717 items[quad].dist = d;
00718 items[quad].item = i;
00719 }
00720 }
00721
00722 for (i=0; i<4; i++)
00723 if (items[i].item != -1)
00724 items[i].dist = sqrt(items[i].dist);
00725 }
00726
00727 #ifdef NONN
00728 static void
00729 grid_adtli (PLFLT *x, PLFLT *y, PLFLT *z, int npts,
00730 PLFLT *xg, int nptsx, PLFLT *yg, int nptsy, PLFLT **zg)
00731 {
00732 coordT *points;
00733 boolT ismalloc = False;
00734 char flags[250];
00735 facetT *facet;
00736 vertexT *vertex, **vertexp;
00737 facetT *neighbor,**neighborp;
00738 int curlong, totlong;
00739 FILE *outfile = NULL;
00740 FILE *errfile = stderr;
00741
00742 int exitcode;
00743 int i, j, k, l;
00744 int dim = 2;
00745 PLFLT xt[3], yt[3], zt[3];
00746 PLFLT A, B, C, D;
00747 coordT point[3];
00748 boolT isoutside;
00749 realT bestdist;
00750 int totpart=0;
00751 int numfacets, numsimplicial, numridges;
00752 int totneighbors, numcoplanars, numtricoplanars;
00753
00754 plwarn("plgriddata: GRID_DTLI, If you have QHull knowledge, FIXME.");
00755
00756
00757
00758 strcpy(flags, "qhull d Qbb Qt", 250);
00759
00760 if ((points = (coordT *) malloc(npts * (dim+1) * sizeof(coordT)))==NULL)
00761 {
00762 plexit("grid_adtli: Insufficient memory");
00763 }
00764
00765 for (i=0; i<npts; i++) {
00766 points[i*dim] = x[i];
00767 points[i*dim+1] = y[i];
00768 }
00769
00770 #if 1
00771 exitcode = qh_new_qhull (dim, npts, points, ismalloc,
00772 flags, outfile, errfile);
00773 #else
00774 qh_init_A (stdin, stdout, stderr, 0, NULL);
00775 exitcode = setjmp (qh errexit);
00776 if (!exitcode) {
00777 qh_initflags (flags);
00778 qh PROJECTdelaunay = True;
00779 qh_init_B (points, npts, dim, ismalloc);
00780 qh_qhull();
00781 }
00782 #endif
00783 if (!exitcode) {
00784
00785 #if 0
00786 printf("Triangles\n");
00787 FORALLfacets {
00788 if (!facet->upperdelaunay) {
00789 FOREACHvertex_(facet->vertices)
00790 printf (" %d", qh_pointid (vertex->point));
00791 printf ("\n");
00792 }
00793 }
00794 #endif
00795
00796 #if 0
00797 printf("Neigbors\n");
00798
00799 qh_findgood_all (qh facet_list);
00800 qh_countfacets (qh facet_list, NULL, !qh_ALL, &numfacets, &numsimplicial,
00801 &totneighbors, &numridges, &numcoplanars, &numtricoplanars);
00802
00803 FORALLfacets {
00804 if (!facet->upperdelaunay) {
00805 FOREACHneighbor_(facet)
00806 printf (" %d", neighbor->visitid ? neighbor->visitid - 1: - neighbor->id);
00807 printf ("\n");
00808 }
00809 }
00810 #endif
00811
00812
00813 exitcode = setjmp (qh errexit);
00814 if (!exitcode) {
00815 qh NOerrexit= False;
00816 for(i=0; i<nptsx; i++)
00817 for(j=0; j<nptsy; j++){
00818 l = 0;
00819 point[0] = xg[i];
00820 point[1] = yg[j];
00821 qh_setdelaunay (3, 1, point);
00822
00823
00824
00825
00826 #if 0
00827 facet = qh_findbestfacet (point, qh_ALL, &bestdist, &isoutside);
00828 #endif
00829
00830 #if 0
00831 facet = qh_findbest (point, qh facet_list, qh_ALL,
00832 !qh_ISnewfacets, qh_NOupper,
00833 &bestdist, &isoutside, &totpart);
00834 #endif
00835
00836 #if 0
00837 vertex = qh_nearvertex (facet, point, &bestdist);
00838 #endif
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853 facet = qh_findfacet_all( point, &bestdist, &isoutside, &totpart );
00854
00855 if (facet->upperdelaunay)
00856 zg[i][j] = NaN;
00857 else {
00858 FOREACHvertex_(facet->vertices) {
00859 k = qh_pointid(vertex->point);
00860 xt[l] = x[k];
00861 yt[l] = y[k];
00862 zt[l] = z[k];
00863 l++;
00864 }
00865
00866
00867
00868 A = yt[0]*(zt[1]-zt[2]) + yt[1]*(zt[2]-zt[0]) + yt[2]*(zt[0]-zt[1]);
00869 B = zt[0]*(xt[1]-xt[2]) + zt[1]*(xt[2]-xt[0]) + zt[2]*(xt[0]-xt[1]);
00870 C = xt[0]*(yt[1]-yt[2]) + xt[1]*(yt[2]-yt[0]) + xt[2]*(yt[0]-yt[1]);
00871 D = - A*xt[0] - B*yt[0] - C*zt[0];
00872
00873
00874 zg[i][j] = - xg[i]*A/C - yg[j]*B/C - D/C;
00875
00876 }
00877 }
00878 }
00879 qh NOerrexit= True;
00880 }
00881
00882 free(points);
00883 qh_freeqhull(!qh_ALL);
00884 qh_memfreeshort (&curlong, &totlong);
00885 if (curlong || totlong)
00886 fprintf (errfile,
00887 "qhull: did not free %d bytes of long memory (%d pieces)\n",
00888 totlong, curlong);
00889 }
00890 #endif