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 #include "plplotP.h"
00026
00027 #define INSIDE(ix,iy) (BETW(ix,xmin,xmax) && BETW(iy,ymin,ymax))
00028
00029 static PLINT xline[PL_MAXPOLY], yline[PL_MAXPOLY];
00030
00031 static PLINT lastx = PL_UNDEFINED, lasty = PL_UNDEFINED;
00032
00033
00034
00035
00036
00037 static void
00038 pllclp(PLINT *x, PLINT *y, PLINT npts);
00039
00040
00041
00042 static int
00043 clipline(PLINT *p_x1, PLINT *p_y1, PLINT *p_x2, PLINT *p_y2,
00044 PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax);
00045
00046
00047
00048 static void
00049 genlin(short *x, short *y, PLINT npts);
00050
00051
00052
00053 static void
00054 grdashline(short *x, short *y);
00055
00056
00057
00058 static int
00059 pointinpolygon( int n, PLINT *x, PLINT *y, PLINT xp, PLINT yp );
00060
00061
00062
00063
00064
00065
00066
00067 void
00068 c_pljoin(PLFLT x1, PLFLT y1, PLFLT x2, PLFLT y2)
00069 {
00070 plP_movwor(x1, y1);
00071 plP_drawor(x2, y2);
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 void
00081 c_plline(PLINT n, PLFLT *x, PLFLT *y)
00082 {
00083 if (plsc->level < 3) {
00084 plabort("plline: Please set up window first");
00085 return;
00086 }
00087 plP_drawor_poly(x, y, n);
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 void
00100 c_plline3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z)
00101 {
00102 int i;
00103 PLFLT vmin[3], vmax[3], zscale;
00104
00105 if (plsc->level < 3) {
00106 plabort("plline3: Please set up window first");
00107 return;
00108 }
00109
00110
00111 plP_gdom(&vmin[0], &vmax[0], &vmin[1], &vmax[1]);
00112 plP_grange(&zscale, &vmin[2], &vmax[2]);
00113
00114
00115 for( i=0; i < n-1; i++ ) {
00116 PLFLT p0[3], p1[3];
00117 int axis;
00118
00119
00120 p0[0] = x[i]; p0[1] = y[i]; p0[2] = z[i];
00121 p1[0] = x[i+1]; p1[1] = y[i+1]; p1[2] = z[i+1];
00122
00123
00124 for(axis = 0; axis < 3; axis++) {
00125 if(p0[axis] < vmin[axis]) {
00126 if(p1[axis] < vmin[axis]) {
00127 break;
00128 } else {
00129 int j;
00130
00131 PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]);
00132 p0[axis] = vmin[axis];
00133 for(j = 1; j<3; j++) {
00134 int k = (axis+j)%3;
00135 p0[k] = (1-t)*p0[k] + t*p1[k];
00136 }
00137 }
00138 } else if(p1[axis] < vmin[axis]) {
00139 int j;
00140
00141 PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]);
00142 p1[axis] = vmin[axis];
00143 for(j = 1; j<3; j++) {
00144 int k = (axis+j)%3;
00145 p1[k] = (1-t)*p0[k] + t*p1[k];
00146 }
00147 }
00148 if(p0[axis] > vmax[axis]) {
00149 if(p1[axis] > vmax[axis]) {
00150 break;
00151 } else {
00152 int j;
00153
00154 PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]);
00155 p0[axis] = vmax[axis];
00156 for(j = 1; j<3; j++) {
00157 int k = (axis+j)%3;
00158 p0[k] = (1-t)*p0[k] + t*p1[k];
00159 }
00160 }
00161 } else if(p1[axis] > vmax[axis]) {
00162 int j;
00163
00164 PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]);
00165 p1[axis] = vmax[axis];
00166 for(j = 1; j<3; j++) {
00167 int k = (axis+j)%3;
00168 p1[k] = (1-t)*p0[k] + t*p1[k];
00169 }
00170 }
00171 }
00172
00173
00174 if( axis == 3 ) {
00175 PLFLT u0, v0, u1, v1;
00176 u0 = plP_wcpcx(plP_w3wcx( p0[0], p0[1], p0[2] ));
00177 v0 = plP_wcpcy(plP_w3wcy( p0[0], p0[1], p0[2] ));
00178 u1 = plP_wcpcx(plP_w3wcx( p1[0], p1[1], p1[2] ));
00179 v1 = plP_wcpcy(plP_w3wcy( p1[0], p1[1], p1[2] ));
00180 plP_movphy((PLINT)u0,(PLINT)v0);
00181 plP_draphy((PLINT)u1,(PLINT)v1);
00182 }
00183 }
00184 return;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 void
00215 c_plpoly3(PLINT n, PLFLT *x, PLFLT *y, PLFLT *z, PLBOOL *draw, PLBOOL ifcc)
00216 {
00217 int i;
00218 PLFLT vmin[3], vmax[3], zscale;
00219 PLFLT u1, v1, u2, v2, u3, v3;
00220 PLFLT c;
00221
00222 if (plsc->level < 3) {
00223 plabort("plpoly3: Please set up window first");
00224 return;
00225 }
00226
00227 if ( n < 3 ) {
00228 plabort("plpoly3: Must specify at least 3 points");
00229 return;
00230 }
00231
00232
00233
00234 u1 = plP_wcpcx(plP_w3wcx( x[0], y[0], z[0] ));
00235 v1 = plP_wcpcy(plP_w3wcy( x[0], y[0], z[0] ));
00236
00237 u2 = plP_wcpcx(plP_w3wcx( x[1], y[1], z[1] ));
00238 v2 = plP_wcpcy(plP_w3wcy( x[1], y[1], z[1] ));
00239
00240 u3 = plP_wcpcx(plP_w3wcx( x[2], y[2], z[2] ));
00241 v3 = plP_wcpcy(plP_w3wcy( x[2], y[2], z[2] ));
00242
00243 c = (u1-u2)*(v3-v2)-(v1-v2)*(u3-u2);
00244
00245 if ( c *(1 - 2*ABS(ifcc)) < 0. )
00246 return;
00247
00248
00249 plP_gdom(&vmin[0], &vmax[0], &vmin[1], &vmax[1]);
00250 plP_grange(&zscale, &vmin[2], &vmax[2]);
00251
00252
00253 for( i=0; i < n-1; i++ ) {
00254 PLFLT p0[3], p1[3];
00255 int axis;
00256
00257
00258 p0[0] = x[i]; p0[1] = y[i]; p0[2] = z[i];
00259 p1[0] = x[i+1]; p1[1] = y[i+1]; p1[2] = z[i+1];
00260
00261
00262 for(axis = 0; axis < 3; axis++) {
00263 if(p0[axis] < vmin[axis]) {
00264 if(p1[axis] < vmin[axis]) {
00265 break;
00266 } else {
00267 int j;
00268
00269 PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]);
00270 p0[axis] = vmin[axis];
00271 for(j = 1; j<3; j++) {
00272 int k = (axis+j)%3;
00273 p0[k] = (1-t)*p0[k] + t*p1[k];
00274 }
00275 }
00276 } else if(p1[axis] < vmin[axis]) {
00277 int j;
00278
00279 PLFLT t = (vmin[axis] - p0[axis]) / (p1[axis] - p0[axis]);
00280 p1[axis] = vmin[axis];
00281 for(j = 1; j<3; j++) {
00282 int k = (axis+j)%3;
00283 p1[k] = (1-t)*p0[k] + t*p1[k];
00284 }
00285 }
00286 if(p0[axis] > vmax[axis]) {
00287 if(p1[axis] > vmax[axis]) {
00288 break;
00289 } else {
00290 int j;
00291
00292 PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]);
00293 p0[axis] = vmax[axis];
00294 for(j = 1; j<3; j++) {
00295 int k = (axis+j)%3;
00296 p0[k] = (1-t)*p0[k] + t*p1[k];
00297 }
00298 }
00299 } else if(p1[axis] > vmax[axis]) {
00300 int j;
00301
00302 PLFLT t = (vmax[axis] - p0[axis]) / (p1[axis] - p0[axis]);
00303 p1[axis] = vmax[axis];
00304 for(j = 1; j<3; j++) {
00305 int k = (axis+j)%3;
00306 p1[k] = (1-t)*p0[k] + t*p1[k];
00307 }
00308 }
00309 }
00310
00311
00312 if( axis == 3 && draw[i] ) {
00313 PLFLT u0, v0, u1, v1;
00314 u0 = plP_wcpcx(plP_w3wcx( p0[0], p0[1], p0[2] ));
00315 v0 = plP_wcpcy(plP_w3wcy( p0[0], p0[1], p0[2] ));
00316 u1 = plP_wcpcx(plP_w3wcx( p1[0], p1[1], p1[2] ));
00317 v1 = plP_wcpcy(plP_w3wcy( p1[0], p1[1], p1[2] ));
00318 plP_movphy((PLINT)u0,(PLINT)v0);
00319 plP_draphy((PLINT)u1,(PLINT)v1);
00320 }
00321 }
00322 return;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332 void
00333 c_plstyl(PLINT nms, PLINT *mark, PLINT *space)
00334 {
00335 short int i;
00336 short int flag;
00337
00338 if (plsc->level < 1) {
00339 plabort("plstyl: Please call plinit first");
00340 return;
00341 }
00342 if ((nms < 0) || (nms > 10)) {
00343 plabort("plstyl: Broken lines cannot have <0 or >10 elements");
00344 return;
00345 }
00346 flag = 1;
00347 for (i = 0; i < nms; i++) {
00348 if ((mark[i] < 0) || (space[i] < 0)) {
00349 plabort("plstyl: Mark and space lengths must be > 0");
00350 return;
00351 }
00352 if ((mark[i] != 0) || (space[i] != 0)) {
00353 flag = 0;
00354 }
00355 }
00356
00357 if ((nms > 0) && (flag == 1)) {
00358 plabort("plstyl: At least one mark or space must be > 0");
00359 return;
00360 }
00361
00362 plsc->nms = nms;
00363 for (i = 0; i < nms; i++) {
00364 plsc->mark[i] = mark[i];
00365 plsc->space[i] = space[i];
00366 }
00367
00368 plsc->curel = 0;
00369 plsc->pendn = 1;
00370 plsc->timecnt = 0;
00371 plsc->alarm = nms > 0 ? mark[0] : 0;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380 void
00381 plP_movphy(PLINT x, PLINT y)
00382 {
00383 plsc->currx = x;
00384 plsc->curry = y;
00385 }
00386
00387
00388
00389
00390
00391
00392
00393 void
00394 plP_draphy(PLINT x, PLINT y)
00395 {
00396 xline[0] = plsc->currx;
00397 xline[1] = x;
00398 yline[0] = plsc->curry;
00399 yline[1] = y;
00400
00401 pllclp(xline, yline, 2);
00402 }
00403
00404
00405
00406
00407
00408
00409
00410 void
00411 plP_movwor(PLFLT x, PLFLT y)
00412 {
00413 plsc->currx = plP_wcpcx(x);
00414 plsc->curry = plP_wcpcy(y);
00415 }
00416
00417
00418
00419
00420
00421
00422
00423 void
00424 plP_drawor(PLFLT x, PLFLT y)
00425 {
00426 xline[0] = plsc->currx;
00427 xline[1] = plP_wcpcx(x);
00428 yline[0] = plsc->curry;
00429 yline[1] = plP_wcpcy(y);
00430
00431 pllclp(xline, yline, 2);
00432 }
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 void
00443 plP_draphy_poly(PLINT *x, PLINT *y, PLINT n)
00444 {
00445 PLINT i, j, ib, ilim;
00446
00447 for (ib = 0; ib < n; ib += PL_MAXPOLY - 1) {
00448 ilim = MIN(PL_MAXPOLY, n - ib);
00449
00450 for (i = 0; i < ilim; i++) {
00451 j = ib + i;
00452 xline[i] = x[j];
00453 yline[i] = y[j];
00454 }
00455 pllclp(xline, yline, ilim);
00456 }
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 void
00468 plP_drawor_poly(PLFLT *x, PLFLT *y, PLINT n)
00469 {
00470 PLINT i, j, ib, ilim;
00471
00472 for (ib = 0; ib < n; ib += PL_MAXPOLY - 1) {
00473 ilim = MIN(PL_MAXPOLY, n - ib);
00474
00475 for (i = 0; i < ilim; i++) {
00476 j = ib + i;
00477 xline[i] = plP_wcpcx(x[j]);
00478 yline[i] = plP_wcpcy(y[j]);
00479 }
00480 pllclp(xline, yline, ilim);
00481 }
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491 static void
00492 pllclp(PLINT *x, PLINT *y, PLINT npts)
00493 {
00494 plP_pllclp(x, y, npts, plsc->clpxmi, plsc->clpxma,
00495 plsc->clpymi, plsc->clpyma, genlin);
00496 }
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508 void
00509 plP_pllclp(PLINT *x, PLINT *y, PLINT npts,
00510 PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax,
00511 void (*draw) (short *, short *, PLINT))
00512 {
00513 PLINT x1, x2, y1, y2;
00514 PLINT i, iclp = 0;
00515
00516 short _xclp[PL_MAXPOLY], _yclp[PL_MAXPOLY];
00517 short *xclp, *yclp;
00518 int drawable;
00519
00520 if ( npts < PL_MAXPOLY ) {
00521 xclp = _xclp;
00522 yclp = _yclp;
00523 } else {
00524 if (((xclp = (short *) malloc( npts*sizeof(short) ))==NULL)||
00525 ((yclp = (short *) malloc( npts*sizeof(short) ))==NULL))
00526 {
00527 plexit("plP_pllclp: Insufficient memory");
00528 }
00529 }
00530
00531 for (i = 0; i < npts - 1; i++) {
00532 x1 = x[i];
00533 x2 = x[i + 1];
00534 y1 = y[i];
00535 y2 = y[i + 1];
00536
00537 drawable = (INSIDE(x1, y1) && INSIDE(x2, y2));
00538 if ( ! drawable)
00539 drawable = ! clipline(&x1, &y1, &x2, &y2, xmin, xmax, ymin, ymax);
00540
00541 if (drawable) {
00542
00543
00544
00545 if (iclp == 0) {
00546 xclp[iclp] = x1;
00547 yclp[iclp] = y1;
00548 iclp++;
00549 xclp[iclp] = x2;
00550 yclp[iclp] = y2;
00551 }
00552
00553
00554
00555
00556 else if (x1 == xclp[iclp] && y1 == yclp[iclp]) {
00557 iclp++;
00558 xclp[iclp] = x2;
00559 yclp[iclp] = y2;
00560 }
00561
00562
00563
00564 else {
00565 if (iclp + 1 >= 2)
00566 (*draw)(xclp, yclp, iclp + 1);
00567 iclp = 0;
00568 xclp[iclp] = x1;
00569 yclp[iclp] = y1;
00570 iclp++;
00571 xclp[iclp] = x2;
00572 yclp[iclp] = y2;
00573 }
00574 }
00575 }
00576
00577
00578
00579 if (iclp + 1 >= 2)
00580 (*draw)(xclp, yclp, iclp + 1);
00581
00582 plsc->currx = x[npts-1];
00583 plsc->curry = y[npts-1];
00584
00585 if ( xclp != _xclp ) {
00586 free( xclp );
00587 free( yclp );
00588 }
00589 }
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614 static int
00615 circulation(PLINT *x, PLINT *y, PLINT npts)
00616 {
00617 PLFLT xproduct;
00618 int direction = 0;
00619 PLFLT x1, y1, x2, y2, x3, y3;
00620 int i;
00621
00622 xproduct = 0.0 ;
00623 x1 = x[0];
00624 y1 = y[0];
00625 for (i = 1; i < npts - 2; i++) {
00626 x2 = x[i+1];
00627 y2 = y[i+1];
00628 x3 = x[i+2];
00629 y3 = y[i+2];
00630 xproduct = xproduct + (x2-x1)*(y3-y2) - (y2-y1)*(x3-x2);
00631 }
00632
00633 if (xproduct > 0.0) direction = 1;
00634 if (xproduct < 0.0) direction = -1;
00635 return direction;
00636 }
00637
00638
00639
00640
00641
00642
00643
00644 void
00645 plP_plfclp(PLINT *x, PLINT *y, PLINT npts,
00646 PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax,
00647 void (*draw) (short *, short *, PLINT))
00648 {
00649 PLINT i, x1, x2, y1, y2;
00650 int iclp = 0, iout = 2;
00651 short _xclp[2*PL_MAXPOLY+2], _yclp[2*PL_MAXPOLY+2];
00652 short *xclp, *yclp;
00653 int drawable;
00654 int crossed_xmin1 = 0, crossed_xmax1 = 0;
00655 int crossed_ymin1 = 0, crossed_ymax1 = 0;
00656 int crossed_xmin2 = 0, crossed_xmax2 = 0;
00657 int crossed_ymin2 = 0, crossed_ymax2 = 0;
00658 int crossed_up = 0, crossed_down = 0;
00659 int crossed_left = 0, crossed_right = 0;
00660 int inside_lb ;
00661 int inside_lu ;
00662 int inside_rb ;
00663 int inside_ru ;
00664
00665
00666 if (npts < 3 || !draw) return;
00667
00668 if ( npts < PL_MAXPOLY ) {
00669 xclp = _xclp;
00670 yclp = _yclp;
00671 } else {
00672 if (((xclp = (short *) malloc( (2*npts+2)*sizeof(short) ))==NULL)||
00673 ((yclp = (short *) malloc( (2*npts+2)*sizeof(short) ))==NULL))
00674 {
00675 plexit("plP_plfclp: Insufficient memory");
00676 }
00677 }
00678
00679
00680 inside_lb = pointinpolygon(npts,x,y,xmin,ymin) ;
00681 inside_lu = pointinpolygon(npts,x,y,xmin,ymax) ;
00682 inside_rb = pointinpolygon(npts,x,y,xmax,ymin) ;
00683 inside_ru = pointinpolygon(npts,x,y,xmax,ymax) ;
00684
00685 for (i = 0; i < npts - 1; i++) {
00686 x1 = x[i]; x2 = x[i+1];
00687 y1 = y[i]; y2 = y[i+1];
00688
00689 drawable = (INSIDE(x1, y1) && INSIDE(x2, y2));
00690 if ( ! drawable)
00691 drawable = ! clipline(&x1, &y1, &x2, &y2, xmin, xmax, ymin, ymax);
00692
00693 if (drawable) {
00694
00695 crossed_xmin2 = (x1 == xmin); crossed_xmax2 = (x1 == xmax);
00696 crossed_ymin2 = (y1 == ymin); crossed_ymax2 = (y1 == ymax);
00697
00698 crossed_left = (crossed_left || crossed_xmin2);
00699 crossed_right = (crossed_right || crossed_xmax2);
00700 crossed_down = (crossed_down || crossed_ymin2);
00701 crossed_up = (crossed_up || crossed_ymax2);
00702 iout = iclp+2;
00703
00704
00705 if (iclp == 0) {
00706 xclp[iclp] = x1; yclp[iclp] = y1; iclp++;
00707 xclp[iclp] = x2; yclp[iclp] = y2; iclp++;
00708 }
00709
00710
00711
00712
00713 else if (x1 == xclp[iclp-1] && y1 == yclp[iclp-1]) {
00714 xclp[iclp] = x2; yclp[iclp] = y2; iclp++;
00715 }
00716
00717
00718
00719
00720
00721
00722 else {
00723
00724
00725
00726
00727 xclp[iclp+1] = x2; yclp[iclp+1] = y2;
00728 xclp[iclp+2] = x1; yclp[iclp+2] = y1;
00729 iout = iout - iclp + 1;
00730
00731 if ( ((crossed_xmin1 && crossed_xmax2) ||
00732 (crossed_xmin2 && crossed_xmax1)) &&
00733 inside_lu )
00734 {
00735 if ( crossed_xmin1 )
00736 {
00737 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00738 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00739 } else {
00740 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00741 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00742 }
00743 }
00744
00745 else if ( ((crossed_xmin1 && crossed_xmax2) ||
00746 (crossed_xmin2 && crossed_xmax1)) &&
00747 inside_lb )
00748 {
00749 if ( crossed_xmin1 )
00750 {
00751 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00752 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00753 } else {
00754 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00755 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00756 }
00757 }
00758
00759 else if ( ((crossed_ymin1 && crossed_ymax2) ||
00760 (crossed_ymin2 && crossed_ymax1)) &&
00761 inside_lb )
00762 {
00763 if ( crossed_ymin1 )
00764 {
00765 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00766 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00767 } else {
00768 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00769 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00770 }
00771 }
00772
00773 else if ( ((crossed_ymin1 && crossed_ymax2) ||
00774 (crossed_ymin2 && crossed_ymax1)) &&
00775 inside_rb )
00776 {
00777 if ( crossed_ymin1 )
00778 {
00779 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00780 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00781 } else {
00782 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00783 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00784 }
00785 }
00786
00787
00788 else if ( (crossed_xmin1 && crossed_ymin2) ||
00789 (crossed_ymin1 && crossed_xmin2) )
00790 {
00791 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00792 }
00793
00794 else if ( (crossed_xmax1 && crossed_ymin2) ||
00795 (crossed_ymin1 && crossed_xmax2) )
00796 {
00797 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00798 }
00799
00800 else if ( (crossed_xmin1 && crossed_ymax2) ||
00801 (crossed_ymax1 && crossed_xmin2) )
00802 {
00803 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00804 }
00805
00806 else if ( (crossed_xmax1 && crossed_ymax2) ||
00807 (crossed_ymax1 && crossed_xmax2) )
00808 {
00809 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00810 }
00811
00812
00813 xclp[iclp] = x1; yclp[iclp] = y1; iclp++;
00814 xclp[iclp] = x2; yclp[iclp] = y2; iclp++;
00815 }
00816
00817
00818 crossed_xmin1 = (x2 == xmin); crossed_xmax1 = (x2 == xmax);
00819 crossed_ymin1 = (y2 == ymin); crossed_ymax1 = (y2 == ymax);
00820 }
00821 }
00822
00823
00824
00825
00826
00827 if (iclp == 0) {
00828 if ( inside_lb ) {
00829 (*draw)(xclp, yclp, iclp);
00830
00831 if ( xclp != _xclp ) {
00832 free( xclp );
00833 free( yclp );
00834 }
00835
00836
00837 return;
00838 }
00839 }
00840
00841
00842
00843 if (iclp >= 2) {
00844 int debug=0;
00845 int dir = circulation(x, y, npts);
00846 if (debug) {
00847 if ( (xclp[0] == xmin && xclp[iclp-1] == xmax) ||
00848 (xclp[0] == xmax && xclp[iclp-1] == xmin) ||
00849 (yclp[0] == ymin && yclp[iclp-1] == ymax) ||
00850 (yclp[0] == ymax && yclp[iclp-1] == ymin) ||
00851 (xclp[0] == xmin && yclp[iclp-1] == ymin) ||
00852 (yclp[0] == ymin && xclp[iclp-1] == xmin) ||
00853 (xclp[0] == xmax && yclp[iclp-1] == ymin) ||
00854 (yclp[0] == ymin && xclp[iclp-1] == xmax) ||
00855 (xclp[0] == xmax && yclp[iclp-1] == ymax) ||
00856 (yclp[0] == ymax && xclp[iclp-1] == xmax) ||
00857 (xclp[0] == xmin && yclp[iclp-1] == ymax) ||
00858 (yclp[0] == ymax && xclp[iclp-1] == xmin) ) {
00859 printf("dir=%d, clipped points:\n", dir);
00860 for (i=0; i < iclp; i++)
00861 printf(" x[%d]=%d y[%d]=%d", i, xclp[i], i, yclp[i]);
00862 printf("\n");
00863 printf("pre-clipped points:\n");
00864 for (i=0; i < npts; i++)
00865 printf(" x[%d]=%d y[%d]=%d", i, x[i], i, y[i]);
00866 printf("\n");
00867 }
00868 }
00869
00870
00871
00872 if (xclp[0] == xmin && xclp[iclp-1] == xmax)
00873 {
00874 if (dir > 0) {
00875 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00876 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00877 }
00878 else {
00879 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00880 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00881 }
00882 }
00883 else if (xclp[0] == xmax && xclp[iclp-1] == xmin)
00884 {
00885 if (dir > 0) {
00886 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00887 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00888 }
00889 else {
00890 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00891 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00892 }
00893 }
00894
00895
00896 else if (yclp[0] == ymin && yclp[iclp-1] == ymax)
00897 {
00898 if (dir > 0) {
00899 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00900 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00901 }
00902 else {
00903 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00904 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00905 }
00906 }
00907 else if (yclp[0] == ymax && yclp[iclp-1] == ymin)
00908 {
00909 if (dir > 0) {
00910 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00911 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00912 }
00913 else {
00914 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00915 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00916 }
00917 }
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931 else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir < 0) ||
00932 (yclp[0] == ymin && xclp[iclp-1] == xmin && dir > 0) )
00933 {
00934 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00935 }
00936
00937 else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir > 0))
00938 {
00939 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00940 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00941 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00942 }
00943
00944 else if ((yclp[0] == ymin && xclp[iclp-1] == xmin && dir < 0))
00945 {
00946 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00947 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00948 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00949 }
00950
00951 else if ((xclp[0] == xmax && yclp[iclp-1] == ymin && dir > 0) ||
00952 (yclp[0] == ymin && xclp[iclp-1] == xmax && dir < 0) )
00953 {
00954 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00955 }
00956
00957 else if (yclp[0] == ymin && xclp[iclp-1] == xmax && dir > 0)
00958 {
00959 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00960 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00961 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00962 }
00963
00964 else if (xclp[0] == xmax && yclp[iclp-1] == ymin && dir < 0)
00965 {
00966 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00967 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00968 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00969 }
00970
00971 else if ((xclp[0] == xmax && yclp[iclp-1] == ymax && dir < 0) ||
00972 (yclp[0] == ymax && xclp[iclp-1] == xmax && dir > 0) )
00973 {
00974 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
00975 }
00976
00977 else if (xclp[0] == xmax && yclp[iclp-1] == ymax && dir > 0)
00978 {
00979 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00980 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00981 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00982 }
00983
00984 else if (yclp[0] == ymax && xclp[iclp-1] == xmax && dir < 0)
00985 {
00986 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
00987 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
00988 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00989 }
00990
00991 else if ((xclp[0] == xmin && yclp[iclp-1] == ymax && dir > 0) ||
00992 (yclp[0] == ymax && xclp[iclp-1] == xmin && dir < 0) )
00993 {
00994 xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
00995 }
00996
00997 else if (yclp[0] == ymax && xclp[iclp-1] == xmin && dir > 0)
00998 {
00999 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
01000 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
01001 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
01002 }
01003
01004 else if (xclp[0] == xmin && yclp[iclp-1] == ymax && dir < 0)
01005 {
01006 xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
01007 xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
01008 xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
01009 }
01010 }
01011
01012
01013
01014
01015
01016
01017 if ( crossed_left+crossed_right+crossed_down+crossed_up == 1 &&
01018 inside_lb+inside_rb+inside_lu+inside_ru == 4 ) {
01019 int dir = circulation(x, y, npts);
01020 PLINT xlim[4], ylim[4];
01021 int insert;
01022 int incr;
01023
01024 xlim[0] = xmin ; ylim[0] = ymin ;
01025 xlim[1] = xmax ; ylim[1] = ymin ;
01026 xlim[2] = xmax ; ylim[2] = ymax ;
01027 xlim[3] = xmin ; ylim[3] = ymax ;
01028 if ( dir > 0 ) {
01029 incr = 1;
01030 insert = 0*crossed_left + 1*crossed_down + 2*crossed_right +
01031 3*crossed_up ;
01032 } else {
01033 incr = -1;
01034 insert = 3*crossed_left + 2*crossed_up + 1*crossed_right +
01035 0*crossed_down ;
01036 }
01037 for ( i=0; i < 4; i ++ ) {
01038 xclp[iclp] = xlim[insert] ;
01039 yclp[iclp] = ylim[insert] ;
01040 iclp ++ ;
01041 insert += incr ;
01042 if ( insert > 3 ) insert = 0 ;
01043 if ( insert < 0 ) insert = 3 ;
01044 }
01045 }
01046
01047
01048 if (iclp >= 3)
01049 (*draw)(xclp, yclp, iclp);
01050
01051 if ( xclp != _xclp ) {
01052 free( xclp );
01053 free( yclp );
01054 }
01055 }
01056
01057
01058
01059
01060
01061
01062
01063 static int
01064 clipline(PLINT *p_x1, PLINT *p_y1, PLINT *p_x2, PLINT *p_y2,
01065 PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
01066 {
01067 PLINT t, dx, dy, flipx, flipy;
01068 double dydx = 0, dxdy = 0;
01069
01070
01071
01072
01073 if ((*p_x1 <= xmin && *p_x2 <= xmin) ||
01074 (*p_x1 >= xmax && *p_x2 >= xmax) ||
01075 (*p_y1 <= ymin && *p_y2 <= ymin) ||
01076 (*p_y1 >= ymax && *p_y2 >= ymax))
01077 return 1;
01078
01079
01080 if ( (*p_x1 == PLINT_MIN) || (*p_y1 == PLINT_MIN) ||
01081 (*p_x2 == PLINT_MIN) || (*p_y2 == PLINT_MIN) )
01082 return 1;
01083
01084 flipx = 0;
01085 flipy = 0;
01086
01087 if (*p_x2 < *p_x1) {
01088 *p_x1 = 2 * xmin - *p_x1;
01089 *p_x2 = 2 * xmin - *p_x2;
01090 xmax = 2 * xmin - xmax;
01091 t = xmax;
01092 xmax = xmin;
01093 xmin = t;
01094 flipx = 1;
01095 }
01096
01097 if (*p_y2 < *p_y1) {
01098 *p_y1 = 2 * ymin - *p_y1;
01099 *p_y2 = 2 * ymin - *p_y2;
01100 ymax = 2 * ymin - ymax;
01101 t = ymax;
01102 ymax = ymin;
01103 ymin = t;
01104 flipy = 1;
01105 }
01106
01107 dx = *p_x2 - *p_x1;
01108 dy = *p_y2 - *p_y1;
01109
01110 if (dx != 0 && dy != 0) {
01111 dydx = (double) dy / (double) dx;
01112 dxdy = 1./ dydx;
01113 }
01114
01115 if (*p_x1 < xmin) {
01116 if (dx != 0 && dy != 0)
01117 *p_y1 = *p_y1 + ROUND((xmin - *p_x1) * dydx);
01118 *p_x1 = xmin;
01119 }
01120
01121 if (*p_y1 < ymin) {
01122 if (dx != 0 && dy != 0)
01123 *p_x1 = *p_x1 + ROUND((ymin - *p_y1) * dxdy);
01124 *p_y1 = ymin;
01125 }
01126
01127 if (*p_x1 >= xmax || *p_y1 >= ymax)
01128 return 1;
01129
01130 if (*p_y2 > ymax) {
01131 if (dx != 0 && dy != 0)
01132 *p_x2 = *p_x2 - ROUND((*p_y2 - ymax) * dxdy);
01133 *p_y2 = ymax;
01134 }
01135
01136 if (*p_x2 > xmax) {
01137 if (dx != 0 && dy != 0)
01138 *p_y2 = *p_y2 - ROUND((*p_x2 - xmax) * dydx);
01139 *p_x2 = xmax;
01140 }
01141
01142 if (flipx) {
01143 *p_x1 = 2 * xmax - *p_x1;
01144 *p_x2 = 2 * xmax - *p_x2;
01145 }
01146
01147 if (flipy) {
01148 *p_y1 = 2 * ymax - *p_y1;
01149 *p_y2 = 2 * ymax - *p_y2;
01150 }
01151
01152 return 0;
01153 }
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163 static void
01164 genlin(short *x, short *y, PLINT npts)
01165 {
01166
01167
01168 if (plsc->nms == 0) {
01169 if (npts== 2)
01170 plP_line(x, y);
01171 else
01172 plP_polyline(x, y, npts);
01173 }
01174
01175
01176
01177
01178 else {
01179
01180 PLINT i;
01181
01182
01183
01184 if (plsc->dev_dash) {
01185 plsc->dev_npts = npts;
01186 plsc->dev_x = x;
01187 plsc->dev_y = y;
01188 plP_esc(PLESC_DASH, NULL);
01189 return;
01190 }
01191
01192 for (i = 0; i < npts - 1; i++) {
01193 grdashline(x+i, y+i);
01194 }
01195 }
01196 }
01197
01198
01199
01200
01201
01202
01203
01204 static void
01205 grdashline(short *x, short *y)
01206 {
01207 PLINT nx, ny, nxp, nyp, incr, temp;
01208 PLINT modulo, dx, dy, i, xtmp, ytmp;
01209 PLINT tstep, pix_distance, j;
01210 int loop_x;
01211 short xl[2], yl[2];
01212 double nxstep, nystep;
01213
01214
01215
01216 if (x[0] != lastx || y[0] != lasty) {
01217 plsc->curel = 0;
01218 plsc->pendn = 1;
01219 plsc->timecnt = 0;
01220 plsc->alarm = plsc->mark[0];
01221 }
01222
01223 lastx = xtmp = x[0];
01224 lasty = ytmp = y[0];
01225
01226 if (x[0] == x[1] && y[0] == y[1])
01227 return;
01228
01229 nx = x[1] - x[0];
01230 dx = (nx > 0) ? 1 : -1;
01231 nxp = ABS(nx);
01232
01233 ny = y[1] - y[0];
01234 dy = (ny > 0) ? 1 : -1;
01235 nyp = ABS(ny);
01236
01237 if (nyp > nxp) {
01238 modulo = nyp;
01239 incr = nxp;
01240 loop_x = 0;
01241 }
01242 else {
01243 modulo = nxp;
01244 incr = nyp;
01245 loop_x = 1;
01246 }
01247
01248 temp = modulo / 2;
01249
01250
01251
01252 nxstep = nxp * plsc->umx;
01253 nystep = nyp * plsc->umy;
01254 tstep = (PLINT)(sqrt( nxstep * nxstep + nystep * nystep ) / modulo);
01255 if (tstep < 1) tstep = 1;
01256
01257
01258
01259 i = 0;
01260 while (i < modulo) {
01261 pix_distance = (plsc->alarm - plsc->timecnt + tstep - 1) / tstep;
01262 i += pix_distance;
01263 if (i > modulo)
01264 pix_distance -= (i - modulo);
01265 plsc->timecnt += pix_distance * tstep;
01266
01267 temp += pix_distance * incr;
01268 j = temp / modulo;
01269 temp = temp % modulo;
01270
01271 if (loop_x) {
01272 xtmp += pix_distance * dx;
01273 ytmp += j * dy;
01274 }
01275 else {
01276 xtmp += j * dx;
01277 ytmp += pix_distance * dy;
01278 }
01279 if (plsc->pendn != 0) {
01280 xl[0] = lastx;
01281 yl[0] = lasty;
01282 xl[1] = xtmp;
01283 yl[1] = ytmp;
01284 plP_line(xl, yl);
01285 }
01286
01287
01288
01289 while (plsc->timecnt >= plsc->alarm) {
01290 if (plsc->pendn != 0) {
01291 plsc->pendn = 0;
01292 plsc->timecnt -= plsc->alarm;
01293 plsc->alarm = plsc->space[plsc->curel];
01294 }
01295 else {
01296 plsc->pendn = 1;
01297 plsc->timecnt -= plsc->alarm;
01298 plsc->curel++;
01299 if (plsc->curel >= plsc->nms)
01300 plsc->curel = 0;
01301 plsc->alarm = plsc->mark[plsc->curel];
01302 }
01303 }
01304 lastx = xtmp;
01305 lasty = ytmp;
01306 }
01307 }
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317 static int
01318 pointinpolygon( int n, PLINT *x, PLINT *y, PLINT xp, PLINT yp )
01319 {
01320 int i;
01321 int count_crossings;
01322 PLFLT x1, y1, x2, y2, xpp, ypp, xout, yout, xmax;
01323 PLFLT xvp, yvp, xvv, yvv, xv1, yv1, xv2, yv2;
01324 PLFLT inprod1, inprod2;
01325
01326 xpp = (PLFLT) xp;
01327 ypp = (PLFLT) yp;
01328
01329 count_crossings = 0;
01330
01331
01332
01333
01334 xmax = x[0] ;
01335 xout = x[0] ;
01336 yout = y[0] ;
01337 for ( i = 0; i < n ; i ++ ) {
01338 if ( xout > x[i] ) {
01339 xout = x[i] ;
01340 }
01341 if ( xmax < x[i] ) {
01342 xmax = x[i] ;
01343 }
01344 }
01345 xout = xout - (xmax-xout) ;
01346
01347
01348
01349
01350 xpp = (PLFLT) xp;
01351 ypp = (PLFLT) yp;
01352
01353 xvp = xpp - xout;
01354 yvp = ypp - yout;
01355
01356 for ( i = 0; i < n; i ++ ) {
01357 x1 = (PLFLT) x[i] ;
01358 y1 = (PLFLT) y[i] ;
01359 if ( i < n-1 ) {
01360 x2 = (PLFLT) x[i+1] ;
01361 y2 = (PLFLT) y[i+1] ;
01362 } else {
01363 x2 = (PLFLT) x[0] ;
01364 y2 = (PLFLT) y[0] ;
01365 }
01366
01367
01368 if ( x1 == x2 && y1 == y2 ) {
01369 continue;
01370 }
01371
01372
01373
01374 xv1 = x1 - xout;
01375 yv1 = y1 - yout;
01376 xv2 = x2 - xout;
01377 yv2 = y2 - yout;
01378 inprod1 = xv1*yvp - yv1*xvp;
01379 inprod2 = xv2*yvp - yv2*xvp;
01380 if ( inprod1 * inprod2 >= 0.0 ) {
01381
01382 continue;
01383 }
01384
01385
01386
01387 xvv = x2 - x1;
01388 yvv = y2 - y1;
01389 xv1 = xpp - x1;
01390 yv1 = ypp - y1;
01391 xv2 = xout - x1;
01392 yv2 = yout - y1;
01393 inprod1 = xv1*yvv - yv1*xvv;
01394 inprod2 = xv2*yvv - yv2*xvv;
01395 if ( inprod1 * inprod2 >= 0.0 ) {
01396
01397 continue;
01398 }
01399
01400
01401 count_crossings ++;
01402 }
01403
01404
01405
01406
01407 return (count_crossings%2);
01408 }