26 #define INSIDE( ix, iy ) ( BETW( ix, xmin, xmax ) && BETW( iy, ymin, ymax ) )
28 #define DTOR ( PI / 180. )
33 #define BETW_NBCC( ix, ia, ib ) ( ( ( ix ) <= ( ia + PL_NBCC ) && ( ix ) >= ( ib - PL_NBCC ) ) || ( ( ix ) >= ( ia - PL_NBCC ) && ( ix ) <= ( ib + PL_NBCC ) ) )
79 compar(
const void *,
const void * );
96 #ifdef USE_FILL_INTERSECTION_POLYGON
98 fill_intersection_polygon(
PLINT recursion_depth,
PLINT ifextrapolygon,
100 void ( *
fill )(
short *,
short *,
PLINT ),
135 PLINT *xpoly, *ypoly;
139 if ( plsc->level < 3 )
141 plabort(
"plfill: Please set up window first" );
146 plabort(
"plfill: Not enough points in object" );
152 xpoly = (
PLINT *) malloc( (
size_t) ( n + 1 ) *
sizeof (
PLINT ) );
153 ypoly = (
PLINT *) malloc( (
size_t) ( n + 1 ) *
sizeof (
PLINT ) );
155 if ( ( xpoly == NULL ) || ( ypoly == NULL ) )
157 plexit(
"plfill: Insufficient memory for large polygon" );
166 for ( i = 0; i < n; i++ )
173 if ( xpoly[0] != xpoly[n - 1] || ypoly[0] != ypoly[n - 1] )
176 xpoly[n - 1] = xpoly[0];
177 ypoly[n - 1] = ypoly[0];
180 plP_plfclp( xpoly, ypoly, n, plsc->clpxmi, plsc->clpxma,
181 plsc->clpymi, plsc->clpyma,
plP_fill );
208 PLINT *xpoly, *ypoly;
211 PLFLT xmin, xmax, ymin, ymax, zmin, zmax, zscale;
213 if ( plsc->level < 3 )
215 plabort(
"plfill3: Please set up window first" );
220 plabort(
"plfill3: Not enough points in object" );
227 tx = (
PLFLT *) malloc( (
size_t) ( n + 1 ) *
sizeof (
PLFLT ) );
228 ty = (
PLFLT *) malloc( (
size_t) ( n + 1 ) *
sizeof (
PLFLT ) );
229 tz = (
PLFLT *) malloc( (
size_t) ( n + 1 ) *
sizeof (
PLFLT ) );
230 xpoly = (
PLINT *) malloc( (
size_t) ( n + 1 ) *
sizeof (
PLINT ) );
231 ypoly = (
PLINT *) malloc( (
size_t) ( n + 1 ) *
sizeof (
PLINT ) );
233 if ( ( tx == NULL ) || ( ty == NULL ) || ( tz == NULL ) ||
234 ( xpoly == NULL ) || ( ypoly == NULL ) )
236 plexit(
"plfill3: Insufficient memory for large polygon" );
248 plP_gdom( &xmin, &xmax, &ymin, &ymax );
252 for ( i = 0; i < n; i++ )
254 tx[i] = x[i]; ty[i] = y[i]; tz[i] = z[i];
256 if ( tx[0] != tx[n - 1] || ty[0] != ty[n - 1] || tz[0] != tz[n - 1] )
259 tx[n - 1] = tx[0]; ty[n - 1] = ty[0]; tz[n - 1] = tz[0];
261 V[0] = tx; V[1] = ty; V[2] = tz;
268 for ( i = 0; i < n; i++ )
286 plP_plfclp( xpoly, ypoly, n, plsc->clpxmi, plsc->clpxma,
287 plsc->clpymi, plsc->clpyma,
plP_fill );
310 PLINT xp1, yp1, xp2, yp2, xp3, yp3;
320 plabort(
"plfill: Out of memory" );
326 plbuf_write = plsc->plbuf_write;
327 plsc->plbuf_write =
FALSE;
330 for ( k = 0; k < plsc->nps; k++ )
334 temp =
DTOR * plsc->inclin[k] * 0.1;
335 si = sin( temp ) * plsc->ypmm;
336 ci = cos( temp ) * plsc->xpmm;
340 temp = sqrt( (
double) ( si * si + ci * ci ) );
344 dinc = (
PLINT) ( plsc->delta[k] *
SSQR( plsc->ypmm *
ABS( ci ),
345 plsc->xpmm *
ABS( si ) ) / 1000. );
362 for ( i = 0; i < n; i++ )
367 buildlist( xp1, yp1, xp2, yp2, xp3, yp3, dinc );
397 fprintf( stderr,
"plfill: oh oh we are lost\n" );
400 fprintf( stderr,
"plfill: %d %d\n",
426 *a = (
PLINT) floor( (
double) ( ta * c + tb * d + 0.5 ) );
427 *b = (
PLINT) floor( (
double) ( tb * c - ta * d + 0.5 ) );
435 PLINT dx, dy, cstep, nstep, ploty, plotx;
442 if ( yp2 > yp3 && ( ( yp2 % dinc ) == 0 ) )
460 nstep = ( yp3 > yp2 ? 1 : -1 );
466 ploty = ( min_y / dinc ) * dinc;
470 for (; ploty <= max_y; ploty += dinc )
476 if ( cstep == -nstep )
478 if ( yp2 == yp3 && yp1 > yp2 )
481 plotx = xp1 + (
PLINT) floor( ( (
double) ( ploty - yp1 ) * dx ) / dy + 0.5 );
499 plexit(
"plfill: Out of memory!" );
509 compar(
const void *pnum1,
const void *pnum2 )
511 const struct point *pnt1, *pnt2;
513 pnt1 = (
const struct point *) pnum1;
514 pnt2 = (
const struct point *) pnum2;
516 if ( pnt1->
y < pnt2->
y )
518 else if ( pnt1->
y > pnt2->
y )
523 if ( pnt1->
x < pnt2->
x )
525 else if ( pnt1->
x > pnt2->
x )
540 void ( *draw )(
short *,
short *,
PLINT ) )
542 #ifdef USE_FILL_INTERSECTION_POLYGON
543 PLINT *x10, *y10, *x1, *y1, *if1, i1start = 0, i, im1, n1, n1m1,
545 PLINT x2[4] = { xmin, xmax, xmax, xmin };
546 PLINT y2[4] = { ymin, ymin, ymax, ymax };
547 PLINT if2[4] = { 0, 0, 0, 0 };
551 if ( npts < 3 || !draw )
554 if ( ( x10 = (
PLINT *) malloc( (
size_t) npts *
sizeof (
PLINT ) ) ) == NULL )
556 plexit(
"plP_plfclp: Insufficient memory" );
558 if ( ( y10 = (
PLINT *) malloc( (
size_t) npts *
sizeof (
PLINT ) ) ) == NULL )
560 plexit(
"plP_plfclp: Insufficient memory" );
568 for ( i = 0; i < npts; i++ )
570 if ( !( x[i] == x[im1] && y[i] == y[im1] ) )
591 if ( positive_orientation( n1, x10, y10 ) )
598 if ( ( x1 = (
PLINT *) malloc( (
size_t) n1 *
sizeof (
PLINT ) ) ) == NULL )
600 plexit(
"plP_plfclp: Insufficient memory" );
602 if ( ( y1 = (
PLINT *) malloc( (
size_t) n1 *
sizeof (
PLINT ) ) ) == NULL )
604 plexit(
"plP_plfclp: Insufficient memory" );
607 for ( i = 0; i < n1; i++ )
609 x1[n1m1 - i] = x10[i];
610 y1[n1m1 - i] = y10[i];
620 for ( i = 0; i < n1; i++ )
622 if ( ( ifnotpointinpolygon =
628 if ( ifnotpointinpolygon )
629 fill_intersection_polygon( 0, 0, 0, draw, x1, y1, i1start, n1, x2, y2, if2, n2 );
632 if ( ( if1 = (
PLINT *) calloc( n1,
sizeof (
PLINT ) ) ) == NULL )
634 plexit(
"plP_plfclp: Insufficient memory" );
636 fill_intersection_polygon( 0, 0, 0, draw, x2, y2, i1start, n2, x1, y1, if1, n1 );
643 #else // USE_FILL_INTERSECTION_POLYGON
645 PLINT i, x1, x2, y1, y2;
646 int iclp = 0, iout = 2;
648 short *xclp = NULL, *yclp = NULL;
650 int crossed_xmin1 = 0, crossed_xmax1 = 0;
651 int crossed_ymin1 = 0, crossed_ymax1 = 0;
652 int crossed_xmin2 = 0, crossed_xmax2 = 0;
653 int crossed_ymin2 = 0, crossed_ymax2 = 0;
654 int crossed_up = 0, crossed_down = 0;
655 int crossed_left = 0, crossed_right = 0;
662 if ( npts < 3 || !draw )
672 if ( ( ( xclp = (
short *) malloc( (
size_t) ( 2 * npts + 2 ) *
sizeof (
short ) ) ) == NULL ) ||
673 ( ( yclp = (
short *) malloc( (
size_t) ( 2 * npts + 2 ) *
sizeof (
short ) ) ) == NULL ) )
675 plexit(
"plP_plfclp: Insufficient memory" );
683 for ( i = 0; i < npts - 1; i++ )
685 x1 = x[i]; x2 = x[i + 1];
686 y1 = y[i]; y2 = y[i + 1];
691 xmin, xmax, ymin, ymax );
696 crossed_xmin2 = ( x1 == xmin ); crossed_xmax2 = ( x1 == xmax );
697 crossed_ymin2 = ( y1 == ymin ); crossed_ymax2 = ( y1 == ymax );
699 crossed_left = ( crossed_left || crossed_xmin2 );
700 crossed_right = ( crossed_right || crossed_xmax2 );
701 crossed_down = ( crossed_down || crossed_ymin2 );
702 crossed_up = ( crossed_up || crossed_ymax2 );
708 xclp[iclp] = (short) x1; yclp[iclp] = (short) y1; iclp++;
709 xclp[iclp] = (short) x2; yclp[iclp] = (short) y2; iclp++;
715 else if ( x1 == (
int) xclp[iclp - 1] && y1 == (int) yclp[iclp - 1] )
717 xclp[iclp] = (short) x2; yclp[iclp] = (short) y2; iclp++;
731 xclp[iclp + 1] = (short) x2; yclp[iclp + 1] = (short) y2;
732 xclp[iclp + 2] = (short) x1; yclp[iclp + 2] = (short) y1;
733 iout = iout - iclp + 1;
735 if ( ( ( crossed_xmin1 && crossed_xmax2 ) ||
736 ( crossed_xmin2 && crossed_xmax1 ) ) &&
741 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
742 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
746 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
747 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
751 else if ( ( ( crossed_xmin1 && crossed_xmax2 ) ||
752 ( crossed_xmin2 && crossed_xmax1 ) ) &&
757 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
758 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
762 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
763 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
767 else if ( ( ( crossed_ymin1 && crossed_ymax2 ) ||
768 ( crossed_ymin2 && crossed_ymax1 ) ) &&
773 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
774 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
778 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
779 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
783 else if ( ( ( crossed_ymin1 && crossed_ymax2 ) ||
784 ( crossed_ymin2 && crossed_ymax1 ) ) &&
789 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
790 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
794 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
795 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
800 else if ( ( crossed_xmin1 && crossed_ymin2 ) ||
801 ( crossed_ymin1 && crossed_xmin2 ) )
803 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
806 else if ( ( crossed_xmax1 && crossed_ymin2 ) ||
807 ( crossed_ymin1 && crossed_xmax2 ) )
809 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
812 else if ( ( crossed_xmin1 && crossed_ymax2 ) ||
813 ( crossed_ymax1 && crossed_xmin2 ) )
815 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
818 else if ( ( crossed_xmax1 && crossed_ymax2 ) ||
819 ( crossed_ymax1 && crossed_xmax2 ) )
821 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
825 xclp[iclp] = (short) x1; yclp[iclp] = (short) y1; iclp++;
826 xclp[iclp] = (short) x2; yclp[iclp] = (short) y2; iclp++;
830 crossed_xmin1 = ( x2 == xmin ); crossed_xmax1 = ( x2 == xmax );
831 crossed_ymin1 = ( y2 == ymin ); crossed_ymax1 = ( y2 == ymax );
842 xclp[0] = (short) xmin; yclp[0] = (short) ymin;
843 xclp[1] = (short) xmax; yclp[1] = (short) ymin;
844 xclp[2] = (short) xmax; yclp[2] = (short) ymax;
845 xclp[3] = (short) xmin; yclp[3] = (short) ymax;
846 xclp[4] = (short) xmin; yclp[4] = (short) ymin;
847 ( *draw )( xclp, yclp, 5 );
867 if ( ( xclp[0] == (
short) xmin && xclp[iclp - 1] == (
short) xmax ) ||
868 ( xclp[0] == (
short) xmax && xclp[iclp - 1] == (
short) xmin ) ||
869 ( yclp[0] == (
short) ymin && yclp[iclp - 1] == (
short) ymax ) ||
870 ( yclp[0] == (
short) ymax && yclp[iclp - 1] == (
short) ymin ) ||
871 ( xclp[0] == (
short) xmin && yclp[iclp - 1] == (
short) ymin ) ||
872 ( yclp[0] == (
short) ymin && xclp[iclp - 1] == (
short) xmin ) ||
873 ( xclp[0] == (
short) xmax && yclp[iclp - 1] == (
short) ymin ) ||
874 ( yclp[0] == (
short) ymin && xclp[iclp - 1] == (
short) xmax ) ||
875 ( xclp[0] == (
short) xmax && yclp[iclp - 1] == (
short) ymax ) ||
876 ( yclp[0] == (
short) ymax && xclp[iclp - 1] == (
short) xmax ) ||
877 ( xclp[0] == (
short) xmin && yclp[iclp - 1] == (
short) ymax ) ||
878 ( yclp[0] == (
short) ymax && xclp[iclp - 1] == (
short) xmin ) )
880 printf(
"dir=%d, clipped points:\n", dir );
881 for ( i = 0; i < iclp; i++ )
882 printf(
" x[%d]=%hd y[%d]=%hd", i, xclp[i], i, yclp[i] );
884 printf(
"pre-clipped points:\n" );
885 for ( i = 0; i < npts; i++ )
886 printf(
" x[%d]=%d y[%d]=%d", i, x[i], i, y[i] );
893 if ( xclp[0] == (
short) xmin && xclp[iclp - 1] == (
short) xmax )
897 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
898 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
902 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
903 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
906 else if ( xclp[0] == (
short) xmax && xclp[iclp - 1] == (short) xmin )
910 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
911 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
915 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
916 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
921 else if ( yclp[0] == (
short) ymin && yclp[iclp - 1] == (short) ymax )
925 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
926 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
930 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
931 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
934 else if ( yclp[0] == (
short) ymax && yclp[iclp - 1] == (short) ymin )
938 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
939 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
943 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
944 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
960 else if ( ( xclp[0] == (
short) xmin && yclp[iclp - 1] == (short) ymin && dir < 0 ) ||
961 ( yclp[0] == (short) ymin && xclp[iclp - 1] == (
short) xmin && dir > 0 ) )
963 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
966 else if ( ( xclp[0] == (
short) xmin && yclp[iclp - 1] == (short) ymin && dir > 0 ) )
968 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
969 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
970 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
973 else if ( ( yclp[0] == ymin && xclp[iclp - 1] == xmin && dir < 0 ) )
975 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
976 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
977 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
980 else if ( ( xclp[0] == (
short) xmax && yclp[iclp - 1] == (short) ymin && dir > 0 ) ||
981 ( yclp[0] == (short) ymin && xclp[iclp - 1] == (
short) xmax && dir < 0 ) )
983 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
986 else if ( yclp[0] == (
short) ymin && xclp[iclp - 1] == (short) xmax && dir > 0 )
988 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
989 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
990 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
993 else if ( xclp[0] == (
short) xmax && yclp[iclp - 1] == (short) ymin && dir < 0 )
995 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
996 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
997 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
1000 else if ( ( xclp[0] == (
short) xmax && yclp[iclp - 1] == (short) ymax && dir < 0 ) ||
1001 ( yclp[0] == (short) ymax && xclp[iclp - 1] == (
short) xmax && dir > 0 ) )
1003 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
1006 else if ( xclp[0] == (
short) xmax && yclp[iclp - 1] == (short) ymax && dir > 0 )
1008 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
1009 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
1010 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
1013 else if ( yclp[0] == (
short) ymax && xclp[iclp - 1] == (short) xmax && dir < 0 )
1015 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
1016 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
1017 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
1020 else if ( ( xclp[0] == (
short) xmin && yclp[iclp - 1] == (short) ymax && dir > 0 ) ||
1021 ( yclp[0] == (short) ymax && xclp[iclp - 1] == (
short) xmin && dir < 0 ) )
1023 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymax; iclp++;
1026 else if ( yclp[0] == (
short) ymax && xclp[iclp - 1] == (short) xmin && dir > 0 )
1028 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
1029 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
1030 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
1033 else if ( xclp[0] == (
short) xmin && yclp[iclp - 1] == (short) ymax && dir < 0 )
1035 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymax; iclp++;
1036 xclp[iclp] = (short) xmax; yclp[iclp] = (short) ymin; iclp++;
1037 xclp[iclp] = (short) xmin; yclp[iclp] = (short) ymin; iclp++;
1046 if ( inside_lb + inside_rb + inside_lu + inside_ru == 4 )
1049 PLINT xlim[4], ylim[4];
1053 xlim[0] = xmin; ylim[0] = ymin;
1054 xlim[1] = xmax; ylim[1] = ymin;
1055 xlim[2] = xmax; ylim[2] = ymax;
1056 xlim[3] = xmin; ylim[3] = ymax;
1058 if ( crossed_left + crossed_right + crossed_down + crossed_up == 1 )
1063 insert = 0 * crossed_left + 1 * crossed_down + 2 * crossed_right +
1069 insert = 3 * crossed_left + 2 * crossed_up + 1 * crossed_right +
1074 if ( crossed_left + crossed_right == 2 && crossed_down + crossed_up == 0 )
1076 if ( xclp[iclp - 1] == xmin )
1104 if ( crossed_left + crossed_right == 0 && crossed_down + crossed_up == 2 )
1106 if ( yclp[iclp - 1] == ymin )
1134 for ( i = 0; i < 4; i++ )
1136 xclp[iclp] = (short) xlim[insert];
1137 yclp[iclp] = (short) ylim[insert];
1149 ( *draw )( xclp, yclp, iclp );
1151 if ( xclp != _xclp )
1157 #endif // USE_FILL_INTERSECTION_POLYGON
1187 PLFLT x1, y1, x2, y2, x3, y3;
1193 for ( i = 1; i < npts - 2; i++ )
1199 xproduct = xproduct + ( x2 - x1 ) * ( y3 - y2 ) - ( y2 - y1 ) * ( x3 - x2 );
1202 if ( xproduct > 0.0 )
1204 if ( xproduct < 0.0 )
1214 int i, return_value;
1216 PLFLT xmaximum = fabs( xp ), ymaximum = fabs( yp ), xscale, yscale;
1217 if ( ( xint = (
PLINT *) malloc( (
size_t) n *
sizeof (
PLINT ) ) ) == NULL )
1219 plexit(
"PlP_pointinpolygon: Insufficient memory" );
1221 if ( ( yint = (
PLINT *) malloc( (
size_t) n *
sizeof (
PLINT ) ) ) == NULL )
1223 plexit(
"PlP_pointinpolygon: Insufficient memory" );
1225 for ( i = 0; i < n; i++ )
1227 xmaximum =
MAX( xmaximum, fabs( x[i] ) );
1228 ymaximum =
MAX( ymaximum, fabs( y[i] ) );
1230 xscale = 1.e8 / xmaximum;
1231 yscale = 1.e8 / ymaximum;
1232 for ( i = 0; i < n; i++ )
1234 xint[i] = (
PLINT) ( xscale * x[i] );
1235 yint[i] = (
PLINT) ( yscale * y[i] );
1238 (
PLINT) ( xscale * xp ), (
PLINT) ( yscale * yp ) );
1241 return return_value;
1256 #define NEW_NOTPOINTINPOLYGON_CODE
1260 #ifdef NEW_NOTPOINTINPOLYGON_CODE
1261 int i, im1, ifnotcrossed;
1262 int count_crossings = 0;
1263 PLINT xmin, xout, yout, xintersect, yintersect;
1271 for ( i = 1; i < n; i++ )
1273 xout =
MAX( xout, x[i] );
1274 xmin =
MIN( xmin, x[i] );
1277 xout = xout + ( xout - xmin ) + 10;
1283 for ( i = 0; i < n; i++ )
1285 if ( !( x[im1] == x[i] && y[im1] == y[i] ) )
1287 ifnotcrossed =
notcrossed( &xintersect, &yintersect,
1288 x[im1], y[im1], x[i], y[i],
1289 xp, yp, xout, yout );
1291 if ( !ifnotcrossed )
1303 if ( ( count_crossings % 2 ) == 1 )
1308 #else // NEW_NOTPOINTINPOLYGON_CODE
1310 int count_crossings;
1311 PLFLT x1, y1, x2, y2, xpp, ypp, xout, yout, xmax;
1312 PLFLT xvp, yvp, xvv, yvv, xv1, yv1, xv2, yv2;
1313 PLFLT inprod1, inprod2;
1318 count_crossings = 0;
1326 for ( i = 0; i < n; i++ )
1337 xout = xout - ( xmax - xout );
1348 for ( i = 0; i < n; i++ )
1354 x2 = (
PLFLT) x[i + 1];
1355 y2 = (
PLFLT) y[i + 1];
1364 if ( x1 == x2 && y1 == y2 )
1375 inprod1 = xv1 * yvp - yv1 * xvp;
1376 inprod2 = xv2 * yvp - yv2 * xvp;
1377 if ( inprod1 * inprod2 >= 0.0 )
1391 inprod1 = xv1 * yvv - yv1 * xvv;
1392 inprod2 = xv2 * yvv - yv2 * xvv;
1393 if ( inprod1 * inprod2 >= 0.0 )
1406 return !( count_crossings % 2 );
1408 #endif // NEW_NOTPOINTINPOLYGON_CODE
1410 #define MAX_RECURSION_DEPTH 10
1458 #ifdef USE_FILL_INTERSECTION_POLYGON
1460 fill_intersection_polygon(
PLINT recursion_depth,
PLINT ifextrapolygon,
1462 void ( *
fill )(
short *,
short *,
PLINT ),
1468 PLINT i1, i1m1, i1start_new,
1470 kk, kkstart1, kkstart21, kkstart22,
1472 range21, range22, ncrossed, ncrossed_change,
1473 nsplit1, nsplit2, nsplit2m1;
1474 PLINT xintersect[2], yintersect[2], i1intersect[2],
1476 PLINT *xsplit1, *ysplit1, *ifsplit1,
1477 *xsplit2, *ysplit2, *ifsplit2;
1478 PLINT ifill, nfill = 0,
1479 ifnotpolygon1inpolygon2, ifnotpolygon2inpolygon1;
1481 short *xfill, *yfill;
1485 plwarn(
"fill_intersection_polygon: Recursion_depth too large. "
1486 "Probably an internal error figuring out intersections. " );
1492 plwarn(
"fill_intersection_polygon: Internal error; n1 < 3." );
1498 plwarn(
"fill_intersection_polygon: Internal error; n2 < 3." );
1502 if ( i1start < 0 || i1start >= n1 )
1504 plwarn(
"fill_intersection_polygon: invalid i1start." );
1513 for ( i1 = i1start; i1 < n1; i1++ )
1515 if ( x1[i1] == x1[i1m1] && y1[i1] == y1[i1m1] )
1522 plwarn(
"fill_intersection_polygon: Internal error; i1 < n1." );
1527 for ( i2 = 0; i2 < n2; i2++ )
1529 if ( x2[i2] == x2[i2m1] && y2[i2] == y2[i2m1] )
1536 plwarn(
"fill_intersection_polygon: Internal error; i2 < n2." );
1599 for ( i1 = i1start; i1 < n1; i1++ )
1601 ncrossed_change = number_crossings(
1602 &xintersect[ncrossed], &yintersect[ncrossed],
1603 &i2intersect[ncrossed], 2 - ncrossed,
1604 i1, n1, x1, y1, n2, x2, y2 );
1605 if ( ncrossed_change > 0 )
1607 i1intersect[ncrossed] = i1;
1608 if ( ncrossed_change == 2 )
1612 i1intersect[1] = i1;
1614 ncrossed += ncrossed_change;
1615 if ( ncrossed == 2 )
1630 range1 = i1intersect[1] - i1intersect[0];
1637 kkstart1 = i1intersect[0];
1642 range21 = i2intersect[0] - i2intersect[1];
1655 int ifxsort, ifascend;
1661 i2 = i2intersect[1];
1666 ifxsort = abs( x2[i2] - x2[i2m1] ) > abs( y2[i2] - y2[i2m1] );
1667 ifascend = ( ifxsort && x2[i2] > x2[i2m1] ) ||
1668 ( !ifxsort && y2[i2] > y2[i2m1] );
1669 if ( ( ifxsort && ifascend && xintersect[0] < xintersect[1] ) ||
1670 ( !ifxsort && ifascend && yintersect[0] < yintersect[1] ) ||
1671 ( ifxsort && !ifascend && xintersect[0] >= xintersect[1] ) ||
1672 ( !ifxsort && !ifascend && yintersect[0] >= yintersect[1] ) )
1678 kkstart21 = i2intersect[1];
1679 nsplit1 = 2 + range1 + range21;
1685 range22 = n2 - range21;
1687 kkstart22 = i2intersect[1] - 1;
1688 if ( kkstart22 < 0 )
1690 nsplit2 = 2 + range1 + range22;
1692 if ( ( xsplit1 = (
PLINT *) malloc( (
size_t) nsplit1 *
sizeof (
PLINT ) ) ) == NULL )
1694 plexit(
"fill_intersection_polygon: Insufficient memory" );
1696 if ( ( ysplit1 = (
PLINT *) malloc( (
size_t) nsplit1 *
sizeof (
PLINT ) ) ) == NULL )
1698 plexit(
"fill_intersection_polygon: Insufficient memory" );
1700 if ( ( ifsplit1 = (
PLINT *) malloc( (
size_t) nsplit1 *
sizeof (
PLINT ) ) ) == NULL )
1702 plexit(
"fill_intersection_polygon: Insufficient memory" );
1705 if ( ( xsplit2 = (
PLINT *) malloc( (
size_t) nsplit2 *
sizeof (
PLINT ) ) ) == NULL )
1707 plexit(
"fill_intersection_polygon: Insufficient memory" );
1709 if ( ( ysplit2 = (
PLINT *) malloc( (
size_t) nsplit2 *
sizeof (
PLINT ) ) ) == NULL )
1711 plexit(
"fill_intersection_polygon: Insufficient memory" );
1713 if ( ( ifsplit2 = (
PLINT *) malloc( (
size_t) nsplit2 *
sizeof (
PLINT ) ) ) == NULL )
1715 plexit(
"fill_intersection_polygon: Insufficient memory" );
1726 xsplit1[k] = xintersect[0];
1727 ysplit1[k] = yintersect[0];
1729 nsplit2m1 = nsplit2 - 1;
1730 xsplit2[nsplit2m1 - k] = xintersect[0];
1731 ysplit2[nsplit2m1 - k] = yintersect[0];
1732 ifsplit2[nsplit2m1 - k] = 1;
1738 for ( k = kstart; k < range1 + 1; k++ )
1740 xsplit1[k] = x1[kk];
1741 ysplit1[k] = y1[kk];
1743 xsplit2[nsplit2m1 - k] = x1[kk];
1744 ysplit2[nsplit2m1 - k] = y1[kk++];
1745 ifsplit2[nsplit2m1 - k] = 2;
1747 xsplit1[k] = xintersect[1];
1748 ysplit1[k] = yintersect[1];
1750 xsplit2[nsplit2m1 - k] = xintersect[1];
1751 ysplit2[nsplit2m1 - k] = yintersect[1];
1752 ifsplit2[nsplit2m1 - k] = 1;
1758 for ( k = kstart; k < nsplit1; k++ )
1760 xsplit1[k] = x2[kk];
1761 ysplit1[k] = y2[kk];
1762 ifsplit1[k] = if2[kk++];
1772 fill_intersection_polygon(
1773 recursion_depth + 1, ifextrapolygon, 1,
fill,
1774 x1, y1, i1start_new, n1,
1775 xsplit1, ysplit1, ifsplit1, nsplit1 );
1783 for ( k = kstart; k < nsplit2; k++ )
1785 xsplit2[nsplit2m1 - k] = x2[kk];
1786 ysplit2[nsplit2m1 - k] = y2[kk];
1787 ifsplit2[nsplit2m1 - k] = if2[kk--];
1797 fill_intersection_polygon(
1798 recursion_depth + 1, ifextrapolygon, -1,
fill,
1799 x1, y1, i1start_new, n1,
1800 xsplit2, ysplit2, ifsplit2, nsplit2 );
1810 if ( ncrossed != 0 )
1812 plwarn(
"fill_intersection_polygon: Internal error; ncrossed != 0." );
1821 if ( fill_status == -1 )
1823 else if ( fill_status == 1 )
1829 else if ( fill_status == 0 )
1832 if ( recursion_depth != 0 )
1834 plwarn(
"fill_intersection_polygon: Internal error; fill_status == 0 for recursion_depth > 0" );
1847 for ( i1 = 0; i1 < n1; i1++ )
1849 if ( ( ifnotpolygon1inpolygon2 =
1856 ifnotpolygon2inpolygon1 = 1;
1857 for ( i2 = 0; i2 < n2; i2++ )
1861 if ( !if2[i2] && ( ifnotpolygon2inpolygon1 =
1866 if ( ifnotpolygon2inpolygon1 == 0 && ifnotpolygon1inpolygon2 == 0 )
1867 plwarn(
"fill_intersection_polygon: Internal error; no intersections found but each polygon definitely inside the other!" );
1868 else if ( ifnotpolygon2inpolygon1 == 2 && ifnotpolygon1inpolygon2 == 2 )
1872 else if ( ifnotpolygon2inpolygon1 == 0 )
1879 else if ( ifnotpolygon1inpolygon2 == 0 )
1886 else if ( ifnotpolygon2inpolygon1 == 1 && ifnotpolygon1inpolygon2 == 1 )
1899 plwarn(
"fill_intersection_polygon: inscribed polygons are still ToDo" );
1905 if ( ( xfill = (
short *) malloc( (
size_t) nfill *
sizeof (
short ) ) ) == NULL )
1907 plexit(
"fill_intersection_polygon: Insufficient memory" );
1909 if ( ( yfill = (
short *) malloc( (
size_t) nfill *
sizeof (
short ) ) ) == NULL )
1911 plexit(
"fill_intersection_polygon: Insufficient memory" );
1913 for ( ifill = 0; ifill < nfill; ifill++ )
1915 xfill[ifill] = (short) xfiller[ifill];
1916 yfill[ifill] = (short) yfiller[ifill];
1918 ( *fill )( xfill, yfill, nfill );
1943 PLFLT factor, factor_NBCC, fxintersect, fyintersect;
1946 PLFLT xA2A1, yA2A1, xB2B1, yB2B1;
1947 PLFLT xB1A1, yB1A1, xB2A1, yB2A1;
1972 factor = xA2A1 * yB2B1 - yA2A1 * xB2B1;
1973 factor_NBCC =
PL_NBCC * ( fabs( xA2A1 ) + fabs( yB2B1 ) + fabs( yA2A1 ) + fabs( xB2B1 ) );
1974 if ( fabs( factor ) <= factor_NBCC )
1976 if ( fabs( factor ) > 0. )
1988 factor = ( xB1A1 * yB2A1 - yB1A1 * xB2A1 ) / factor;
1989 fxintersect = factor * xA2A1 + xA1;
1990 fyintersect = factor * yA2A1 + yA1;
1999 if ( fabs( fxintersect - xA1 ) <=
PL_NBCC && fabs( fyintersect - yA1 ) <=
PL_NBCC )
2001 else if ( fabs( fxintersect - xA2 ) <=
PL_NBCC && fabs( fyintersect - yA2 ) <=
PL_NBCC )
2003 else if ( fabs( fxintersect - xB1 ) <=
PL_NBCC && fabs( fyintersect - yB1 ) <=
PL_NBCC )
2005 else if ( fabs( fxintersect - xB2 ) <=
PL_NBCC && fabs( fyintersect - yB2 ) <=
PL_NBCC )
2015 *xintersect = (
PLINT) fxintersect;
2016 *yintersect = (
PLINT) fyintersect;
2022 #ifdef USE_FILL_INTERSECTION_POLYGON
2041 PLFLT twice_area = 0.;
2044 plwarn(
"positive_orientation: internal logic error, n < 3" );
2048 for ( i = 0; i < n; i++ )
2053 if ( twice_area == 0. )
2055 plwarn(
"positive_orientation: internal logic error, twice_area == 0." );
2059 return twice_area > 0.;
2079 int i1m1, i2, i2m1, ifnotcrossed;
2080 int ifxsort, ifascend, count_crossings = 0, status = 0;
2081 PLINT xintersect, yintersect;
2086 if ( !( ncross == 1 || ncross == 2 ) ||
2087 ( x1[i1m1] == x1[i1] && y1[i1m1] == y1[i1] ) || n1 < 2 || n2 < 2 )
2089 plwarn(
"findcrossings: invalid call" );
2093 ifxsort = abs( x1[i1] - x1[i1m1] ) > abs( y1[i1] - y1[i1m1] );
2094 ifascend = ( ifxsort && x1[i1] > x1[i1m1] ) ||
2095 ( !ifxsort && y1[i1] > y1[i1m1] );
2107 for ( i2 = 0; i2 < n2; i2++ )
2109 if ( !( x2[i2m1] == x2[i2] && y2[i2m1] == y2[i2] ) )
2111 ifnotcrossed =
notcrossed( &xintersect, &yintersect,
2112 x1[i1m1], y1[i1m1], x1[i1], y1[i1],
2113 x2[i2m1], y2[i2m1], x2[i2], y2[i2] );
2115 if ( !ifnotcrossed )
2118 if ( count_crossings == 1 )
2120 xcross[0] = xintersect;
2121 ycross[0] = yintersect;
2127 if ( ( ifxsort && ifascend && xintersect < xcross[0] ) ||
2128 ( !ifxsort && ifascend && yintersect < ycross[0] ) ||
2129 ( ifxsort && !ifascend && xintersect >= xcross[0] ) ||
2130 ( !ifxsort && !ifascend && yintersect >= ycross[0] ) )
2134 xcross[1] = xcross[0];
2135 ycross[1] = ycross[0];
2136 i2cross[1] = i2cross[0];
2139 xcross[0] = xintersect;
2140 ycross[0] = yintersect;
2143 else if ( ncross == 2 && ( count_crossings == 2 || (
2144 ( ifxsort && ifascend && xintersect < xcross[1] ) ||
2145 ( !ifxsort && ifascend && yintersect < ycross[1] ) ||
2146 ( ifxsort && !ifascend && xintersect >= xcross[1] ) ||
2147 ( !ifxsort && !ifascend && yintersect >= ycross[1] ) ) ) )
2149 xcross[1] = xintersect;
2150 ycross[1] = yintersect;
void plexit(PLCHAR_VECTOR errormsg)
static int compar(const void *, const void *)
static int notcrossed(PLINT *xintersect, PLINT *yintersect, PLINT xA1, PLINT yA1, PLINT xA2, PLINT yA2, PLINT xB1, PLINT yB1, PLINT xB2, PLINT yB2)
void plP_grange(PLFLT *p_zscl, PLFLT *p_zmin, PLFLT *p_zmax)
int plP_clipline(PLINT *p_x1, PLINT *p_y1, PLINT *p_x2, PLINT *p_y2, PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax)
void plabort(PLCHAR_VECTOR errormsg)
static void tran(PLINT *, PLINT *, PLFLT, PLFLT)
static int notpointinpolygon(PLINT n, PLINT_VECTOR x, PLINT_VECTOR y, PLINT xp, PLINT yp)
int plP_clip_poly(int Ni, PLFLT *Vi[3], int axis, PLFLT dir, PLFLT offset)
#define TRANSFORM(x, y, xnew, ynew)
void c_plfill3(PLINT n, PLFLT_VECTOR x, PLFLT_VECTOR y, PLFLT_VECTOR z)
const PLINT * PLINT_VECTOR
static void addcoord(PLINT, PLINT)
PLFLT plP_w3wcy(PLFLT x, PLFLT y, PLFLT z)
#define BETW_NBCC(ix, ia, ib)
static int circulation(PLINT *x, PLINT *y, PLINT npts)
static void buildlist(PLINT, PLINT, PLINT, PLINT, PLINT, PLINT, PLINT)
void plP_draphy(PLINT x, PLINT y)
void plP_fill(short *x, short *y, PLINT npts)
void plfill_soft(short *x, short *y, PLINT n)
PLFLT plP_w3wcx(PLFLT x, PLFLT y, PLFLT PL_UNUSED(z))
void plP_movphy(PLINT x, PLINT y)
#define MAX_RECURSION_DEPTH
void plP_plfclp(PLINT *x, PLINT *y, PLINT npts, PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax, void(*draw)(short *, short *, PLINT))
int plP_pointinpolygon(PLINT n, PLFLT_VECTOR x, PLFLT_VECTOR y, PLFLT xp, PLFLT yp)
void plwarn(PLCHAR_VECTOR errormsg)
void plbuf_write(PLStream *pls, void *data, size_t bytes)
const PLFLT * PLFLT_VECTOR
void plP_gdom(PLFLT *p_xmin, PLFLT *p_xmax, PLFLT *p_ymin, PLFLT *p_ymax)
PLDLLIMPEXP_CXX void fill(PLINT n, const PLFLT *x, const PLFLT *y)
void c_plfill(PLINT n, PLFLT_VECTOR x, PLFLT_VECTOR y)