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
00029
00030 #define BINC 50
00031
00032 static PLINT pl3mode = 0;
00033 static PLINT pl3upv = 1;
00034
00035 static PLINT zbflg = 0, zbcol, zbwidth;
00036 static PLFLT zbtck;
00037
00038 static PLINT *oldhiview = NULL;
00039 static PLINT *oldloview = NULL;
00040 static PLINT *newhiview = NULL;
00041 static PLINT *newloview = NULL;
00042 static PLINT *utmp = NULL;
00043 static PLINT *vtmp = NULL;
00044 static PLFLT *ctmp = NULL;
00045
00046 static PLINT mhi, xxhi, newhisize;
00047 static PLINT mlo, xxlo, newlosize;
00048
00049
00050 static PLFLT xlight, ylight, zlight;
00051 static PLINT falsecolor=0;
00052 static PLFLT fc_minz, fc_maxz;
00053
00054
00055
00056 static void plgrid3 (PLFLT);
00057 static void plnxtv (PLINT *, PLINT *, PLFLT*, PLINT, PLINT);
00058 static void plside3 (PLFLT *, PLFLT *, PLFLT **, PLINT, PLINT, PLINT);
00059 static void plt3zz (PLINT, PLINT, PLINT, PLINT,
00060 PLINT, PLINT *, PLFLT *, PLFLT *, PLFLT **,
00061 PLINT, PLINT, PLINT *, PLINT *, PLFLT*);
00062 static void plnxtvhi (PLINT *, PLINT *, PLFLT*, PLINT, PLINT);
00063 static void plnxtvlo (PLINT *, PLINT *, PLFLT*, PLINT, PLINT);
00064 static void plnxtvhi_draw(PLINT *u, PLINT *v, PLFLT* c, PLINT n);
00065
00066 static void savehipoint (PLINT, PLINT);
00067 static void savelopoint (PLINT, PLINT);
00068 static void swaphiview (void);
00069 static void swaploview (void);
00070 static void myexit (char *);
00071 static void myabort (char *);
00072 static void freework (void);
00073 static int plabv (PLINT, PLINT, PLINT, PLINT, PLINT, PLINT);
00074 static void pl3cut (PLINT, PLINT, PLINT, PLINT, PLINT,
00075 PLINT, PLINT, PLINT, PLINT *, PLINT *);
00076 static PLFLT plGetAngleToLight(PLFLT* x, PLFLT* y, PLFLT* z);
00077 static void plP_draw3d(PLINT x, PLINT y, PLFLT *c, PLINT j, PLINT move);
00078 static void plxyindexlimits(PLINT instart, PLINT inn,
00079 PLINT *inarray_min, PLINT *inarray_max,
00080 PLINT *outstart, PLINT *outn, PLINT outnmax,
00081 PLINT *outarray_min, PLINT *outarray_max);
00082
00083
00084
00085 #if MJL_HACK
00086 static void plP_fill3(PLINT x0, PLINT y0, PLINT x1, PLINT y1,
00087 PLINT x2, PLINT y2, PLINT j);
00088 static void plP_fill4(PLINT x0, PLINT y0, PLINT x1, PLINT y1,
00089 PLINT x2, PLINT y2, PLINT x3, PLINT y3, PLINT j);
00090 #endif
00091
00092
00093
00094
00095
00096
00097
00098 void
00099 c_pllightsource(PLFLT x, PLFLT y, PLFLT z)
00100 {
00101 xlight = x;
00102 ylight = y;
00103 zlight = z;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 void
00116 c_plmesh(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny, PLINT opt)
00117 {
00118 c_plot3dc(x, y, z, nx, ny, opt | MESH, NULL, 0);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 void
00141 c_plmeshc(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny, PLINT opt,
00142 PLFLT *clevel, PLINT nlevel)
00143 {
00144 c_plot3dc(x, y, z, nx, ny, opt | MESH, clevel, nlevel);
00145 }
00146
00147
00148
00149 int
00150 plP_clip_poly(int Ni, PLFLT *Vi[3], int axis, PLFLT dir, PLFLT offset)
00151 {
00152 int anyout = 0;
00153 PLFLT in[PL_MAXPOLY], T[3][PL_MAXPOLY];
00154 int No = 0;
00155 int i, j, k;
00156
00157 for(i=0; i<Ni; i++) {
00158 in[i] = Vi[axis][i] * dir + offset;
00159 anyout += in[i] < 0;
00160 }
00161
00162
00163 if(anyout == 0)
00164 return Ni;
00165
00166
00167 if(anyout == Ni) {
00168 return 0;
00169 }
00170
00171
00172
00173 for(i=0; i<3; i++) {
00174 for(j=0; j<Ni; j++) {
00175 T[i][j] = Vi[i][j];
00176 }
00177 }
00178
00179 for(i=0; i<Ni; i++) {
00180 j = (i+1) % Ni;
00181
00182 if(in[i]>=0 && in[j]>=0) {
00183 for(k=0; k<3; k++)
00184 Vi[k][No] = T[k][j];
00185 No++;
00186 } else if(in[i]>=0 && in[j]<0) {
00187 PLFLT u = in[i] / (in[i] - in[j]);
00188 for(k = 0; k<3; k++)
00189 Vi[k][No] = T[k][i]*(1-u) + T[k][j]*u;
00190 No++;
00191 } else if(in[i]<0 && in[j]>=0) {
00192 PLFLT u = in[i] / (in[i] - in[j]);
00193 for(k = 0; k<3; k++)
00194 Vi[k][No] = T[k][i]*(1-u) + T[k][j]*u;
00195 No++;
00196 for(k=0; k<3; k++)
00197 Vi[k][No] = T[k][j];
00198 No++;
00199 }
00200 }
00201 return No;
00202 }
00203
00204
00205 static void
00206 shade_triangle(PLFLT x0, PLFLT y0, PLFLT z0,
00207 PLFLT x1, PLFLT y1, PLFLT z1,
00208 PLFLT x2, PLFLT y2, PLFLT z2)
00209 {
00210 int i;
00211
00212 short u[6], v[6];
00213 PLFLT x[6], y[6], z[6];
00214 int n;
00215 PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale;
00216 PLFLT *V[3];
00217
00218 plP_gdom(&xmin, &xmax, &ymin, &ymax);
00219 plP_grange(&zscale, &zmin, &zmax);
00220
00221 x[0] = x0; x[1] = x1; x[2] = x2;
00222 y[0] = y0; y[1] = y1; y[2] = y2;
00223 z[0] = z0; z[1] = z1; z[2] = z2;
00224 n = 3;
00225
00226 V[0] = x; V[1] = y; V[2] = z;
00227
00228 n = plP_clip_poly(n, V, 0, 1, -xmin);
00229 n = plP_clip_poly(n, V, 0, -1, xmax);
00230 n = plP_clip_poly(n, V, 1, 1, -ymin);
00231 n = plP_clip_poly(n, V, 1, -1, ymax);
00232 n = plP_clip_poly(n, V, 2, 1, -zmin);
00233 n = plP_clip_poly(n, V, 2, -1, zmax);
00234
00235 if(n > 0) {
00236 if (falsecolor)
00237 plcol1(((z[0] + z[1] + z[2]) /3. - fc_minz) / (fc_maxz - fc_minz));
00238 else
00239 plcol1(plGetAngleToLight(x, y, z));
00240
00241 for(i=0; i<n; i++) {
00242 u[i] = plP_wcpcx(plP_w3wcx(x[i], y[i], z[i]));
00243 v[i] = plP_wcpcy(plP_w3wcy(x[i], y[i], z[i]));
00244 }
00245 u[n] = u[0];
00246 v[n] = v[0];
00247
00248 #ifdef SHADE_DEBUG
00249 plcol0(1);
00250 x[3]=x[0]; y[3]=y[0]; z[3]=z[0];
00251 plline3(4,x,y,z);
00252 #else
00253 plP_fill(u, v, n+1);
00254 #endif
00255 }
00256 }
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 void
00268 c_plsurf3d(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny,
00269 PLINT opt, PLFLT *clevel, PLINT nlevel)
00270 {
00271 PLINT i;
00272 PLINT *indexymin = (PLINT *) malloc((size_t) (nx*sizeof(PLINT)));
00273 PLINT *indexymax = (PLINT *) malloc((size_t) (nx*sizeof(PLINT)));
00274
00275 if ( ! indexymin || ! indexymax)
00276 plexit("plsurf3d: Out of memory.");
00277 for (i = 0; i < nx; i++) {
00278 indexymin[i] = 0;
00279 indexymax[i] = ny;
00280 }
00281 c_plsurf3dl(x, y, z, nx, ny, opt, clevel, nlevel,
00282 0, nx, indexymin, indexymax);
00283 free_mem(indexymin);
00284 free_mem(indexymax);
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 void
00322 c_plsurf3dl(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny,
00323 PLINT opt, PLFLT *clevel, PLINT nlevel,
00324 PLINT ixstart, PLINT ixn, PLINT *indexymin, PLINT *indexymax)
00325 {
00326 PLFLT cxx, cxy, cyx, cyy, cyz;
00327 PLINT i, j, k;
00328 PLINT ixDir, ixOrigin, iyDir, iyOrigin, nFast, nSlow;
00329 PLINT ixFast, ixSlow, iyFast, iySlow;
00330 PLINT iFast, iSlow;
00331 PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale;
00332 PLFLT xm, ym, zm;
00333 PLINT ixmin=0, ixmax=nx, iymin=0, iymax=ny;
00334 PLFLT xx[3],yy[3],zz[3];
00335 PLFLT px[4], py[4], pz[4];
00336 CONT_LEVEL *cont, *clev;
00337 CONT_LINE *cline;
00338 int ct, ix, iy, iftriangle;
00339 PLINT color = plsc->icol0, width = plsc->width;
00340
00341 if (plsc->level < 3) {
00342 myabort("plsurf3dl: Please set up window first");
00343 return;
00344 }
00345
00346 if (nx <= 0 || ny <= 0) {
00347 myabort("plsurf3dl: Bad array dimensions.");
00348 return;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358 fc_minz = plsc->ranmi;
00359 fc_maxz = plsc->ranma;
00360 if (fc_maxz == fc_minz) {
00361 plwarn("plsurf3dl: Maximum and minimum Z values are equal! \"fixing\"...");
00362 fc_maxz = fc_minz + 1e-6;
00363 }
00364
00365 if (opt & MAG_COLOR)
00366 falsecolor = 1;
00367 else
00368 falsecolor = 0;
00369
00370 plP_gdom(&xmin, &xmax, &ymin, &ymax);
00371 plP_grange(&zscale, &zmin, &zmax);
00372 if(zmin > zmax) {
00373 PLFLT t = zmin;
00374 zmin = zmax;
00375 zmax = t;
00376 }
00377
00378
00379
00380 for (i = 0; i < nx - 1; i++) {
00381 if (x[i] >= x[i + 1]) {
00382 myabort("plsurf3dl: X array must be strictly increasing");
00383 return;
00384 }
00385 if (x[i] < xmin && x[i+1] >= xmin)
00386 ixmin = i;
00387 if (x[i+1] > xmax && x[i] <= xmax)
00388 ixmax = i+2;
00389 }
00390 for (i = 0; i < ny - 1; i++) {
00391 if (y[i] >= y[i + 1]) {
00392 myabort("plsurf3dl: Y array must be strictly increasing");
00393 return;
00394 }
00395 if (y[i] < ymin && y[i+1] >= ymin)
00396 iymin = i;
00397 if (y[i+1] > ymax && y[i] <= ymax)
00398 iymax = i+2;
00399 }
00400
00401
00402 plP_gw3wc(&cxx, &cxy, &cyx, &cyy, &cyz);
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 if(cxy >= 0) {
00414 ixDir = 1;
00415 ixOrigin = ixmin;
00416 } else {
00417 ixDir = -1;
00418 ixOrigin = ixmax - 1;
00419 }
00420
00421 if(cxx >= 0) {
00422 iyDir = -1;
00423 iyOrigin = iymax - 1;
00424 } else {
00425 iyDir = 1;
00426 iyOrigin = iymin;
00427 }
00428
00429 if (fabs(cxx) > fabs(cxy)) {
00430
00431 nFast = ixmax - ixmin;
00432 nSlow = iymax - iymin;
00433
00434 ixFast = ixDir; ixSlow = 0;
00435 iyFast = 0; iySlow = iyDir;
00436 } else {
00437 nFast = iymax - iymin;
00438 nSlow = ixmax - ixmin;
00439
00440 ixFast = 0; ixSlow = ixDir;
00441 iyFast = iyDir; iySlow = 0;
00442 }
00443
00444
00445 if (zbflg) {
00446 PLFLT bx[3], by[3], bz[3];
00447 PLFLT tick=zbtck, tp;
00448 PLINT nsub=0;
00449
00450
00451 pldtik(zmin, zmax, &tick, &nsub, FALSE);
00452
00453
00454 bx[0] = (ixOrigin!=ixmin && ixFast==0) || ixFast > 0 ? xmax : xmin;
00455 by[0] = (iyOrigin!=iymin && iyFast==0) || iyFast > 0 ? ymax : ymin;
00456 bx[1] = ixOrigin!=ixmin ? xmax : xmin;
00457 by[1] = iyOrigin!=iymin ? ymax : ymin;
00458 bx[2] = (ixOrigin!=ixmin && ixSlow==0) || ixSlow > 0 ? xmax : xmin;
00459 by[2] = (iyOrigin!=iymin && iySlow==0) || iySlow > 0 ? ymax : ymin;
00460
00461 plwid(zbwidth);
00462 plcol0(zbcol);
00463 for(tp = tick * floor(zmin / tick) + tick; tp <= zmax; tp += tick) {
00464 bz[0] = bz[1] = bz[2] = tp;
00465 plline3(3, bx, by, bz);
00466 }
00467
00468 bx[0] = bx[1];
00469 by[0] = by[1];
00470 bz[0] = zmin;
00471 plline3(2, bx, by, bz);
00472 plwid(width);
00473 plcol0(color);
00474 }
00475
00476
00477
00478
00479
00480
00481
00482
00483 if (clevel != NULL && opt & BASE_CONT) {
00484 #define NPTS 100
00485 int np = NPTS;
00486 PLFLT **zstore;
00487 PLcGrid2 cgrid2;
00488 PLFLT *zz = (PLFLT *) malloc(NPTS*sizeof(PLFLT));
00489 if (zz==NULL) plexit("plsurf3dl: Insufficient memory");
00490
00491
00492
00493
00494 cgrid2.nx = nx;
00495 cgrid2.ny = ny;
00496 plAlloc2dGrid(&cgrid2.xg, nx, ny);
00497 plAlloc2dGrid(&cgrid2.yg, nx, ny);
00498 plAlloc2dGrid(&zstore, nx, ny);
00499
00500 for (i = ixstart; i < ixn; i++) {
00501 for (j = 0; j < indexymin[i]; j++) {
00502 cgrid2.xg[i][j] = x[i];
00503 cgrid2.yg[i][j] = y[indexymin[i]];
00504 zstore[i][j] = z[i][indexymin[i]];
00505 }
00506 for (j = indexymin[i]; j < indexymax[i]; j++) {
00507 cgrid2.xg[i][j] = x[i];
00508 cgrid2.yg[i][j] = y[j];
00509 zstore[i][j] = z[i][j];
00510 }
00511 for (j = indexymax[i]; j < ny; j++) {
00512 cgrid2.xg[i][j] = x[i];
00513 cgrid2.yg[i][j] = y[indexymax[i]-1];
00514 zstore[i][j] = z[i][indexymax[i]-1];
00515 }
00516 }
00517
00518 cont_store(zstore, nx, ny, ixstart+1, ixn, 1, ny,
00519 clevel, nlevel, pltr2, (void *) &cgrid2, &cont);
00520
00521
00522 plFree2dGrid(zstore, nx, ny);
00523 plFree2dGrid(cgrid2.xg, nx, ny);
00524 plFree2dGrid(cgrid2.yg, nx, ny);
00525
00526
00527 clev = cont;
00528 do {
00529 cline = clev->line;
00530 do {
00531 if (cline->npts > np) {
00532 np = cline->npts;
00533 if ((zz = (PLFLT *) realloc(zz, np*sizeof(PLFLT)))==NULL)
00534 {
00535 plexit("c_plsurf3dl: Insufficient memory");
00536 }
00537 }
00538 for (j=0; j<cline->npts; j++)
00539 zz[j] = plsc->ranmi;
00540 if (cline->npts > 0) {
00541 plcol1((clev->level-fc_minz)/(fc_maxz-fc_minz));
00542 plline3(cline->npts, cline->x, cline->y, zz);
00543 }
00544 cline = cline->next;
00545 }
00546 while(cline != NULL);
00547 clev = clev->next;
00548 }
00549 while(clev != NULL);
00550
00551 cont_clean_store(cont);
00552 free(zz);
00553 }
00554
00555
00556 for(iSlow=0; iSlow < nSlow-1; iSlow++) {
00557 for(iFast=0; iFast < nFast-1; iFast++) {
00558
00559
00560
00561
00562
00563
00564
00565 xm = ym = zm = 0.;
00566
00567 iftriangle = 1;
00568 for(i=0; i<2; i++) {
00569 for(j=0; j<2; j++) {
00570
00571
00572 ix = ixFast * (iFast+i) + ixSlow * (iSlow+j) + ixOrigin;
00573 iy = iyFast * (iFast+i) + iySlow * (iSlow+j) + iyOrigin;
00574
00575 if (ixstart <= ix && ix < ixn &&
00576 indexymin[ix] <= iy && iy < indexymax[ix]) {
00577 xm += px[2*i+j] = x[ix];
00578 ym += py[2*i+j] = y[iy];
00579 zm += pz[2*i+j] = z[ix][iy];
00580 }
00581 else {
00582 iftriangle = 0;
00583 break;
00584 }
00585 }
00586 if (iftriangle == 0)
00587 break;
00588 }
00589
00590 if (iftriangle == 0)
00591 continue;
00592
00593
00594
00595 xm /= 4.; ym /= 4.; zm /= 4.;
00596
00597
00598
00599 for (i=1; i<3; i++) {
00600 for (j=0; j<4; j+=3) {
00601 shade_triangle(px[j], py[j], pz[j], xm, ym, zm, px[i], py[i], pz[i]);
00602
00603
00604
00605 #define min3(a,b,c) (MIN((MIN(a,b)),c))
00606 #define max3(a,b,c) (MAX((MAX(a,b)),c))
00607
00608 if (clevel != NULL && (opt & SURF_CONT)) {
00609 for (k=0; k<nlevel; k++) {
00610 if (clevel[k] >= min3(pz[i],zm,pz[j]) && clevel[k] < max3(pz[i],zm,pz[j])) {
00611 ct = 0;
00612 if (clevel[k] >= MIN(pz[i],zm) && clevel[k] < MAX(pz[i],zm)) {
00613 xx[ct] = ((clevel[k] - pz[i])*(xm-px[i]))/(zm-pz[i]) + px[i];
00614 yy[ct] = ((clevel[k] - pz[i])*(ym-py[i]))/(zm-pz[i]) + py[i];
00615 ct++;
00616 }
00617
00618 if (clevel[k] >= MIN(pz[i],pz[j]) && clevel[k] < MAX(pz[i],pz[j])) {
00619 xx[ct] = ((clevel[k] - pz[i])*(px[j]-px[i]))/(pz[j]-pz[i]) + px[i];
00620 yy[ct] = ((clevel[k] - pz[i])*(py[j]-py[i]))/(pz[j]-pz[i]) + py[i];
00621 ct++;
00622 }
00623
00624 if (clevel[k] >= MIN(pz[j],zm) && clevel[k] < MAX(pz[j],zm)) {
00625 xx[ct] = ((clevel[k] - pz[j])*(xm-px[j]))/(zm-pz[j]) + px[j];
00626 yy[ct] = ((clevel[k] - pz[j])*(ym-py[j]))/(zm-pz[j]) + py[j];
00627 ct++;
00628 }
00629
00630 if (ct == 2) {
00631
00632
00633
00634
00635
00636 if (opt & SURF_CONT) {
00637
00638 plcol0(color);
00639 zz[0] = zz[1] = clevel[k];
00640 plline3(2, xx, yy, zz);
00641 }
00642
00643
00644
00645 } else
00646 plwarn("plsurf3dl: ***ERROR***\n");
00647 }
00648 }
00649 }
00650 }
00651 }
00652 }
00653 }
00654
00655 if (opt & FACETED) {
00656 plcol0(0);
00657 c_plot3dcl(x, y, z, nx, ny, MESH | DRAW_LINEXY, NULL, 0,
00658 ixstart, ixn, indexymin, indexymax);
00659 }
00660
00661 if (opt & DRAW_SIDES) {
00662
00663 PLFLT zscale, zmin, zmax;
00664
00665 plP_grange(&zscale, &zmin, &zmax);
00666
00667 iSlow = nSlow-1;
00668 iftriangle = 1;
00669 for(iFast=0; iFast < nFast-1; iFast++) {
00670 for(i=0; i<2; i++) {
00671 ix = ixFast * (iFast+i) + ixSlow * iSlow + ixOrigin;
00672 iy = iyFast * (iFast+i) + iySlow * iSlow + iyOrigin;
00673 if (ixstart <= ix && ix < ixn &&
00674 indexymin[ix] <= iy && iy < indexymax[ix]) {
00675 px[2*i] = x[ix];
00676 py[2*i] = y[iy];
00677 pz[2*i] = z[ix][iy];
00678 }
00679 else {
00680 iftriangle = 0;
00681 break;
00682 }
00683 }
00684 if (iftriangle == 0)
00685 break;
00686
00687
00688 shade_triangle(px[0], py[0], pz[0], px[2], py[2], pz[2], px[0], py[0], zmin);
00689 shade_triangle(px[2], py[2], pz[2], px[2], py[2], zmin, px[0], py[0], zmin);
00690 }
00691
00692 iFast = nFast-1;
00693 iftriangle = 1;
00694 for(iSlow=0; iSlow < nSlow-1; iSlow++) {
00695 for(i=0; i<2; i++) {
00696 ix = ixFast * iFast + ixSlow * (iSlow+i) + ixOrigin;
00697 iy = iyFast * iFast + iySlow * (iSlow+i) + iyOrigin;
00698 if (ixstart <= ix && ix < ixn &&
00699 indexymin[ix] <= iy && iy < indexymax[ix]) {
00700 px[2*i] = x[ix];
00701 py[2*i] = y[iy];
00702 pz[2*i] = z[ix][iy];
00703 }
00704 else {
00705 iftriangle = 0;
00706 break;
00707 }
00708 }
00709 if (iftriangle == 0)
00710 break;
00711
00712
00713 shade_triangle(px[0], py[0], pz[0], px[2], py[2], pz[2], px[0], py[0], zmin);
00714 shade_triangle(px[2], py[2], pz[2], px[2], py[2], zmin, px[0], py[0], zmin);
00715 }
00716 }
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728 void
00729 c_plot3d(PLFLT *x, PLFLT *y, PLFLT **z,
00730 PLINT nx, PLINT ny, PLINT opt, PLBOOL side)
00731 {
00732 c_plot3dc( x, y, z, nx, ny, opt | (side != 0 ? DRAW_SIDES : 0), NULL, 0);
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 void
00745 c_plot3dc(PLFLT *x, PLFLT *y, PLFLT **z,
00746 PLINT nx, PLINT ny, PLINT opt,
00747 PLFLT *clevel, PLINT nlevel)
00748 {
00749 c_plot3dcl( x, y, z, nx, ny, opt, clevel, nlevel, 0, 0, NULL, NULL);
00750 }
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775 void
00776 c_plot3dcl(PLFLT *x, PLFLT *y, PLFLT **z,
00777 PLINT nx, PLINT ny, PLINT opt,
00778 PLFLT *clevel, PLINT nlevel,
00779 PLINT ixstart, PLINT ixn, PLINT *indexymin, PLINT *indexymax)
00780 {
00781 PLFLT cxx, cxy, cyx, cyy, cyz;
00782 PLINT init, i, ix, iy, color, width;
00783 PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale;
00784 PLINT ixmin=0, ixmax=nx-1, iymin=0, iymax=ny-1;
00785 PLINT clipped = 0, base_cont = 0, side = 0;
00786
00787 pl3mode = 0;
00788
00789 if (plsc->level < 3) {
00790 myabort("plot3dcl: Please set up window first");
00791 return;
00792 }
00793
00794 if ((opt & 3) == 0) {
00795 myabort("plot3dcl: Bad option");
00796 return;
00797 }
00798
00799 if (nx <= 0 || ny <= 0) {
00800 myabort("plot3dcl: Bad array dimensions.");
00801 return;
00802 }
00803
00804 plP_gdom(&xmin, &xmax, &ymin, &ymax);
00805 plP_grange(&zscale, &zmin, &zmax);
00806 if(zmin > zmax) {
00807 PLFLT t = zmin;
00808 zmin = zmax;
00809 zmax = t;
00810 }
00811
00812
00813
00814 for (i = 0; i < nx - 1; i++) {
00815 if (x[i] >= x[i + 1]) {
00816 myabort("plot3dcl: X array must be strictly increasing");
00817 return;
00818 }
00819 }
00820 for (i = 0; i < ny - 1; i++) {
00821 if (y[i] >= y[i + 1]) {
00822 myabort("plot3dcl: Y array must be strictly increasing");
00823 return;
00824 }
00825 }
00826
00827 if (opt & MESH)
00828 pl3mode = 1;
00829
00830 if (opt & DRAW_SIDES)
00831 side = 1;
00832
00833
00834 if (xmin < x[0])
00835 xmin = x[0];
00836 if (xmax > x[nx-1])
00837 xmax = x[nx-1];
00838 if (ymin < y[0])
00839 ymin = y[0];
00840 if (ymax > y[ny-1])
00841 ymax = y[ny-1];
00842 for (ixmin = 0; ixmin < nx-1 && x[ixmin+1] < xmin; ixmin++) {}
00843 for (ixmax = nx-1; ixmax > 0 && x[ixmax-1] > xmax; ixmax--) {}
00844 for (iymin = 0; iymin < ny-1 && y[iymin+1] < ymin; iymin++) {}
00845 for (iymax = ny-1; iymax > 0 && y[iymax-1] > ymax; iymax--) {}
00846
00847
00848 if(ixmin > 0 || ixmax < nx-1 || iymin > 0 || iymax < ny-1) {
00849
00850 int _nx = ixmax - ixmin + 1;
00851 int _ny = iymax - iymin + 1;
00852 PLFLT *_x, *_y, **_z;
00853 PLFLT ty0, ty1, tx0, tx1;
00854 int i, j;
00855
00856 if(_nx <= 1 || _ny <= 1) {
00857 myabort("plot3dcl: selected x or y range has no data");
00858 return;
00859 }
00860
00861
00862 if (((_x = (PLFLT*)malloc(_nx * sizeof(PLFLT)))==NULL)||
00863 ((_y = (PLFLT*)malloc(_ny * sizeof(PLFLT)))==NULL)||
00864 ((_z = (PLFLT**)malloc(_nx * sizeof(PLFLT*)))==NULL))
00865 {
00866 plexit("c_plot3dcl: Insufficient memory");
00867 }
00868
00869 clipped = 1;
00870
00871
00872 _x[0] = xmin;
00873 _x[_nx-1] = xmax;
00874 for(i=1; i<_nx-1; i++)
00875 _x[i] = x[ixmin+i];
00876 _y[0] = ymin;
00877 _y[_ny-1] = ymax;
00878 for(i=1; i<_ny-1; i++)
00879 _y[i] = y[iymin+i];
00880
00881
00882 for(i=0; i<_nx; i++)
00883 {
00884 if ((_z[i] = (PLFLT*)malloc(_ny * sizeof(PLFLT)))==NULL)
00885 {
00886 plexit("c_plot3dcl: Insufficient memory");
00887 }
00888 }
00889
00890
00891 ty0 = (_y[0] - y[iymin]) / (y[iymin+1] - y[iymin]);
00892 ty1 = (_y[_ny-1] - y[iymax-1]) / (y[iymax] - y[iymax-1]);
00893 tx0 = (_x[0] - x[ixmin]) / (x[ixmin+1] - x[ixmin]);
00894 tx1 = (_x[_nx-1] - x[ixmax-1]) / (x[ixmax] - x[ixmax-1]);
00895 for(i=0; i<_nx; i++) {
00896 if(i==0) {
00897 _z[i][0] = z[ixmin][iymin]*(1-ty0)*(1-tx0) + z[ixmin][iymin+1]*(1-tx0)*ty0
00898 + z[ixmin+1][iymin]*tx0*(1-ty0) + z[ixmin+1][iymin+1]*tx0*ty0;
00899 for(j=1; j<_ny-1; j++)
00900 _z[i][j] = z[ixmin][iymin+j]*(1-tx0) + z[ixmin+1][iymin+j]*tx0;
00901 _z[i][_ny-1] = z[ixmin][iymax-1]*(1-tx0)*(1-ty1) + z[ixmin][iymax]*(1-tx0)*ty1
00902 + z[ixmin+1][iymax-1]*tx0*(1-ty1) + z[ixmin+1][iymax]*tx0*ty1;
00903 } else if(i==_nx-1) {
00904 _z[i][0] = z[ixmax-1][iymin]*(1-tx1)*(1-ty0) + z[ixmax-1][iymin+1]*(1-tx1)*ty0
00905 + z[ixmax][iymin]*tx1*(1-ty0) + z[ixmax][iymin+1]*tx1*ty0;
00906 for(j=1; j<_ny-1; j++)
00907 _z[i][j] = z[ixmax-1][iymin+j]*(1-tx1) + z[ixmax][iymin+j]*tx1;
00908 _z[i][_ny-1] = z[ixmax-1][iymax-1]*(1-tx1)*(1-ty1) + z[ixmax][iymax]*(1-tx1)*ty1
00909 + z[ixmax][iymax-1]*tx1*(1-ty1) + z[ixmax][iymax]*tx1*ty1;
00910 } else {
00911 _z[i][0] = z[ixmin+i][iymin]*(1-ty0) + z[ixmin+i][iymin+1]*ty0;
00912 for(j=1; j<_ny-1; j++)
00913 _z[i][j] = z[ixmin+i][iymin+j];
00914 _z[i][_ny-1] = z[ixmin+i][iymax-1]*(1-ty1) + z[ixmin+i][iymax]*ty1;
00915 }
00916 for(j=0; j<_ny; j++) {
00917 if(_z[i][j] < zmin)
00918 _z[i][j] = zmin;
00919 else if(_z[i][j] > zmax)
00920 _z[i][j] = zmax;
00921 }
00922 }
00923
00924 x = _x;
00925 y = _y;
00926 z = _z;
00927 nx = _nx;
00928 ny = _ny;
00929 }
00930
00931 if ((opt & BASE_CONT) || (opt & TOP_CONT) || (opt && MAG_COLOR)) {
00932
00933
00934
00935
00936
00937
00938
00939 fc_minz = plsc->ranmi;
00940 fc_maxz = plsc->ranma;
00941
00942 if (fc_maxz == fc_minz) {
00943 plwarn("plot3dcl: Maximum and minimum Z values are equal! \"fixing\"...");
00944 fc_maxz = fc_minz + 1e-6;
00945 }
00946 }
00947
00948 if (opt & BASE_CONT) {
00949 if (clevel != NULL && nlevel != 0) {
00950 base_cont = 1;
00951
00952
00953 pl3mode = 1;
00954 }
00955 }
00956
00957 if (opt & MAG_COLOR) {
00958 if ((ctmp = (PLFLT *) malloc((size_t) (2 * MAX(nx, ny) * sizeof(PLFLT))))==NULL)
00959 {
00960 plexit("c_plot3dcl: Insufficient memory");
00961 }
00962 } else
00963 ctmp = NULL;
00964
00965
00966 opt &= DRAW_LINEXY;
00967
00968
00969
00970 utmp = (PLINT *) malloc((size_t) (2 * MAX(nx, ny) * sizeof(PLINT)));
00971 vtmp = (PLINT *) malloc((size_t) (2 * MAX(nx, ny) * sizeof(PLINT)));
00972
00973 if ( ! utmp || ! vtmp)
00974 myexit("plot3dcl: Out of memory.");
00975
00976 plP_gw3wc(&cxx, &cxy, &cyx, &cyy, &cyz);
00977 init = 1;
00978
00979
00980
00981 if (cxx >= 0.0 && cxy <= 0.0) {
00982 if (opt == DRAW_LINEY)
00983 plt3zz(1, ny, 1, -1, -opt, &init, x, y, z, nx, ny, utmp, vtmp,ctmp);
00984 else {
00985 for (iy = 2; iy <= ny; iy++)
00986 plt3zz(1, iy, 1, -1, -opt, &init, x, y, z, nx, ny, utmp, vtmp,ctmp);
00987 }
00988 if (opt == DRAW_LINEX)
00989 plt3zz(1, ny, 1, -1, opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
00990 else {
00991 for (ix = 1; ix <= nx - 1; ix++)
00992 plt3zz(ix, ny, 1, -1, opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
00993 }
00994 }
00995
00996 else if (cxx <= 0.0 && cxy <= 0.0) {
00997 if (opt == DRAW_LINEX)
00998 plt3zz(nx, ny, -1, -1, opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
00999 else {
01000 for (ix = 2; ix <= nx; ix++)
01001 plt3zz(ix, ny, -1, -1, opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01002 }
01003 if (opt == DRAW_LINEY)
01004 plt3zz(nx, ny, -1, -1, -opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01005 else {
01006 for (iy = ny; iy >= 2; iy--)
01007 plt3zz(nx, iy, -1, -1, -opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01008 }
01009 }
01010
01011 else if (cxx <= 0.0 && cxy >= 0.0) {
01012 if (opt == DRAW_LINEY)
01013 plt3zz(nx, 1, -1, 1, -opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01014 else {
01015 for (iy = ny - 1; iy >= 1; iy--)
01016 plt3zz(nx, iy, -1, 1, -opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01017 }
01018 if (opt == DRAW_LINEX)
01019 plt3zz(nx, 1, -1, 1, opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01020 else {
01021 for (ix = nx; ix >= 2; ix--)
01022 plt3zz(ix, 1, -1, 1, opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01023 }
01024 }
01025
01026 else if (cxx >= 0.0 && cxy >= 0.0) {
01027 if (opt == DRAW_LINEX)
01028 plt3zz(1, 1, 1, 1, opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01029 else {
01030 for (ix = nx - 1; ix >= 1; ix--)
01031 plt3zz(ix, 1, 1, 1, opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01032 }
01033 if (opt == DRAW_LINEY)
01034 plt3zz(1, 1, 1, 1, -opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01035 else {
01036 for (iy = 1; iy <= ny - 1; iy++)
01037 plt3zz(1, iy, 1, 1, -opt, &init, x, y, z, nx, ny, utmp, vtmp, ctmp);
01038 }
01039 }
01040
01041
01042
01043 if (base_cont){
01044 int np = NPTS, j;
01045 CONT_LEVEL *cont, *clev;
01046 CONT_LINE *cline;
01047
01048 PLINT *uu = (PLINT *) malloc(NPTS*sizeof(PLINT));
01049 PLINT *vv = (PLINT *) malloc(NPTS*sizeof(PLINT));
01050
01051 PLFLT **zstore;
01052 PLcGrid2 cgrid2;
01053
01054 if ((uu==NULL)||(vv==NULL))
01055 {
01056 plexit("c_plot3dcl: Insufficient memory");
01057 }
01058
01059 cgrid2.nx = nx;
01060 cgrid2.ny = ny;
01061 plAlloc2dGrid(&cgrid2.xg, nx, ny);
01062 plAlloc2dGrid(&cgrid2.yg, nx, ny);
01063 plAlloc2dGrid(&zstore, nx, ny);
01064
01065 for (i = 0; i < nx; i++) {
01066 for (j = 0; j < ny; j++) {
01067 cgrid2.xg[i][j] = x[i];
01068 cgrid2.yg[i][j] = y[j];
01069 zstore[i][j] = z[i][j];
01070 }
01071 }
01072
01073 pl3upv = 0;
01074
01075
01076 cont_store(zstore, nx, ny, 1, nx, 1, ny,
01077 clevel, nlevel, pltr2, (void *) &cgrid2, &cont);
01078
01079
01080 plFree2dGrid(zstore, nx, ny);
01081 plFree2dGrid(cgrid2.xg, nx, ny);
01082 plFree2dGrid(cgrid2.yg, nx, ny);
01083
01084
01085 clev = cont;
01086 do {
01087 cline = clev->line;
01088 do {
01089 int cx, i, k, l, m, start, end;
01090 PLFLT tx, ty;
01091 if (cline->npts > np) {
01092 np = cline->npts;
01093 if (((uu = (PLINT *) realloc(uu, np*sizeof(PLINT)))==NULL)||
01094 ((vv = (PLINT *) realloc(vv, np*sizeof(PLINT)))==NULL))
01095 {
01096 plexit("c_plot3dcl: Insufficient memory");
01097 }
01098 }
01099
01100
01101
01102
01103 i = 0;
01104 if (cline->npts > 0) {
01105 do {
01106 plcol1((clev->level-fc_minz)/(fc_maxz-fc_minz));
01107 cx = plP_wcpcx(plP_w3wcx(cline->x[i],cline->y[i], plsc->ranmi));
01108 for (j=i; j < cline->npts; j++) {
01109 uu[j] = plP_wcpcx(plP_w3wcx(cline->x[j],cline->y[j], plsc->ranmi));
01110 vv[j] = plP_wcpcy(plP_w3wcy(cline->x[j],cline->y[j], plsc->ranmi));
01111 if (uu[j] < cx)
01112 break;
01113 else
01114 cx = uu[j];
01115 }
01116 plnxtv(&uu[i], &vv[i], NULL, j-i, 0);
01117
01118 if (j < cline->npts) {
01119 start = j-1;
01120 for (i = start; i < cline->npts; i++) {
01121 uu[i] = plP_wcpcx(plP_w3wcx(cline->x[i],cline->y[i], plsc->ranmi));
01122 if (uu[i] > cx)
01123 break;
01124 else
01125 cx = uu[i];
01126 }
01127 end = i-1;
01128
01129 for (k=0; k < (end-start+1)/2; k++) {
01130 l = start+k;
01131 m = end-k;
01132 tx = cline->x[l];
01133 ty = cline->y[l];
01134 cline->x[l] = cline->x[m];
01135 cline->y[l] = cline->y[m];
01136 cline->x[m] = tx;
01137 cline->y[m] = ty;
01138 }
01139
01140
01141 for (j=start; j <= end; j++) {
01142 uu[j] = plP_wcpcx(plP_w3wcx(cline->x[j],cline->y[j], plsc->ranmi));
01143 vv[j] = plP_wcpcy(plP_w3wcy(cline->x[j],cline->y[j], plsc->ranmi));
01144 }
01145 plnxtv(&uu[start], &vv[start], NULL, end-start+1, 0);
01146
01147 cline->x[end] = cline->x[start];
01148 cline->y[end] = cline->y[start];
01149 i = end;
01150 }
01151 } while (j < cline->npts && i < cline->npts);
01152 }
01153 cline = cline->next;
01154 }
01155 while(cline != NULL);
01156 clev = clev->next;
01157 }
01158 while(clev != NULL);
01159
01160 cont_clean_store(cont);
01161 pl3upv = 1;
01162 free(uu);
01163 free(vv);
01164 }
01165
01166
01167
01168 if (side)
01169 plside3(x, y, z, nx, ny, opt);
01170
01171 if (zbflg) {
01172 color = plsc->icol0;
01173 width = plsc->width;
01174 plwid(zbwidth);
01175 plcol0(zbcol);
01176 plgrid3(zbtck);
01177 plwid(width);
01178 plcol0(color);
01179 }
01180
01181 freework();
01182
01183 if(clipped) {
01184 free(x);
01185 free(y);
01186 for(i=0; i<nx; i++)
01187 free(z[i]);
01188 free(z);
01189 }
01190 }
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211 static void
01212 plxyindexlimits(PLINT instart, PLINT inn,
01213 PLINT *inarray_min, PLINT *inarray_max,
01214 PLINT *outstart, PLINT *outn, PLINT outnmax,
01215 PLINT *outarray_min, PLINT *outarray_max)
01216 {
01217 PLINT i, j;
01218 if (inn < 0) {
01219 myabort("plxyindexlimits: Must have instart >= 0");
01220 return;
01221 }
01222 if (inn - instart <= 0) {
01223 myabort("plxyindexlimits: Must have at least 1 defined point");
01224 return;
01225 }
01226 *outstart = inarray_min[instart];
01227 *outn = inarray_max[instart];
01228 for (i=instart; i<inn; i++) {
01229 *outstart = MIN(*outstart, inarray_min[i]);
01230 *outn = MAX(*outn, inarray_max[i]);
01231 if (i + 2 < inn) {
01232 if (inarray_min[i] < inarray_min[i+1] &&
01233 inarray_min[i+1] > inarray_min[i+2]) {
01234 myabort("plxyindexlimits: inarray_min must not have a maximum");
01235 return;
01236 }
01237 if (inarray_max[i] > inarray_max[i+1] &&
01238 inarray_max[i+1] < inarray_max[i+2]) {
01239 myabort("plxyindexlimits: inarray_max must not have a minimum");
01240 return;
01241 }
01242 }
01243 }
01244 if (*outstart < 0) {
01245 myabort("plxyindexlimits: Must have all elements of inarray_min >= 0");
01246 return;
01247 }
01248 if (*outn > outnmax) {
01249 myabort("plxyindexlimits: Must have all elements of inarray_max <= outnmax");
01250 return;
01251 }
01252 for (j=*outstart; j < *outn; j++) {
01253 i = instart;
01254
01255 while (i < inn && !(inarray_min[i] <= j && j < inarray_max[i]))
01256 i++;
01257 if (i < inn)
01258 outarray_min[j] = i;
01259 else {
01260 myabort("plxyindexlimits: bad logic; invalid i should never happen");
01261 return;
01262 }
01263
01264 while (i < inn && (inarray_min[i] <= j && j < inarray_max[i]))
01265 i++;
01266 outarray_max[j] = i;
01267 }
01268 }
01269
01270
01271
01272
01273
01274
01275
01276 void
01277 plP_gzback(PLINT **zbf, PLINT **zbc, PLFLT **zbt, PLINT **zbw)
01278 {
01279 *zbf = &zbflg;
01280 *zbc = &zbcol;
01281 *zbt = &zbtck;
01282 *zbw = &zbwidth;
01283 }
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293 static PLFLT
01294 plGetAngleToLight(PLFLT* x, PLFLT* y, PLFLT* z)
01295 {
01296 PLFLT vx1, vx2, vy1, vy2, vz1, vz2;
01297 PLFLT px, py, pz;
01298 PLFLT vlx, vly, vlz;
01299 PLFLT mag1, mag2;
01300 PLFLT cosangle;
01301
01302 vx1 = x[1] - x[0];
01303 vx2 = x[2] - x[1];
01304 vy1 = y[1] - y[0];
01305 vy2 = y[2] - y[1];
01306 vz1 = z[1] - z[0];
01307 vz2 = z[2] - z[1];
01308
01309
01310 px = vy1*vz2 - vz1*vy2;
01311 py = vz1*vx2 - vx1*vz2;
01312 pz = vx1*vy2 - vy1*vx2;
01313 mag1 = px*px + py*py + pz*pz;
01314
01315
01316 if (mag1 == 0)
01317 return 1;
01318
01319 vlx = xlight - x[0];
01320 vly = ylight - y[0];
01321 vlz = zlight - z[0];
01322 mag2 = vlx*vlx + vly*vly + vlz*vlz;
01323 if (mag2 ==0)
01324 return 1;
01325
01326
01327 cosangle = fabs( (vlx*px + vly*py + vlz*pz) / sqrt(mag1*mag2) );
01328
01329
01330 if (cosangle > 1) cosangle = 1;
01331 return cosangle;
01332 }
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346 static void
01347 plt3zz(PLINT x0, PLINT y0, PLINT dx, PLINT dy, PLINT flag, PLINT *init,
01348 PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny,
01349 PLINT *u, PLINT *v, PLFLT* c)
01350 {
01351 PLINT n = 0;
01352 PLFLT x2d, y2d;
01353
01354 while (1 <= x0 && x0 <= nx && 1 <= y0 && y0 <= ny) {
01355 x2d = plP_w3wcx(x[x0 - 1], y[y0 - 1], z[x0 - 1][y0 - 1]);
01356 y2d = plP_w3wcy(x[x0 - 1], y[y0 - 1], z[x0 - 1][y0 - 1]);
01357 u[n] = plP_wcpcx(x2d);
01358 v[n] = plP_wcpcy(y2d);
01359 if (c != NULL)
01360 c[n] = (z[x0 - 1][y0 - 1] - fc_minz)/(fc_maxz-fc_minz);
01361
01362 switch (flag) {
01363 case -3:
01364 y0 += dy;
01365 flag = -flag;
01366 break;
01367 case -2:
01368 y0 += dy;
01369 break;
01370 case -1:
01371 y0 += dy;
01372 flag = -flag;
01373 break;
01374 case 1:
01375 x0 += dx;
01376 break;
01377 case 2:
01378 x0 += dx;
01379 flag = -flag;
01380 break;
01381 case 3:
01382 x0 += dx;
01383 flag = -flag;
01384 break;
01385 }
01386 n++;
01387 }
01388
01389 if (flag == 1 || flag == -2) {
01390 if (flag == 1) {
01391 x0 -= dx;
01392 y0 += dy;
01393 }
01394 else if (flag == -2) {
01395 y0 -= dy;
01396 x0 += dx;
01397 }
01398 if (1 <= x0 && x0 <= nx && 1 <= y0 && y0 <= ny) {
01399 x2d = plP_w3wcx( x[x0 - 1], y[y0 - 1], z[x0 - 1][y0 - 1]);
01400 y2d = plP_w3wcy( x[x0 - 1], y[y0 - 1], z[x0 - 1][y0 - 1]);
01401 u[n] = plP_wcpcx(x2d);
01402 v[n] = plP_wcpcy(y2d);
01403 if (c != NULL)
01404 c[n] = (z[x0 - 1][y0 - 1] - fc_minz)/(fc_maxz-fc_minz);
01405 n++;
01406 }
01407 }
01408
01409
01410
01411 plnxtv(u, v, c, n, *init);
01412 *init = 0;
01413 }
01414
01415
01416
01417
01418
01419
01420
01421
01422 static void
01423 plside3(PLFLT *x, PLFLT *y, PLFLT **z, PLINT nx, PLINT ny, PLINT opt)
01424 {
01425 PLINT i;
01426 PLFLT cxx, cxy, cyx, cyy, cyz;
01427 PLFLT xmin, ymin, zmin, xmax, ymax, zmax, zscale;
01428 PLFLT tx, ty, ux, uy;
01429
01430 plP_gw3wc(&cxx, &cxy, &cyx, &cyy, &cyz);
01431 plP_gdom(&xmin, &xmax, &ymin, &ymax);
01432 plP_grange(&zscale, &zmin, &zmax);
01433
01434
01435
01436 if (cxx >= 0.0 && cxy <= 0.0) {
01437 if (opt != 1) {
01438 for (i = 0; i < nx; i++) {
01439 tx = plP_w3wcx(x[i], y[0], zmin);
01440 ty = plP_w3wcy(x[i], y[0], zmin);
01441 ux = plP_w3wcx(x[i], y[0], z[i][0]);
01442 uy = plP_w3wcy(x[i], y[0], z[i][0]);
01443 pljoin(tx, ty, ux, uy);
01444 }
01445 }
01446 if (opt != 2) {
01447 for (i = 0; i < ny; i++) {
01448 tx = plP_w3wcx(x[0], y[i], zmin);
01449 ty = plP_w3wcy(x[0], y[i], zmin);
01450 ux = plP_w3wcx(x[0], y[i], z[0][i]);
01451 uy = plP_w3wcy(x[0], y[i], z[0][i]);
01452 pljoin(tx, ty, ux, uy);
01453 }
01454 }
01455 }
01456 else if (cxx <= 0.0 && cxy <= 0.0) {
01457 if (opt != 1) {
01458 for (i = 0; i < nx; i++) {
01459 tx = plP_w3wcx(x[i], y[ny - 1], zmin);
01460 ty = plP_w3wcy(x[i], y[ny - 1], zmin);
01461 ux = plP_w3wcx(x[i], y[ny - 1], z[i][ny - 1]);
01462 uy = plP_w3wcy(x[i], y[ny - 1], z[i][ny - 1]);
01463 pljoin(tx, ty, ux, uy);
01464 }
01465 }
01466 if (opt != 2) {
01467 for (i = 0; i < ny; i++) {
01468 tx = plP_w3wcx(x[0], y[i], zmin);
01469 ty = plP_w3wcy(x[0], y[i], zmin);
01470 ux = plP_w3wcx(x[0], y[i], z[0][i]);
01471 uy = plP_w3wcy(x[0], y[i], z[0][i]);
01472 pljoin(tx, ty, ux, uy);
01473 }
01474 }
01475 }
01476 else if (cxx <= 0.0 && cxy >= 0.0) {
01477 if (opt != 1) {
01478 for (i = 0; i < nx; i++) {
01479 tx = plP_w3wcx(x[i], y[ny - 1], zmin);
01480 ty = plP_w3wcy(x[i], y[ny - 1], zmin);
01481 ux = plP_w3wcx(x[i], y[ny - 1], z[i][ny - 1]);
01482 uy = plP_w3wcy(x[i], y[ny - 1], z[i][ny - 1]);
01483 pljoin(tx, ty, ux, uy);
01484 }
01485 }
01486 if (opt != 2) {
01487 for (i = 0; i < ny; i++) {
01488 tx = plP_w3wcx(x[nx - 1], y[i], zmin);
01489 ty = plP_w3wcy(x[nx - 1], y[i], zmin);
01490 ux = plP_w3wcx(x[nx - 1], y[i], z[nx - 1][i]);
01491 uy = plP_w3wcy(x[nx - 1], y[i], z[nx - 1][i]);
01492 pljoin(tx, ty, ux, uy);
01493 }
01494 }
01495 }
01496 else if (cxx >= 0.0 && cxy >= 0.0) {
01497 if (opt != 1) {
01498 for (i = 0; i < nx; i++) {
01499 tx = plP_w3wcx(x[i], y[0], zmin);
01500 ty = plP_w3wcy(x[i], y[0], zmin);
01501 ux = plP_w3wcx(x[i], y[0], z[i][0]);
01502 uy = plP_w3wcy(x[i], y[0], z[i][0]);
01503 pljoin(tx, ty, ux, uy);
01504 }
01505 }
01506 if (opt != 2) {
01507 for (i = 0; i < ny; i++) {
01508 tx = plP_w3wcx(x[nx - 1], y[i], zmin);
01509 ty = plP_w3wcy(x[nx - 1], y[i], zmin);
01510 ux = plP_w3wcx(x[nx - 1], y[i], z[nx - 1][i]);
01511 uy = plP_w3wcy(x[nx - 1], y[i], z[nx - 1][i]);
01512 pljoin(tx, ty, ux, uy);
01513 }
01514 }
01515 }
01516 }
01517
01518
01519
01520
01521
01522
01523
01524
01525 static void
01526 plgrid3(PLFLT tick)
01527 {
01528 PLFLT xmin, ymin, zmin, xmax, ymax, zmax, zscale;
01529 PLFLT cxx, cxy, cyx, cyy, cyz, zmin_in, zmax_in;
01530 PLINT u[3], v[3];
01531 PLINT nsub = 0;
01532 PLFLT tp;
01533
01534 plP_gw3wc(&cxx, &cxy, &cyx, &cyy, &cyz);
01535 plP_gdom(&xmin, &xmax, &ymin, &ymax);
01536 plP_grange(&zscale, &zmin_in, &zmax_in);
01537 zmin = (zmax_in > zmin_in) ? zmin_in: zmax_in;
01538 zmax = (zmax_in > zmin_in) ? zmax_in: zmin_in;
01539
01540 pldtik(zmin, zmax, &tick, &nsub, FALSE);
01541 tp = tick * floor(zmin / tick) + tick;
01542 pl3upv = 0;
01543
01544 if (cxx >= 0.0 && cxy <= 0.0) {
01545 while (tp <= zmax) {
01546 u[0] = plP_wcpcx(plP_w3wcx(xmin, ymax, tp));
01547 v[0] = plP_wcpcy(plP_w3wcy(xmin, ymax, tp));
01548 u[1] = plP_wcpcx(plP_w3wcx(xmax, ymax, tp));
01549 v[1] = plP_wcpcy(plP_w3wcy(xmax, ymax, tp));
01550 u[2] = plP_wcpcx(plP_w3wcx(xmax, ymin, tp));
01551 v[2] = plP_wcpcy(plP_w3wcy(xmax, ymin, tp));
01552 plnxtv(u, v, 0, 3, 0);
01553
01554 tp += tick;
01555 }
01556 u[0] = plP_wcpcx(plP_w3wcx(xmax, ymax, zmin));
01557 v[0] = plP_wcpcy(plP_w3wcy(xmax, ymax, zmin));
01558 u[1] = plP_wcpcx(plP_w3wcx(xmax, ymax, zmax));
01559 v[1] = plP_wcpcy(plP_w3wcy(xmax, ymax, zmax));
01560 plnxtv(u, v, 0, 2, 0);
01561 }
01562 else if (cxx <= 0.0 && cxy <= 0.0) {
01563 while (tp <= zmax) {
01564 u[0] = plP_wcpcx(plP_w3wcx(xmax, ymax, tp));
01565 v[0] = plP_wcpcy(plP_w3wcy(xmax, ymax, tp));
01566 u[1] = plP_wcpcx(plP_w3wcx(xmax, ymin, tp));
01567 v[1] = plP_wcpcy(plP_w3wcy(xmax, ymin, tp));
01568 u[2] = plP_wcpcx(plP_w3wcx(xmin, ymin, tp));
01569 v[2] = plP_wcpcy(plP_w3wcy(xmin, ymin, tp));
01570 plnxtv(u, v, 0,3, 0);
01571
01572 tp += tick;
01573 }
01574 u[0] = plP_wcpcx(plP_w3wcx(xmax, ymin, zmin));
01575 v[0] = plP_wcpcy(plP_w3wcy(xmax, ymin, zmin));
01576 u[1] = plP_wcpcx(plP_w3wcx(xmax, ymin, zmax));
01577 v[1] = plP_wcpcy(plP_w3wcy(xmax, ymin, zmax));
01578 plnxtv(u, v, 0,2, 0);
01579 }
01580 else if (cxx <= 0.0 && cxy >= 0.0) {
01581 while (tp <= zmax) {
01582 u[0] = plP_wcpcx(plP_w3wcx(xmax, ymin, tp));
01583 v[0] = plP_wcpcy(plP_w3wcy(xmax, ymin, tp));
01584 u[1] = plP_wcpcx(plP_w3wcx(xmin, ymin, tp));
01585 v[1] = plP_wcpcy(plP_w3wcy(xmin, ymin, tp));
01586 u[2] = plP_wcpcx(plP_w3wcx(xmin, ymax, tp));
01587 v[2] = plP_wcpcy(plP_w3wcy(xmin, ymax, tp));
01588 plnxtv(u, v, 0,3, 0);
01589
01590 tp += tick;
01591 }
01592 u[0] = plP_wcpcx(plP_w3wcx(xmin, ymin, zmin));
01593 v[0] = plP_wcpcy(plP_w3wcy(xmin, ymin, zmin));
01594 u[1] = plP_wcpcx(plP_w3wcx(xmin, ymin, zmax));
01595 v[1] = plP_wcpcy(plP_w3wcy(xmin, ymin, zmax));
01596 plnxtv(u, v, 0,2, 0);
01597 }
01598 else if (cxx >= 0.0 && cxy >= 0.0) {
01599 while (tp <= zmax) {
01600 u[0] = plP_wcpcx(plP_w3wcx(xmin, ymin, tp));
01601 v[0] = plP_wcpcy(plP_w3wcy(xmin, ymin, tp));
01602 u[1] = plP_wcpcx(plP_w3wcx(xmin, ymax, tp));
01603 v[1] = plP_wcpcy(plP_w3wcy(xmin, ymax, tp));
01604 u[2] = plP_wcpcx(plP_w3wcx(xmax, ymax, tp));
01605 v[2] = plP_wcpcy(plP_w3wcy(xmax, ymax, tp));
01606 plnxtv(u, v, 0,3, 0);
01607
01608 tp += tick;
01609 }
01610 u[0] = plP_wcpcx(plP_w3wcx(xmin, ymax, zmin));
01611 v[0] = plP_wcpcy(plP_w3wcy(xmin, ymax, zmin));
01612 u[1] = plP_wcpcx(plP_w3wcx(xmin, ymax, zmax));
01613 v[1] = plP_wcpcy(plP_w3wcy(xmin, ymax, zmax));
01614 plnxtv(u, v, 0,2, 0);
01615 }
01616 pl3upv = 1;
01617 }
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 static void
01635 plnxtv(PLINT *u, PLINT *v, PLFLT* c, PLINT n, PLINT init)
01636 {
01637 plnxtvhi(u, v, c, n, init);
01638
01639 if (pl3mode)
01640 plnxtvlo(u, v, c, n, init);
01641 }
01642
01643
01644
01645
01646
01647
01648
01649 static void
01650 plnxtvhi(PLINT *u, PLINT *v, PLFLT* c, PLINT n, PLINT init)
01651 {
01652
01653
01654
01655
01656 if (init == 1) {
01657 int i;
01658 oldhiview = (PLINT *) malloc((size_t) (2 * n * sizeof(PLINT)));
01659 if ( ! oldhiview)
01660 myexit("plnxtvhi: Out of memory.");
01661
01662 oldhiview[0] = u[0];
01663 oldhiview[1] = v[0];
01664 plP_draw3d(u[0], v[0], c, 0, 1);
01665 for (i = 1; i < n; i++) {
01666 oldhiview[2 * i] = u[i];
01667 oldhiview[2 * i + 1] = v[i];
01668 plP_draw3d(u[i], v[i], c, i, 0);
01669 }
01670 mhi = n;
01671 return;
01672 }
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687 xxhi = 0;
01688 if (pl3upv != 0) {
01689 newhisize = 2 * (mhi + BINC);
01690 if (newhiview != NULL) {
01691 newhiview =
01692 (PLINT *) realloc((void *) newhiview,
01693 (size_t) (newhisize * sizeof(PLINT)));
01694 }
01695 else {
01696 newhiview =
01697 (PLINT *) malloc((size_t) (newhisize * sizeof(PLINT)));
01698 }
01699 if ( ! newhiview)
01700 myexit("plnxtvhi: Out of memory.");
01701 }
01702
01703
01704
01705 plnxtvhi_draw(u, v, c, n);
01706
01707
01708
01709 swaphiview();
01710 }
01711
01712
01713
01714
01715
01716
01717
01718 static void
01719 plnxtvhi_draw(PLINT *u, PLINT *v, PLFLT* c, PLINT n)
01720 {
01721 PLINT i = 0, j = 0, first = 1;
01722 PLINT sx1 = 0, sx2 = 0, sy1 = 0, sy2 = 0;
01723 PLINT su1, su2, sv1, sv2;
01724 PLINT cx, cy, px, py;
01725 PLINT seg, ptold, lstold = 0, pthi, pnewhi = 0, newhi, change, ochange = 0;
01726
01727
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738 while (i < mhi || j < n) {
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749 ptold = (j >= n || (i < mhi && oldhiview[2 * i] < u[j]));
01750 if (ptold) {
01751 px = oldhiview[2 * i];
01752 py = oldhiview[2 * i + 1];
01753 seg = j > 0 && j < n;
01754 if (seg) {
01755 sx1 = u[j - 1];
01756 sy1 = v[j - 1];
01757 sx2 = u[j];
01758 sy2 = v[j];
01759 }
01760 } else {
01761 px = u[j];
01762 py = v[j];
01763 seg = i > 0 && i < mhi;
01764 if (seg) {
01765 sx1 = oldhiview[2 * (i - 1)];
01766 sy1 = oldhiview[2 * (i - 1) + 1];
01767 sx2 = oldhiview[2 * i];
01768 sy2 = oldhiview[2 * i + 1];
01769 }
01770 }
01771
01772
01773
01774
01775
01776
01777
01778 if (seg)
01779 pthi = plabv(px, py, sx1, sy1, sx2, sy2);
01780 else
01781 pthi = 1;
01782
01783 newhi = (ptold && !pthi) || (!ptold && pthi);
01784
01785
01786
01787
01788 change = (newhi && !pnewhi) || (!newhi && pnewhi);
01789
01790
01791
01792
01793
01794 if (first) {
01795 plP_draw3d(px, py, c, j, 1);
01796 first = 0;
01797 lstold = ptold;
01798 savehipoint(px, py);
01799 pthi = 0;
01800 ochange = 0;
01801 } else if (change) {
01802
01803
01804
01805
01806
01807 if (pl3upv == 0 && ((!ptold && j == 0) || (ptold && i == 0))) {
01808 plP_draw3d(px, py, c, j, 1);
01809 lstold = ptold;
01810 pthi = 0;
01811 ochange = 0;
01812 } else if (pl3upv == 0 &&
01813 (( ! ptold && i >= mhi) || (ptold && j >= n))) {
01814 plP_draw3d(px, py, c, j, 1);
01815 lstold = ptold;
01816 pthi = 0;
01817 ochange = 0;
01818 } else {
01819
01820
01821
01822
01823
01824
01825 if (i == 0) {
01826 sx1 = oldhiview[0];
01827 sy1 = -1;
01828 sx2 = oldhiview[0];
01829 sy2 = oldhiview[1];
01830 } else if (i >= mhi) {
01831 sx1 = oldhiview[2 * (mhi - 1)];
01832 sy1 = oldhiview[2 * (mhi - 1) + 1];
01833 sx2 = oldhiview[2 * (mhi - 1)];
01834 sy2 = -1;
01835 } else {
01836 sx1 = oldhiview[2 * (i - 1)];
01837 sy1 = oldhiview[2 * (i - 1) + 1];
01838 sx2 = oldhiview[2 * i];
01839 sy2 = oldhiview[2 * i + 1];
01840 }
01841
01842 if (j == 0) {
01843 su1 = u[0];
01844 sv1 = -1;
01845 su2 = u[0];
01846 sv2 = v[0];
01847 } else if (j >= n) {
01848 su1 = u[n - 1];
01849 sv1 = v[n - 1];
01850 su2 = u[n - 1];
01851 sv2 = -1;
01852 } else {
01853 su1 = u[j - 1];
01854 sv1 = v[j - 1];
01855 su2 = u[j];
01856 sv2 = v[j];
01857 }
01858
01859
01860
01861 pl3cut(sx1, sy1, sx2, sy2, su1, sv1, su2, sv2, &cx, &cy);
01862 if (cx == px && cy == py) {
01863 if (lstold && !ochange)
01864 plP_draw3d(px, py, c, j, 1);
01865 else
01866 plP_draw3d(px, py, c, j, 0);
01867
01868 savehipoint(px, py);
01869 lstold = 1;
01870 pthi = 0;
01871 } else {
01872 if (lstold && !ochange)
01873 plP_draw3d(cx, cy, c, j, 1);
01874 else
01875 plP_draw3d(cx, cy, c, j, 0);
01876
01877 lstold = 1;
01878 savehipoint(cx, cy);
01879 }
01880 ochange = 1;
01881 }
01882 }
01883
01884
01885
01886 if (pthi) {
01887 if (lstold && ptold)
01888 plP_draw3d(px, py, c, j, 1);
01889 else
01890 plP_draw3d(px, py, c, j, 0);
01891
01892 savehipoint(px, py);
01893 lstold = ptold;
01894 ochange = 0;
01895 }
01896 pnewhi = newhi;
01897
01898 if (ptold)
01899 i++;
01900 else
01901 j++;
01902 }
01903 }
01904
01905
01906
01907
01908
01909
01910
01911 static void
01912 plP_draw3d(PLINT x, PLINT y, PLFLT *c, PLINT j, PLINT move)
01913 {
01914 if (move)
01915 plP_movphy(x, y);
01916 else {
01917 if (c != NULL)
01918 plcol1(c[j-1]);
01919 plP_draphy(x, y);
01920 }
01921 }
01922
01923
01924
01925
01926
01927
01928
01929 static void
01930 plnxtvlo(PLINT *u, PLINT *v, PLFLT*c, PLINT n, PLINT init)
01931 {
01932 PLINT i, j, first;
01933 PLINT sx1 = 0, sx2 = 0, sy1 = 0, sy2 = 0;
01934 PLINT su1, su2, sv1, sv2;
01935 PLINT cx, cy, px, py;
01936 PLINT seg, ptold, lstold = 0, ptlo, pnewlo, newlo, change, ochange = 0;
01937
01938 first = 1;
01939 pnewlo = 0;
01940
01941
01942
01943
01944
01945 if (init == 1) {
01946
01947 oldloview = (PLINT *) malloc((size_t) (2 * n * sizeof(PLINT)));
01948 if ( ! oldloview)
01949 myexit("\nplnxtvlo: Out of memory.");
01950
01951 plP_draw3d(u[0], v[0], c, 0, 1);
01952 oldloview[0] = u[0];
01953 oldloview[1] = v[0];
01954 for (i = 1; i < n; i++) {
01955 plP_draw3d(u[i], v[i], c, i, 0);
01956 oldloview[2 * i] = u[i];
01957 oldloview[2 * i + 1] = v[i];
01958 }
01959 mlo = n;
01960 return;
01961 }
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976 xxlo = 0;
01977 i = 0;
01978 j = 0;
01979 if (pl3upv != 0) {
01980 newlosize = 2 * (mlo + BINC);
01981 if (newloview != NULL) {
01982 newloview =
01983 (PLINT *) realloc((void *) newloview,
01984 (size_t) (newlosize * sizeof(PLINT)));
01985 }
01986 else {
01987 newloview =
01988 (PLINT *) malloc((size_t) (newlosize * sizeof(PLINT)));
01989 }
01990 if ( ! newloview)
01991 myexit("plnxtvlo: Out of memory.");
01992 }
01993
01994
01995
01996
01997
01998 while (i < mlo || j < n) {
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008 ptold = (j >= n || (i < mlo && oldloview[2 * i] < u[j]));
02009 if (ptold) {
02010 px = oldloview[2 * i];
02011 py = oldloview[2 * i + 1];
02012 seg = j > 0 && j < n;
02013 if (seg) {
02014 sx1 = u[j - 1];
02015 sy1 = v[j - 1];
02016 sx2 = u[j];
02017 sy2 = v[j];
02018 }
02019 }
02020 else {
02021 px = u[j];
02022 py = v[j];
02023 seg = i > 0 && i < mlo;
02024 if (seg) {
02025 sx1 = oldloview[2 * (i - 1)];
02026 sy1 = oldloview[2 * (i - 1) + 1];
02027 sx2 = oldloview[2 * i];
02028 sy2 = oldloview[2 * i + 1];
02029 }
02030 }
02031
02032
02033
02034
02035
02036
02037
02038 if (seg)
02039 ptlo = !plabv(px, py, sx1, sy1, sx2, sy2);
02040 else
02041 ptlo = 1;
02042
02043 newlo = (ptold && !ptlo) || (!ptold && ptlo);
02044 change = (newlo && !pnewlo) || (!newlo && pnewlo);
02045
02046
02047
02048
02049
02050 if (first) {
02051 plP_draw3d(px, py, c, j, 1);
02052 first = 0;
02053 lstold = ptold;
02054 savelopoint(px, py);
02055 ptlo = 0;
02056 ochange = 0;
02057 }
02058 else if (change) {
02059
02060
02061
02062
02063
02064 if (pl3upv == 0 && ((!ptold && j == 0) || (ptold && i == 0))) {
02065 plP_draw3d(px, py, c, j, 1);
02066 lstold = ptold;
02067 ptlo = 0;
02068 ochange = 0;
02069 }
02070 else if (pl3upv == 0 &&
02071 (( ! ptold && i >= mlo) || (ptold && j >= n))) {
02072 plP_draw3d(px, py, c, j, 1);
02073 lstold = ptold;
02074 ptlo = 0;
02075 ochange = 0;
02076 }
02077
02078
02079
02080
02081
02082
02083 else {
02084 if (i == 0) {
02085 sx1 = oldloview[0];
02086 sy1 = 100000;
02087 sx2 = oldloview[0];
02088 sy2 = oldloview[1];
02089 }
02090 else if (i >= mlo) {
02091 sx1 = oldloview[2 * (mlo - 1)];
02092 sy1 = oldloview[2 * (mlo - 1) + 1];
02093 sx2 = oldloview[2 * (mlo - 1)];
02094 sy2 = 100000;
02095 }
02096 else {
02097 sx1 = oldloview[2 * (i - 1)];
02098 sy1 = oldloview[2 * (i - 1) + 1];
02099 sx2 = oldloview[2 * i];
02100 sy2 = oldloview[2 * i + 1];
02101 }
02102
02103 if (j == 0) {
02104 su1 = u[0];
02105 sv1 = 100000;
02106 su2 = u[0];
02107 sv2 = v[0];
02108 }
02109 else if (j >= n) {
02110 su1 = u[n - 1];
02111 sv1 = v[n - 1];
02112 su2 = u[n];
02113 sv2 = 100000;
02114 }
02115 else {
02116 su1 = u[j - 1];
02117 sv1 = v[j - 1];
02118 su2 = u[j];
02119 sv2 = v[j];
02120 }
02121
02122
02123
02124 pl3cut(sx1, sy1, sx2, sy2, su1, sv1, su2, sv2, &cx, &cy);
02125 if (cx == px && cy == py) {
02126 if (lstold && !ochange)
02127 plP_draw3d(px, py, c, j, 1);
02128 else
02129 plP_draw3d(px, py, c, j, 0);
02130
02131 savelopoint(px, py);
02132 lstold = 1;
02133 ptlo = 0;
02134 }
02135 else {
02136 if (lstold && !ochange)
02137 plP_draw3d(cx, cy, c, j, 1);
02138 else
02139 plP_draw3d(cx, cy, c, j, 0);
02140
02141 lstold = 1;
02142 savelopoint(cx, cy);
02143 }
02144 ochange = 1;
02145 }
02146 }
02147
02148
02149
02150 if (ptlo) {
02151 if (lstold && ptold)
02152 plP_draw3d(px, py, c, j, 1);
02153 else
02154 plP_draw3d(px, py, c, j, 0);
02155
02156 savelopoint(px, py);
02157 lstold = ptold;
02158 ochange = 0;
02159 }
02160
02161 pnewlo = newlo;
02162
02163 if (ptold)
02164 i = i + 1;
02165 else
02166 j = j + 1;
02167 }
02168
02169
02170
02171 swaploview();
02172 }
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182 static void
02183 savehipoint(PLINT px, PLINT py)
02184 {
02185 if (pl3upv == 0)
02186 return;
02187
02188 if (xxhi >= newhisize) {
02189 newhisize += 2 * BINC;
02190 newhiview = (PLINT *) realloc((void *) newhiview,
02191 (size_t) (newhisize * sizeof(PLINT)));
02192 if ( ! newhiview)
02193 myexit("savehipoint: Out of memory.");
02194 }
02195
02196 newhiview[xxhi] = px;
02197 xxhi++;
02198 newhiview[xxhi] = py;
02199 xxhi++;
02200 }
02201
02202 static void
02203 savelopoint(PLINT px, PLINT py)
02204 {
02205 if (pl3upv == 0)
02206 return;
02207
02208 if (xxlo >= newlosize) {
02209 newlosize += 2 * BINC;
02210 newloview = (PLINT *) realloc((void *) newloview,
02211 (size_t) (newlosize * sizeof(PLINT)));
02212 if ( ! newloview)
02213 myexit("savelopoint: Out of memory.");
02214 }
02215
02216 newloview[xxlo] = px;
02217 xxlo++;
02218 newloview[xxlo] = py;
02219 xxlo++;
02220 }
02221
02222
02223
02224
02225
02226
02227
02228
02229
02230 static void
02231 swaphiview(void)
02232 {
02233 PLINT *tmp;
02234
02235 if (pl3upv != 0) {
02236 mhi = xxhi / 2;
02237 tmp = oldhiview;
02238 oldhiview = newhiview;
02239 newhiview = tmp;
02240 }
02241 }
02242
02243 static void
02244 swaploview(void)
02245 {
02246 PLINT *tmp;
02247
02248 if (pl3upv != 0) {
02249 mlo = xxlo / 2;
02250 tmp = oldloview;
02251 oldloview = newloview;
02252 newloview = tmp;
02253 }
02254 }
02255
02256
02257
02258
02259
02260
02261
02262 static void
02263 freework(void)
02264 {
02265 free_mem(oldhiview);
02266 free_mem(oldloview);
02267 free_mem(newhiview);
02268 free_mem(newloview);
02269 free_mem(vtmp);
02270 free_mem(utmp);
02271 free_mem(ctmp);
02272 }
02273
02274
02275
02276
02277
02278
02279
02280 static void
02281 myexit(char *msg)
02282 {
02283 freework();
02284 plexit(msg);
02285 }
02286
02287
02288
02289
02290
02291
02292
02293
02294 static void
02295 myabort(char *msg)
02296 {
02297 freework();
02298 plabort(msg);
02299 }
02300
02301
02302
02303
02304
02305
02306
02307
02308 static int
02309 plabv(PLINT px, PLINT py, PLINT sx1, PLINT sy1, PLINT sx2, PLINT sy2)
02310 {
02311 int above;
02312
02313 if (py >= sy1 && py >= sy2)
02314 above = 1;
02315 else if (py < sy1 && py < sy2)
02316 above = 0;
02317 else if ((double) (sx2 - sx1) * (py - sy1) >=
02318 (double) (px - sx1) * (sy2 - sy1))
02319 above = 1;
02320 else
02321 above = 0;
02322
02323 return above;
02324 }
02325
02326
02327
02328
02329
02330
02331
02332
02333 static void
02334 pl3cut(PLINT sx1, PLINT sy1, PLINT sx2, PLINT sy2,
02335 PLINT su1, PLINT sv1, PLINT su2, PLINT sv2, PLINT *cx, PLINT *cy)
02336 {
02337 PLINT x21, y21, u21, v21, yv1, xu1, a, b;
02338 double fa, fb;
02339
02340 x21 = sx2 - sx1;
02341 y21 = sy2 - sy1;
02342 u21 = su2 - su1;
02343 v21 = sv2 - sv1;
02344 yv1 = sy1 - sv1;
02345 xu1 = sx1 - su1;
02346
02347 a = x21 * v21 - y21 * u21;
02348 fa = (double) a;
02349 if (a == 0) {
02350 if (sx2 < su2) {
02351 *cx = sx2;
02352 *cy = sy2;
02353 }
02354 else {
02355 *cx = su2;
02356 *cy = sv2;
02357 }
02358 return;
02359 }
02360 else {
02361 b = yv1 * u21 - xu1 * v21;
02362 fb = (double) b;
02363 *cx = (PLINT) (sx1 + (fb * x21) / fa + .5);
02364 *cy = (PLINT) (sy1 + (fb * y21) / fa + .5);
02365 }
02366 }
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382 void
02383 plRotationShear(PLFLT *xFormMatrix, PLFLT *rotation, PLFLT *shear, PLFLT *stride)
02384 {
02385 *stride = sqrt(xFormMatrix[0] * xFormMatrix[0] + xFormMatrix[2] * xFormMatrix[2]);
02386
02387 *rotation = acos(xFormMatrix[0] / *stride);
02388 if(xFormMatrix[2] < 0.0){
02389 *rotation = -*rotation;
02390 }
02391
02392 *shear = -asin(xFormMatrix[0]*xFormMatrix[1] +
02393 xFormMatrix[2]*xFormMatrix[3]);
02394
02395
02396
02397
02398
02399 if(xFormMatrix[0]*xFormMatrix[3] - xFormMatrix[1]*xFormMatrix[2] < 0.0){
02400 *shear = -(M_PI + *shear);
02401 }
02402 }
02403