/* See figs3d.h. */ /* Last edited on 2011-09-15 17:59:35 by stolfilocal */ #include #include #include #include #include #include #include #include // #include // #include // #include // #include #include #include void figs_3d_full ( PlotOptions *o, char *tag, interval_t rootCell[], dg_rank_t max_rank ) { char levTag[300]; dg_rank_t r; for (r = 0; r <= max_rank; r++) { sprintf(levTag, "%s-%02d", tag, r); fig_3d_full_level(o, levTag, rootCell, r); } } void fig_3d_full_level( PlotOptions *o, char *tag, interval_t rootCell[], dg_rank_t rank ) { double vdist = 10.0; /* Viewing distance (0 = from infinity.). */ double blow = 1.05; /* Blow-up factor (1 = none). */ auto void do_plot(dg_rank_t r, dg_cell_index_t k, interval_t cell[]); void do_plot(dg_rank_t r, dg_cell_index_t k, interval_t cell[]) { if (r == rank) { /* HACK: supress buried cells (assumed invisible). */ bool_t visible = FALSE; int i; for (i = 0; (!visible) && (i < 3); i++) { bool_t vlo = LO(cell[i]) == LO(rootCell[i]); bool_t vhi = HI(cell[i]) == HI(rootCell[i]); visible |= (vlo | vhi); } if (visible) { plot_3d_cell(ps, o, cell, blow, vdist); } } else { interval_t save = cell[r % 3]; cell[r % 3] = interval_split(save, 0); do_plot(r+1, 2*k, cell); cell[r % 3] = interval_split(save, 1); do_plot(r+1, 2*k + 1, cell); cell[r % 3] = save; } } double scale = o->scale; interval_t bbox[2]; /* Compute bounding box of canonical cell, projected: */ { int u, v, w; bbox[0] = (interval_t){{ INF, -INF }}; bbox[1] = (interval_t){{ INF, -INF }}; for (u = 0; u <= 1; u++) { for (v = 0; v <= 1; v++) { for (w = 0; w <= 1; w++) { double x = rootCell[0].end[u]; double y = rootCell[1].end[v]; double z = rootCell[2].end[w]; double xp, yp, zp; persp_project(x, y, z, &xp, &yp, &zp, vdist); if (xp < LO(bbox[0])) { LO(bbox[0]) = xp; } if (xp > HI(bbox[0])) { HI(bbox[0]) = xp; } if (yp < LO(bbox[1])) { LO(bbox[1]) = yp; } if (yp > HI(bbox[1])) { HI(bbox[1]) = yp; } } } } fprintf(stderr, "bbox = "); print_2d_cell(stderr, bbox); fprintf(stderr, "\n"); } /* Scale down the projection to total width 1.0: */ double wdproj = HI(bbox[0]) - LO(bbox[0]); start_figure(o, tag, tag, &(bbox[0]), scale/wdproj); /* Plot the hierarchy: */ { interval_t tmpCell[3]; int i; for (i = 0; i < 3; i++) { tmpCell[i] = rootCell[i]; } do_plot(0, 1, tmpCell); } finish_figure(o); } void plot_3d_cell ( PSStream *ps, PlotOptions *o, interval_t cell[], double blow, double vdist ) { double xp[4], yp[4], zp[4]; double ctr[3], p[3]; int i, side; /* Compute center, for blow-up effect: */ for (i = 0; i < 3; i++) { ctr[i] = 0.5*(LO(cell[i]) + HI(cell[i])); } /* Enumerate faces: */ for (side = 0; side <= 1; side++) { /* Inferior faces are invisible: */ if (side != 0) { for (i = 0; i < 3; i++) { int j = (i+1) % 3, k = (i+2) % 3; int t = 0, u, v; for (u = 0; u < 2; u++) { for (v = 0; v < 2; v++) { /* Get vertex coords, in cyclic order: */ p[i] = cell[i].end[side]; p[j] = cell[j].end[u]; p[k] = cell[k].end[u + v - 2*u*v]; /* Apply blow-up effect: */ p[0] = ctr[0] + (p[0] - ctr[0])/blow; p[1] = ctr[1] + (p[1] - ctr[1])/blow; p[2] = ctr[2] + (p[2] - ctr[2])/blow; /* Compute isometric projection: */ persp_project( p[0], p[1], p[2], &(xp[t]), &(yp[t]), &(zp[t]), vdist ); t++; } } double shade = 0.8750 + 0.0625*i; double *rgb = &(o->fill.c[0]); pswr_set_fill_color(ps, shade*rgb[0], shade*rgb[1], shade*rgb[2]); pswr_polygon(ps, xp, yp, 4, TRUE, TRUE); } } } }