====================================================================== /* Debug plot ranges: */ pswr_set_pen(ps, 0.0,0.0,1.0, 0.05, 0.0,0.0); pswr_rectangle ( ps, mag[0]*LO(fr[0]), mag[0]*HI(fr[0]), mag[1]*LO(fr[1]), mag[1]*HI(fr[1]), FALSE, TRUE ); pswr_set_pen(ps, 1.0,0.0,1.0, 0.05, 0.0,0.0); pswr_rectangle ( ps, mag[0]*LO(gr[0]), mag[0]*HI(gr[0]), mag[1]*LO(gr[1]), mag[1]*HI(gr[1]), FALSE, TRUE ); pswr_set_pen(ps, 0.0,1.0,1.0, 1.0, 0.0,0.0); pswr_rectangle ( ps, LO(win[0])+0.01, HI(win[0])-0.01, LO(win[1])+0.01, HI(win[1])-0.01, FALSE, TRUE ); ====================================================================== set_scales ( bbox, o->margin[0]/scale, o->margin[1]/scale, hmin, hmax, vmin, vmax ); ====================================================================== void set_scales ( interval_t bbox[], double xmargin, double ymargin, double hmin, double hmax, double vmin, double vmax ); /* Adjusts the scales of the Postscript plotfile {ps} so that the client rectangle {bbox[0] × bbox[1]}, widened by {xmargin} and {ymargin} on all sides, fits snugly (with equal scales) in the plotting area, which is the rectangle {[hmin _ hmax] × [vmin _ vmax]}, in pt, relative to the lower left corner of the figure. */ void set_scales ( interval_t bbox[], double xmargin, double ymargin, double hmin, double hmax, double vmin, double vmax ) { /* Fit {bbox} in the given plot window, with equal scales for X and Y. */ double xc = (LO(bbox[0]) + HI(bbox[0]))/2; double yc = (LO(bbox[1]) + HI(bbox[1]))/2; double wx = (HI(bbox[0]) - LO(bbox[0]) + 2*xmargin)/2; double wy = (HI(bbox[1]) - LO(bbox[1]) + 2*ymargin)/2; double wh = (hmax - hmin)/2; double wv = (vmax - vmin)/2; double scale = (wx/wh > wy/wv ? wx/wh : wy/wv); double xmin = xc - wh*scale, xmax = xc + wh*scale; double ymin = yc - wv*scale, ymax = yc + wv*scale; pswr_set_window ( ps, xmin, xmax, ymin, ymax, hmin, hmax, vmin, vmax, 1,1 ); } ====================================================================== pswr_get_paper_dimensions(o->paperSize, &hpg, &vpg); hmin = hpg/2 - hsz/2 - hmg; hmax = hpg/2 + hsz/2 + hmg; if (hmin < 36.0) { hmax += 36.0-hmin; hmin = 36.0; } vmin = vpg/2 - vsz/2 - vmg; vmax = vpg/2 + vsz/2 + vmg; if (vmin < 36.0) { vmax += 36.0-vmin; vmin = 36.0; } ====================================================================== void plot_1d_mother_pulse ( PSStream *ps, PlotOptions *o, dg_pulse_kind_t kind, dg_degree_t g, dg_cont_t c, bz_index_t ix, dg_grid_size_t p, double xstep, interval_t xr, double xmag, interval_t yr, double ymag ); /* Draws the graph of the mother spline of the given {kind}, degree {g}, continuity class {c}, and index {ix} (which must be in {0..g-c-1}). Assumes {g >= 2*c+1}, and periodic domain with period {p}. The argument {x} ranges in {xr} with step {xstep}, and the spline value is clipped to {yr}. For plotting, the {x} and {y} values are scaled by {xmag} and {ymag}. */ void plot_1d_mother_pulse ( PSStream *ps, PlotOptions *o, dg_pulse_kind_t kind, dg_degree_t g, dg_cont_t c, bz_index_t ix, dg_grid_size_t p, double xstep, interval_t xr, double xmag, interval_t yr, double ymag ) { double x1 = MAXDOUBLE; /* Previous sample point */ double y1; /* Function value at {x1}. */ auto void plot_sample(double t); void plot_sample(double t) { double x0 = (1-t)*LO(xr) + t*HI(xr); double y0 = dg_pulse_mother(kind, g, c, ix, x0, p); if ( (x1 != MAXDOUBLE) && ((y0 >= LO(yr)) || (y0 <= HI(yr))) && ((y1 >= LO(yr)) || (y1 <= HI(yr))) ) { pswr_segment(ps, xmag*x1, ymag*y1, xmag*x0, ymag*y0); } x1 = x0; y1 = y0; } int N = (int)(1.0/xstep); int Nmin = (int)ceil(LO(xr)*N); int Nmax = (int)floor(HI(xr)*N); double h = 0.0001; int i; for (i = Nmin; i <= Nmax; i++) { double t = ((double)i)/((double)N); if ((i % N) == 0) { plot_sample(t-h); plot_sample(t+h); } else { plot_sample(t); } } fflush(ps->file); } void plot_1d_tent ( PSStream *ps, PlotOptions *o, dg_pulse_kind_t kind, dg_degree_t g, dg_cont_t c, dg_tent_t t, dg_grid_size_t p, double xstep, interval_t xr, double xmag, interval_t yr, double ymag ) { double x1 = MAXDOUBLE; /* Previous sample point */ double y1; /* Function value at {x1}. */ auto void plot_sample(double t); void plot_sample(double t) { double x0 = (1-t)*LO(xr) + t*HI(xr); double y0 = dg_pulse_mother(kind, g, c, ix, x0, p); if ( (x1 != MAXDOUBLE) && ((y0 >= LO(yr)) || (y0 <= HI(yr))) && ((y1 >= LO(yr)) || (y1 <= HI(yr))) ) { pswr_segment(ps, xmag*x1, ymag*y1, xmag*x0, ymag*y0); } x1 = x0; y1 = y0; } int N = (int)(1.0/xstep); int Nmin = (int)ceil(LO(xr)*N); int Nmax = (int)floor(HI(xr)*N); double h = 0.0001; int i; for (i = Nmin; i <= Nmax; i++) { double t = ((double)i)/((double)N); if ((i % N) == 0) { plot_sample(t-h); plot_sample(t+h); } else { plot_sample(t); } } fflush(ps->file); } ====================================================================== void set_scales ( FILE *fps, interval_t bbox[], double xmargin, double ymargin, double hmin, double hmax, double vmin, double vmax ) /* Adjusts the scales of the Postscript plotfile {ps} so that the client rectangle {bbox[0] × bbox[1]}, widened by {xmargin} and {ymargin} on all sides, fits snugly (with equal scales) in the plotting area, which is the rectangle {[hmin _ hmax] × [vmin _ vmax]}, in pt, relative to the lower left corner of the figure. */ { /* Fit {bbox} in the given plot window, with equal scales for X and Y. */ double xc = (LO(bbox[0]) + HI(bbox[0]))/2; double yc = (LO(bbox[1]) + HI(bbox[1]))/2; double wx = (HI(bbox[0]) - LO(bbox[0]) + 2*xmargin)/2; double wy = (HI(bbox[1]) - LO(bbox[1]) + 2*ymargin)/2; double wh = (hmax - hmin)/2; double wv = (vmax - vmin)/2; double scale = (wx/wh > wy/wv ? wx/wh : wy/wv); double xmin = xc - wh*scale, xmax = xc + wh*scale; double ymin = yc - wv*scale, ymax = yc + wv*scale; ps_set_window ( fps, xmin, xmax, ymin, ymax, hmin, hmax, vmin, vmax, 1,1 ); } ====================================================================== /* VALUE RANGES FOR TENTS */ interval_t get_tent_range ( dg_dim_t d, dg_pulse_kind_t pkind[], /* Pulse kinds. */ dg_cont_t c[], /* Continuity classes. */ dg_degree_t g[], /* Degrees. */ dg_tent_t t /* The tent. */ ); /* Computes an approximate range for the values of the tent function {t}, assumed to be of dimension {d}, kind {pkind[i]}, continuity class {c[i]}, and degree {g[i]} along each axis {i=0..d-1}. */ interval_t get_tent_range ( dg_pulse_kind_t pkind[], /* Pulse kinds. */ dg_cont_t c[], /* Continuity classes. */ dg_degree_t g[], /* Degrees. */ dg_tent_t t /* The tent. */ ) { /* Get rank of tent: */ dg_rank_t r = dg_cell_rank(t.cell); /* Get the grid sizes of level {r}: */ dg_grid_size_t sz[d]; /* Period of spline (#intervals). */ /* Get the grid's cell count along each axis: */ dg_grid_size(d, r, sz); /* Get the indices of component pulses: */ dg_pulse_mother_index_t pix[d]; /* Position of tent along each axis. */ dg_tent_pulse_indices(d, c, g, t.tix, pix); /* Get ranges of component pulses and multiply them: */ interval_t fr = (interval_t){{ 1.0, 1.0 }}; /* = 1.0 */ int ax; for (ax = 0; ax < d; ax++) { interval_t ur = get_pulse_range(pkind[ax], c[ax], g[ax], pix[ax], sz[ax]); assert(LO(ur) <= HI(ur)); /* Multiply {ur} into {fr}: */ fr = multiply_ranges(&fr, &ur); } return fr; } ---------------------------------------------------------------------- fprintf ( stderr, " range for %c-pulses = [%7.4f _ %7.4f]\n", dg_pulse_kind_to_char(pkind), LO(frp[1]), HI(frp[1]) ); ====================================================================== Last edited on 2005-02-18 12:41:46 by stolfi