void draw_table() /********绘制球桌********/ { setlinestyle(0,0,3); setcolor(WHITE); setwritemode(COPY_PUT); rectangle(1,100,638,480); draw_boundary(); draw_net(); setfillstyle(SOLID_FILL,TABLECOLOR); floodfill(300,400,WHITE); setfillstyle(SOLID_FILL,6); floodfill(20,290,WHITE); floodfill(620,290,WHITE); draw_mark(); }
static void plshade_int( PLFLT ( *f2eval )( PLINT, PLINT, PLPointer ), PLPointer f2eval_data, PLFLT ( * c2eval )( PLINT, PLINT, PLPointer ), // unused, but macro doesn't work PLPointer PL_UNUSED( c2eval_data ), PLINT ( *defined )( PLFLT, PLFLT ), PLINT nx, PLINT ny, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT shade_min, PLFLT shade_max, PLINT sh_cmap, PLFLT sh_color, PLFLT sh_width, PLINT min_color, PLFLT min_width, PLINT max_color, PLFLT max_width, void ( *fill )( PLINT, const PLFLT *, const PLFLT * ), PLINT rectangular, void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ), PLPointer pltr_data ) { PLINT n, slope = 0, ix, iy; int count, i, j, nxny; PLFLT *a, *a0, *a1, dx, dy; PLFLT x[8], y[8], xp[2], tx, ty, init_width; int *c, *c0, *c1; (void) c2eval; // Cast to void to silence compiler warning about unused parameter if ( plsc->level < 3 ) { plabort( "plfshade: window must be set up first" ); return; } if ( nx <= 0 || ny <= 0 ) { plabort( "plfshade: nx and ny must be positive" ); return; } if ( shade_min >= shade_max ) { plabort( "plfshade: shade_max must exceed shade_min" ); return; } if ( pltr == NULL && plsc->coordinate_transform == NULL ) rectangular = 1; int_val = shade_max - shade_min; init_width = plsc->width; pen_col_min = min_color; pen_col_max = max_color; pen_wd_min = min_width; pen_wd_max = max_width; plstyl( (PLINT) 0, NULL, NULL ); plwidth( sh_width ); if ( fill != NULL ) { switch ( sh_cmap ) { case 0: plcol0( (PLINT) sh_color ); break; case 1: plcol1( sh_color ); break; default: plabort( "plfshade: invalid color map selection" ); return; } } // alloc space for value array, and initialize // This is only a temporary kludge nxny = nx * ny; if ( ( a = (PLFLT *) malloc( (size_t) nxny * sizeof ( PLFLT ) ) ) == NULL ) { plabort( "plfshade: unable to allocate memory for value array" ); return; } for ( ix = 0; ix < nx; ix++ ) for ( iy = 0; iy < ny; iy++ ) a[iy + ix * ny] = f2eval( ix, iy, f2eval_data ); // alloc space for condition codes if ( ( c = (int *) malloc( (size_t) nxny * sizeof ( int ) ) ) == NULL ) { plabort( "plfshade: unable to allocate memory for condition codes" ); free( a ); return; } sh_min = shade_min; sh_max = shade_max; set_cond( c, a, nxny ); dx = ( xmax - xmin ) / ( nx - 1 ); dy = ( ymax - ymin ) / ( ny - 1 ); a0 = a; a1 = a + ny; c0 = c; c1 = c + ny; for ( ix = 0; ix < nx - 1; ix++ ) { for ( iy = 0; iy < ny - 1; iy++ ) { count = c0[iy] + c0[iy + 1] + c1[iy] + c1[iy + 1]; // No filling needs to be done for these cases if ( count >= UNDEF ) continue; if ( count == 4 * POS ) continue; if ( count == 4 * NEG ) continue; // Entire rectangle can be filled if ( count == 4 * OK ) { // find biggest rectangle that fits if ( rectangular ) { big_recl( c0 + iy, ny, nx - ix, ny - iy, &i, &j ); } else { i = j = 1; } x[0] = x[1] = ix; x[2] = x[3] = ix + i; y[0] = y[3] = iy; y[1] = y[2] = iy + j; if ( pltr ) { for ( i = 0; i < 4; i++ ) { ( *pltr )( x[i], y[i], &tx, &ty, pltr_data ); x[i] = tx; y[i] = ty; } } else { for ( i = 0; i < 4; i++ ) { x[i] = xmin + x[i] * dx; y[i] = ymin + y[i] * dy; } } if ( fill != NULL ) exfill( fill, defined, (PLINT) 4, x, y ); iy += j - 1; continue; } // Only part of rectangle can be filled n_point = min_points = max_points = 0; n = find_interval( a0[iy], a0[iy + 1], c0[iy], c0[iy + 1], xp ); for ( j = 0; j < n; j++ ) { x[j] = ix; y[j] = iy + xp[j]; } i = find_interval( a0[iy + 1], a1[iy + 1], c0[iy + 1], c1[iy + 1], xp ); for ( j = 0; j < i; j++ ) { x[j + n] = ix + xp[j]; y[j + n] = iy + 1; } n += i; i = find_interval( a1[iy + 1], a1[iy], c1[iy + 1], c1[iy], xp ); for ( j = 0; j < i; j++ ) { x[n + j] = ix + 1; y[n + j] = iy + 1 - xp[j]; } n += i; i = find_interval( a1[iy], a0[iy], c1[iy], c0[iy], xp ); for ( j = 0; j < i; j++ ) { x[n + j] = ix + 1 - xp[j]; y[n + j] = iy; } n += i; if ( pltr ) { for ( i = 0; i < n; i++ ) { ( *pltr )( x[i], y[i], &tx, &ty, pltr_data ); x[i] = tx; y[i] = ty; } } else { for ( i = 0; i < n; i++ ) { x[i] = xmin + x[i] * dx; y[i] = ymin + y[i] * dy; } } if ( min_points == 4 ) slope = plctestez( a, nx, ny, ix, iy, shade_min ); if ( max_points == 4 ) slope = plctestez( a, nx, ny, ix, iy, shade_max ); // n = number of end of line segments // min_points = number times shade_min meets edge // max_points = number times shade_max meets edge // special cases: check number of times a contour is in a box switch ( ( min_points << 3 ) + max_points ) { case 000: case 020: case 002: case 022: if ( fill != NULL && n > 0 ) exfill( fill, defined, n, x, y ); break; case 040: // 2 contour lines in box case 004: if ( n != 6 ) fprintf( stderr, "plfshade err n=%d !6", (int) n ); if ( slope == 1 && c0[iy] == OK ) { if ( fill != NULL ) exfill( fill, defined, n, x, y ); } else if ( slope == 1 ) { selected_polygon( fill, defined, x, y, 0, 1, 2, -1 ); selected_polygon( fill, defined, x, y, 3, 4, 5, -1 ); } else if ( c0[iy + 1] == OK ) { if ( fill != NULL ) exfill( fill, defined, n, x, y ); } else { selected_polygon( fill, defined, x, y, 0, 1, 5, -1 ); selected_polygon( fill, defined, x, y, 2, 3, 4, -1 ); } break; case 044: if ( n != 8 ) fprintf( stderr, "plfshade err n=%d !8", (int) n ); if ( slope == 1 ) { selected_polygon( fill, defined, x, y, 0, 1, 2, 3 ); selected_polygon( fill, defined, x, y, 4, 5, 6, 7 ); } else { selected_polygon( fill, defined, x, y, 0, 1, 6, 7 ); selected_polygon( fill, defined, x, y, 2, 3, 4, 5 ); } break; case 024: case 042: // 3 contours if ( n != 7 ) fprintf( stderr, "plfshade err n=%d !7", (int) n ); if ( ( c0[iy] == OK || c1[iy + 1] == OK ) && slope == 1 ) { if ( fill != NULL ) exfill( fill, defined, n, x, y ); } else if ( ( c0[iy + 1] == OK || c1[iy] == OK ) && slope == 0 ) { if ( fill != NULL ) exfill( fill, defined, n, x, y ); } else if ( c0[iy] == OK ) { selected_polygon( fill, defined, x, y, 0, 1, 6, -1 ); selected_polygon( fill, defined, x, y, 2, 3, 4, 5 ); } else if ( c0[iy + 1] == OK ) { selected_polygon( fill, defined, x, y, 0, 1, 2, -1 ); selected_polygon( fill, defined, x, y, 3, 4, 5, 6 ); } else if ( c1[iy + 1] == OK ) { selected_polygon( fill, defined, x, y, 0, 1, 5, 6 ); selected_polygon( fill, defined, x, y, 2, 3, 4, -1 ); } else if ( c1[iy] == OK ) { selected_polygon( fill, defined, x, y, 0, 1, 2, 3 ); selected_polygon( fill, defined, x, y, 4, 5, 6, -1 ); } else { fprintf( stderr, "plfshade err logic case 024:042\n" ); } break; default: fprintf( stderr, "prog err switch\n" ); break; } draw_boundary( slope, x, y ); if ( fill != NULL ) { plwidth( sh_width ); if ( sh_cmap == 0 ) plcol0( (PLINT) sh_color ); else if ( sh_cmap == 1 ) plcol1( sh_color ); } } a0 = a1; c0 = c1; a1 += ny; c1 += ny; } free( c ); free( a ); plwidth( init_width ); }