/* dgplot.h -- enumeration of faces in a dyadic grid. */ /* Last edited on 2004-08-24 00:55:29 by stolfi */ /* The procedures in this module recursivly enumerate selected cell faces of a subtree of the infinite dyadic cell tree, keeping track of the shape of each face or cell (a tensor-style Bezier patch) and the corresponding node(s) in some finite cell tree. */ #ifndef dgplot_H #define dgplot_H #include #include #include #include #include #include /* NODE STARS Let {T} be a finite binary tree resperesnting a finite multigrid {G}. We define the /node star/ of any {m}-dimensional dyadic locus {E} of rank {r} as the list {T(E)} of the enclosing nodes of the {2^{d-m}} cells in level {r} of {G*} which have {E} as a face. Those cells are listed in such an order that cells {T(E)[u]} and {T(E)[v]} are adjacent across a hyperplane {H} orthogonal to axis {Nrm(E)[j]}, with {T(E)[u]} on the low side of {H}, if and only if {u < v} and {u \XOR v = 2^j}. */ typedef void dg_LocusProc ( dg_Dim d, dg_Locus E, dg_Rank r, bz_Patch *b, dg_NodeStar *NE ); /* A client procedure that consumes some locus {E} of rank {r} in some {d}-dimensional finite dyadic grid. Argument {b} is either NULL or a Bézier patch associated with {E}. Domain coordinate {j} of the patch is coordinate {Spn(E)[j]} of {R^d}. Argument {NE} is the node star of {E}. */ void dg_enum_locus_leaves ( dg_Dim d, dg_Locus E, /* Root locus. */ dg_Rank r, /* Rank of {E}. */ bz_Patch *b, /* Shape of {E}, or NULL. */ dg_NodeStar *NE, /* Nodes of adjacent cells. */ dg_Rank rMax, /* Truncate the recursion just below this rank. */ dg_LocusProc visit /* Client face-processing procedure. */ ); /* Recursively enumerate every leaf locus {E'} descendent from {E}, of rank {r}, calling {visit} on each. Argument {NE} should be a node star for {E}. A locus is considered to be a leaf if it has rank {rMax}, or if none of nodes {NE[j]} has any children. Argument {b} describes the geometry of {E}, as in a {dg_LocusProc}. The leaf locus that lies in the common boundary of two loci {E'0,E'1} contained in {E} is visited only after visiting {E'0} and {E'1}. */ void dg_enum_cell_leaves ( dg_Dim d, dg_CellIndex k, bz_Patch *b, dg_NodeRef_vec_t *nf, /* Nodes of adjacent cells. */ dg_Rank rMax, /* Never split below this rank. */ dg_LocusProc visit /* Client face-processing procedure. */ ); /* Recursively enumerate every leaf locus contained in the closure of cell {k}, calling {visit} on each one (see {dg_enum_leaf_loci}). Argument {b} describes the geometry of {E}, as in a {dg_LocusProc}. Nodes {nf[0..3^d-1]} should be the enclosing nodes of the cells that are neighbors of cell {k}; specifically, {nf[fi]} should be the neighbor opposite to face {fi}. */ /* POSTSCRIPT PLOTTING OF 2D MULTIGRID ITEMS In these procedures, the first two coordinates of each given point are interpreted as {X} and {Y} coordinates for plotting. The remaining components are interpreted as function values. */ void dg_plot_2D_vertex(PSStream *ps, double *c, bz_RDim n); /* Plots a vertex of a 2D finite multigrid {G}, as a small dot. The vertex has coordinates {c[0],c[1]}. Coordinates {c[2..n-1]} are ignored. */ void dg_plot_2D_edge(PSStream *ps, double c0[], double c1[], bz_RDim n); /* Draws an edge of a 2D finite multigrid {G}. The edge is the straight line segment connecting {(c0[0],c0[1])} to {(c1[0],c1[1])}. Coordinates {c0[2..n-1]} and {c1[2..n-1]} are ignored. */ void dg_plot_2D_face ( PSStream *ps, double c00[], /* Coords and values at domain corner {(0,0)}. */ double c01[], /* Coords and values at domain corner {(0,1)}. */ double c10[], /* Coords and values at domain corner {(1,0)}. */ double c11[], /* Coords and values at domain corner {(1,1)}. */ bz_RDim n, /* Dim of point vectors (incl. function values). */ int plotDepth, /* Subdivision depth for plotting. */ double fStart, /* Synchronize isolines with this level. */ double fStep, /* Isoline spacing. */ int kMin, /* Minimum isoline index. */ int kMax, /* Maximum isoline index. */ double *R, double *G, double *B ); /* Paints a face of a 2D finite multigrid {G}. The face is the bilinear patch with the given corners. It is plotted by breaking it into {4^plotDepth} sub-patches, then breaking each sub-patch into 4 triangles. */ /* LOW-LEVEL PLOTTING */ void dg_shade_quadrilateral ( PSStream *ps, double p00[], /* Coords and values at corner [0,0]. */ double p01[], /* Coords and values at corner [0,1]. */ double p10[], /* Coords and values at corner [1,0]. */ double p11[], /* Coords and values at corner [1,1]. */ bz_RDim n, /* Dimension of range space. */ double fMin, /* Minimum function value. */ double fMax /* Maximum function value. */ ); /* Paints values of a function as color shades in a quadrilateral {Q} with given corners, by breaking it into 4 triangles with common vertex at the quadrilateral's barycenter {b}. Affine interpolation is used inside each triangle. The corners should be given in row-by-row order (NOT ccw order). The function values at corners are {{p00,p01,p10,p11}[2..n-1]}. The function value at {b} is assumed to be the average of the corner values. */ void dg_shade_triangle ( PSStream *ps, double a[], /* First vertex. */ double b[], /* Second vertex. */ double c[], /* Third vertex. */ bz_RDim n, /* Dimension of range space. */ double fMin, /* Minimum function value. */ double fMax /* Maximum function value. */ ); /* Paints values of a function as color bands in a triangle {T} with given corners. The function values at corners are {{a,b,c}[2..n-1]}. Affine interpolation is used inside the triangle. */ void dg_bands_in_quadrilateral ( PSStream *ps, double p00[], /* Coords and values at domain corner {(0,0)}. */ double p01[], /* Coords and values at domain corner {(0,1)}. */ double p10[], /* Coords and values at domain corner {(1,0)}. */ double p11[], /* Coords and values at domain corner {(1,1)}. */ bz_RDim n, /* Dim of point vectors (incl. function values). */ double fStart, /* Synchronize isolines with this level. */ double fStep, /* Isoline spacing. */ int kMin, /* Minimum isoline index. */ int kMax, /* Maximum isoline index. */ double *R, double *G, double *B ); /* Paints values of a function as color bands in a quadrilateral {Q} with given corners, by breaking it into 4 triangles with common vertex at the quadrilateral's barycenter {b}. Affine interpolation is used inside each triangle. Uses the color scale {R,G,B}. The corners should be given in row-by-row order (NOT ccw order). The function values at corners are {{p00,p01,p10,p11}[2..n-1]}. The function value at {b} is assumed to be the average of the corner values. */ void dg_isolines_in_quadrilateral ( PSStream *ps, double p00[], /* Coords and values at corner [0,0]. */ double p01[], /* Coords and values at corner [0,1]. */ double p10[], /* Coords and values at corner [1,0]. */ double p11[], /* Coords and values at corner [1,1]. */ bz_RDim n, /* Dimension of range space. */ double fStart, /* Synchronize isolines with this level. */ double fStep, /* Isoline spacing. */ int kMin, /* Minimum isoline index. */ int kMax /* Maximum isoline index. */ ); /* Draws isolines of a function in a quadrilateral {Q} with given corners, by breaking it into 4 triangles with common vertex at the quadrilateral's barycenter {b}. Affine interpolation is used inside each triangle. The corners should be given in row-by-row order (NOT ccw order). The function values at corners are {{p00,p01,p10,p11}[2..n-1]}. The function value at {b} is assumed to be the average of the corner values. */ #endif