📄 doplot.c
字号:
if (dd[1] > xlims[1]) xlims[1] = dd[1]; } } else { xlims[0] = HUGE; xlims[1] = - xlims[0]; for (d = vecs; d; d = d->v_link2) { dd = ft_minmax(d->v_scale, true); if (dd[0] < xlims[0]) xlims[0] = dd[0]; if (dd[1] > xlims[1]) xlims[1] = dd[1]; } for (d = vecs; d; d = d->v_link2) { if (d->v_scale->v_flags & VF_MINGIVEN) if (xlims[0] < d->v_scale->v_minsignal) xlims[0] = d->v_scale->v_minsignal; if (d->v_scale->v_flags & VF_MAXGIVEN) if (xlims[1] > d->v_scale->v_maxsignal) xlims[1] = d->v_scale->v_maxsignal; } } /* Do some coercion of the limits to make them reasonable. */ if ((xlims[0] == 0) && (xlims[1] == 0)) { xlims[0] = -1.0; xlims[1] = 1.0; } if ((ylims[0] == 0) && (ylims[1] == 0)) { ylims[0] = -1.0; ylims[1] = 1.0; } if (xlims[0] > xlims[1]) { tt = xlims[1]; xlims[1] = xlims[0]; xlims[0] = tt; } if (ylims[0] > ylims[1]) { tt = ylims[1]; ylims[1] = ylims[0]; ylims[0] = tt; } if (xlims[0] == xlims[1]) { xlims[0] *= (xlims[0] > 0) ? 0.9 : 1.1; xlims[1] *= (xlims[1] > 0) ? 1.1 : 0.9; } if (ylims[0] == ylims[1]) { /* || fabs(ylims[0])/(ylims[1]-ylims[0]) > 1.0e9 || fabs(ylims[1])/(ylims[1]-ylims[0]) > 1.0e9) */ ylims[0] *= (ylims[0] > 0) ? 0.9 : 1.1; ylims[1] *= (ylims[1] > 0) ? 1.1 : 0.9; }#ifdef notdef /* Now shrink the limits very slightly -- this helps prevent round-off * error from doing bad things. */ if (gtype != GRID_LOGLOG && gtype != GRID_XLOG && gtype != GRID_POLAR && gtype != GRID_SMITH) { tt = xlims[1] - xlims[0]; xlims[0] += tt * 0.001; xlims[1] -= tt * 0.001; } if (gtype != GRID_LOGLOG && gtype != GRID_YLOG && gtype != GRID_POLAR && gtype != GRID_SMITH) { tt = ylims[1] - ylims[0]; ylims[0] += tt * 0.001; ylims[1] -= tt * 0.001; }#endif if ((xlims[0] <= 0.0) && ((gtype == GRID_XLOG) || (gtype == GRID_LOGLOG))) { fprintf(cp_err, "Error: X values must be > 0 for log scale\n"); return (false); } if ((ylims[0] <= 0.0) && ((gtype == GRID_YLOG) || (gtype == GRID_LOGLOG))) { fprintf(cp_err, "Error: Y values must be > 0 for log scale\n"); return (false); } /* Fix the plot limits for smith and polar grids. */ if ((!xlim || !ylim) && (gtype == GRID_POLAR)) { /* (0,0) must be in the center of the screen. */ mx = (fabs(xlims[0]) > fabs(xlims[1])) ? fabs(xlims[0]) : fabs(xlims[1]); my = (fabs(ylims[0]) > fabs(ylims[1])) ? fabs(ylims[0]) : fabs(ylims[1]); rad = (mx > my) ? mx : my; /* rad = sqrt(mx * mx + my * my); */ xlims[0] = - rad; xlims[1] = rad; ylims[0] = - rad; ylims[1] = rad; } else if ((!xlim || !ylim) && (gtype == GRID_SMITH || gtype == GRID_SMITHGRID)) {#ifdef notdef /* Let the user zoom in */ mx = (fabs(xlims[0]) > fabs(xlims[1])) ? fabs(xlims[0]) : fabs(xlims[1]); my = (fabs(ylims[0]) > fabs(ylims[1])) ? fabs(ylims[0]) : fabs(ylims[1]); rad = (mx > my) ? mx : my; /* XXX */ xlims[0] = - rad; xlims[1] = rad; ylims[0] = - rad; ylims[1] = rad;#endif xlims[0] = -1.0; xlims[1] = 1.0; ylims[0] = -1.0; ylims[1] = 1.0; } /* We don't want to try to deal with smith plots for asciiplot. */ if (devname && eq(devname, "lpr")) { /* check if we should (can) linearize */ if (!(!ft_curckt || !ft_curckt->ci_ckt || strcmp(ft_curckt->ci_name, plot_cur->pl_title) || !if_tranparams(ft_curckt, &tstart, &tstop, &tstep) || ((tstop - tstart) * tstep <= 0.0) || ((tstop - tstart) < tstep) || !plot_cur || !plot_cur->pl_dvecs || !plot_cur->pl_scale || !isreal(plot_cur->pl_scale) || !ciprefix("tran", plot_cur->pl_typename))) { newlen = (tstop - tstart) / tstep + 1.5; newscale = (double *) tmalloc(newlen * sizeof(double)); newv_scale = alloc(struct dvec); newv_scale->v_flags = vecs->v_scale->v_flags; newv_scale->v_type = vecs->v_scale->v_type; newv_scale->v_gridtype = vecs->v_scale->v_gridtype; newv_scale->v_length = newlen; newv_scale->v_name = copy(vecs->v_scale->v_name); newv_scale->v_realdata = newscale; for (i = 0, ttime = tstart; i < newlen; i++, ttime += tstep) newscale[i] = ttime; for (v = vecs; v; v= v->v_link2) { newdata = (double *) tmalloc(newlen * sizeof (double)); if (!ft_interpolate(v->v_realdata, newdata, v->v_scale->v_realdata, v->v_scale->v_length, newscale, newlen, 1)) { fprintf(cp_err, "Error: can't interpolate %s\n", v->v_name); return(false); } tfree(v->v_realdata); v->v_realdata = newdata; /* Why go to all this trouble if agraf ignores it? */ nointerp = true; } vecs->v_scale = newv_scale; } ft_agraf(xlims, ylims, vecs->v_scale, vecs->v_plot, vecs, xdelta ? *xdelta : 0.0, ydelta ? *ydelta : 0.0, ((gtype == GRID_XLOG) || (gtype == GRID_LOGLOG)), ((gtype == GRID_YLOG) || (gtype == GRID_LOGLOG)), nointerp); return (true); } /* See if there is one type we can give for the y scale... */ for (j = vecs->v_type, d = vecs->v_link2; d; d = d->v_link2) if (d->v_type != j) { j = SV_NOTYPE; break; } if (devname && eq(devname, "xgraph")) { /* Interface to XGraph-11 Plot Program */ ft_xgraph(xlims, ylims, hcopy, title ? title : vecs->v_plot->pl_title, xlabel ? xlabel : ft_typabbrev(vecs->v_scale->v_type), ylabel ? ylabel : ft_typabbrev(j), gtype, ptype, vecs); return (true); } for (d = vecs, i = 0; d; d = d->v_link2) i++; /* Figure out the X name and the X type. This is sort of bad... */ xn = vecs->v_scale->v_name; xt = vecs->v_scale->v_type; pname = plot_cur->pl_typename; if (!gr_init(xlims, ylims, (oneval ? (char *) NULL : xn), title ? title : vecs->v_plot->pl_title, hcopy, i, xdelta ? *xdelta : 0.0, ydelta ? *ydelta : 0.0, gtype, ptype, xlabel, ylabel, xt, j, pname, cline)) return (false); /* Now plot all the graphs. */ for (d = vecs; d; d = d->v_link2) ft_graf(d, oneval ? (struct dvec *) NULL : d->v_scale, false); gr_clean();#ifdef HAS_MFB if (!strcmp(dispdev->name, "MFB")) MFBHalt( );#endif return (true);}/* This routine gets parameters from the command line, which are of the * form "name number ..." It returns a pointer to the parameter values. */static double *getlims(wl, name, number) wordlist *wl; char *name; int number;{ double *d, *td; wordlist *beg, *wk; char *ss; int n; for (beg = wl; beg; beg = beg->wl_next) { if (eq(beg->wl_word, name)) { if (beg == wl) { fprintf(cp_err, "Syntax error: looking for plot parameters \"%s\".\n", name); return (NULL); } wk = beg; if (number) { d = (double *) tmalloc(sizeof (double) * number); for (n = 0; n < number; n++) { wk = wk->wl_next; if (!wk) { fprintf(cp_err, "Syntax error: not enough parameters for \"%s\".\n", name); return (NULL); } ss = wk->wl_word; td = ft_numparse(&ss, false); if (td == NULL) goto bad; d[n] = *td; } } else /* Minor hack... */ d = (double *) 1; if (beg->wl_prev) beg->wl_prev->wl_next = wk->wl_next; if (wk->wl_next) { wk->wl_next->wl_prev = beg->wl_prev; wk->wl_next = NULL; } if (beg != wl_root) wl_free(beg); return (d); } } return (NULL);bad: fprintf(cp_err, "Syntax error: bad parameters for \"%s\".\n", name); return (NULL);}/* Return a parameter of the form "xlabel foo" */static char *getword(wl, name) char *name; wordlist *wl;{ wordlist *beg; char *s; for (beg = wl; beg; beg = beg->wl_next) { if (eq(beg->wl_word, name)) { if ((beg == wl) || !beg->wl_next) { fprintf(cp_err, "Syntax error: looking for plot keyword at \"%s\".\n", name); return (NULL); } s = copy(beg->wl_next->wl_word); beg->wl_prev->wl_next = beg->wl_next->wl_next; if (beg->wl_next->wl_next) beg->wl_next->wl_next->wl_prev = beg->wl_prev; beg->wl_next->wl_next = NULL; wl_free(beg); return (s); } } return (NULL);}/* Check for and remove a one-word keyword. */static boolgetflag(wl, name) wordlist *wl; char *name;{ while (wl) { if (eq(wl->wl_word, name)) { if (wl->wl_prev) wl->wl_prev->wl_next = wl->wl_next; if (wl->wl_next) wl->wl_next->wl_prev = wl->wl_prev; return (true); } wl = wl->wl_next; } return (false);}/* Extend a data vector to length by replicating the * last element, or truncate it if it is too long. */static voidxtend(v, length) struct dvec *v; int length;{ int i; complex c, *oc; double d, *od; if (v->v_length == length) return; if (v->v_length > length) { v->v_length = length; return; } if (isreal(v)) { od = v->v_realdata; v->v_realdata = (double *) tmalloc(length * sizeof (double)); for (i = 0; i < v->v_length; i++) v->v_realdata[i] = od[i]; d = od[--i]; while (i < length) v->v_realdata[i++] = d; tfree(od); } else { oc = v->v_compdata; v->v_compdata = (complex *) tmalloc(length * sizeof (complex)); for (i = 0; i < v->v_length; i++) { realpart(&v->v_compdata[i]) = realpart(&oc[i]); imagpart(&v->v_compdata[i]) = imagpart(&oc[i]); } realpart(&c) = realpart(&oc[--i]); imagpart(&c) = imagpart(&oc[i]); while (i < length) { realpart(&v->v_compdata[i]) = realpart(&c); imagpart(&v->v_compdata[i++]) = imagpart(&c); tfree(oc); } } v->v_length = length; return;}/* Collapse every *xcomp elements into one, and use only the elements * between xind[0] and xind[1]. */static voidcompress(d, xcomp, xind) struct dvec *d; double *xcomp, *xind;{ int cfac, ihi, ilo, newlen, i; int sz = isreal(d) ? sizeof (double) : sizeof (complex); double *dd; complex *cc; if (xind) { ilo = (int) xind[0]; ihi = (int) xind[1]; if ((ilo <= ihi) && (ilo > 0) && (ilo < d->v_length) && (ihi > 1) && (ihi <= d->v_length)) { newlen = ihi - ilo; dd = (double *) tmalloc(newlen * sz); cc = (complex *) dd; if (isreal(d)) { bcopy((char *) (d->v_realdata + ilo), (char *) dd, newlen * sz); tfree(d->v_realdata); d->v_realdata = dd; } else { bcopy((char *) (d->v_compdata + ilo), (char *) cc, newlen * sz); tfree(d->v_compdata); d->v_compdata = cc; } d->v_length = newlen; } } if (xcomp) { cfac = (int) *xcomp; if ((cfac > 1) && (cfac < d->v_length)) { for (i = 0; i * cfac < d->v_length; i++) if (isreal(d)) d->v_realdata[i] = d->v_realdata[i * cfac]; else d->v_compdata[i] = d->v_compdata[i * cfac]; d->v_length = i; } } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -