⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graf.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
static gr_resize_internal(graph)GRAPH *graph;{    if (!graph->grid.xsized)	    graph->viewport.width = graph->absolute.width -		    1.4 * graph->viewportxoff;    if (!graph->grid.ysized)	    graph->viewport.height = graph->absolute.height -		    2 * graph->viewportyoff;        gr_fixgrid(graph, graph->grid.xdelta, graph->grid.ydelta,            graph->grid.xdatatype, graph->grid.ydatatype);    /* cache width and height info to make DatatoScreen go fast */    /* note: XXX see if this is actually used anywhere */    graph->datawindow.width = graph->datawindow.xmax -                    graph->datawindow.xmin;    graph->datawindow.height = graph->datawindow.ymax -                    graph->datawindow.ymin;    /* cache (datawindow size) / (viewport size) */    graph->aspectratiox = graph->datawindow.width / graph->viewport.width;    graph->aspectratioy = graph->datawindow.height / graph->viewport.height;}/* redraw everything in struct graph */gr_redraw(graph)GRAPH *graph;{    struct dveclist *link;    /* establish current graph so default graphic calls will work right */    PushGraphContext(graph);    DevClear();    /* redraw grid */    gr_redrawgrid(graph);    for (link=graph->plotdata, plotno = 0; link;            link = link->next, plotno++) {      /* redraw legend */      drawlegend(graph, plotno, link->vector);      /* replot data        if onevalue, pass it a NULL scale        otherwise, if vec has its own scale, pass that            else pass vec's plot's scale      */      ft_graf(link->vector,          graph->onevalue ? (struct dvec *) NULL :                    (link->vector->v_scale ?                    link->vector->v_scale :                    link->vector->v_plot->pl_scale),          true);    }    gr_restoretext(graph);    PopGraphContext();}gr_restoretext(graph)GRAPH *graph;{    struct _keyed *k;    /* restore text */    for (k=graph->keyed; k; k = k->next) {      SetColor(k->colorindex);      Text(k->text, k->x, k->y);    }}/* Do some incremental plotting. 3 cases -- first, if length < IPOINTMIN, don't * do anything. Second, if length = IPOINTMIN, plot what we have so far. Third, * if length > IPOINTMIN, plot the last points and resize if needed. * Note we don't check for pole / zero because they are of length 1. *//* note: there is a problem with multiple iplots that use the same vector,    namely, that vector has the same color throughout.  This is another    reason why we need to pull color and linestyle out of dvec XXX    Or maybe even something more drastic ?? */extern bool resumption;staticiplot(pl, id)    struct plot *pl;    int id;{    int len = pl->pl_scale->v_length;    struct dvec *v, *xs = pl->pl_scale;    double *lims, dy;    double start, stop, step;    register int j;    bool changed = false;    int yt;    char *yl = NULL;    double xlims[2], ylims[2];    static REQUEST reqst = { checkup_option, 0 };    int inited = 0;    char commandline[513];    for (j = 0, v = pl->pl_dvecs; v; v = v->v_next)        if (v->v_flags & VF_PLOT)            j++;    if (!j)        return(0);    if (ft_grdb)        fprintf(cp_err, "Entering iplot, len = %d\n\r", len);    if (len < IPOINTMIN) {        /* Nothing yet */        return(0);    } else if (len == IPOINTMIN || !id	    /* || (len > IPOINTMIN && resumption) */) {	resumption = false;        /* Draw the grid for the first time, and plot everything. */        lims = ft_minmax(xs, true);        xlims[0] = lims[0];        xlims[1] = lims[1];        ylims[0] = HUGE;        ylims[1] = - ylims[0];        for (v = pl->pl_dvecs; v; v = v->v_next)            if (v->v_flags & VF_PLOT) {                lims = ft_minmax(v, true);                if (lims[0] < ylims[0])                  ylims[0] = lims[0];                if (lims[1] > ylims[1])                  ylims[1] = lims[1];                if (!yl)                  yl = v->v_name;            }        if (ft_grdb)            fprintf(cp_err,               "iplot: after 5, xlims = %G, %G, ylims = %G, %G\n\r",               xlims[0],              xlims[1],              ylims[0],              ylims[1]);        for (yt = pl->pl_dvecs->v_type, v = pl->pl_dvecs->v_next; v;                v = v->v_next)            if ((v->v_flags & VF_PLOT) && (v->v_type != yt)) {                yt = 0;                break;            }/*        (void) gr_init((double *) NULL, (double *) NULL, xs->v_name,             pl->pl_title, (char *) NULL, j, xdelta, ydelta,            GRID_LIN, plottype, xs->v_name, yl, xs->v_type, yt,            commandline, plotname);*//* note: have command options for iplot to specify xdelta, etc.    So don't need static variables hack.    Assume default values for now.*/	sprintf(commandline, "iplot %s", xs->v_name);        (void) gr_init(xlims, ylims, xs->v_name,            pl->pl_title, (char *) NULL, j, 0.0, 0.0,            GRID_LIN, PLOT_LIN, xs->v_name, yl, xs->v_type, yt,            plot_cur->pl_typename, commandline);        for (v = pl->pl_dvecs; v; v = v->v_next)            if (v->v_flags & VF_PLOT) {              gr_start_internal(v, false);              ft_graf(v, xs, true);            }        inited = 1;    } else {	Input(&reqst, 0);        /* First see if we have to make the screen bigger */        dy = (isreal(xs) ? xs->v_realdata[len - 1] :                realpart(&xs->v_compdata[len - 1]));        if (ft_grdb)            fprintf(cp_err, "x = %G\n\r", dy);        if (!if_tranparams(ft_curckt, &start, &stop, &step) ||                !ciprefix("tran", pl->pl_typename)) {            stop = HUGE;            start = - stop;        }        while (dy < currentgraph->data.xmin) {            changed = true;            if (ft_grdb)              fprintf(cp_err, "resize: xlo %G -> %G\n\r",                  currentgraph->data.xmin,                  currentgraph->data.xmin -                    (currentgraph->data.xmax -                    currentgraph->data.xmin)                * XFACTOR);            currentgraph->data.xmin -=              (currentgraph->data.xmax -              currentgraph->data.xmin)              * XFACTOR;            if (currentgraph->data.xmin < start) {                currentgraph->data.xmin = start;                break;            }        }        if (currentgraph->data.xmax <                currentgraph->data.xmin)            currentgraph->data.xmax =                    currentgraph->data.xmin;        while (dy > currentgraph->data.xmax) {            changed = true;            if (ft_grdb)                fprintf(cp_err, "resize: xhi %G -> %G\n\r",                  currentgraph->data.xmax,                  currentgraph->data.xmax +                    (currentgraph->data.xmax -                     currentgraph->data.xmin) * XFACTOR);            currentgraph->data.xmax +=                    (currentgraph->data.xmax -                    currentgraph->data.xmin) *                    XFACTOR;            if (currentgraph->data.xmax > stop) {                currentgraph->data.xmax = stop;                break;            }        }        for (v = pl->pl_dvecs; v; v = v->v_next) {            if (!(v->v_flags & VF_PLOT))                continue;            dy = (isreal(v) ? v->v_realdata[len - 1] :                    realpart(&v->v_compdata[len - 1]));            if (ft_grdb)                fprintf(cp_err, "y = %G\n\r", dy);            while (dy < currentgraph->data.ymin) {                changed = true;                if (ft_grdb)                  fprintf(cp_err, "resize: ylo %G -> %G\n\r",                    currentgraph->data.ymin,                    currentgraph->data.ymin -                    (currentgraph->data.ymax -                     currentgraph->data.ymin) * YFACTOR);                currentgraph->data.ymin -=                  (currentgraph->data.ymax -                  currentgraph->data.ymin) * YFACTOR;            }            if (currentgraph->data.ymax <                    currentgraph->data.ymin)                currentgraph->data.ymax =                        currentgraph->data.ymin;            while (dy > currentgraph->data.ymax) {                changed = true;                if (ft_grdb)                  fprintf(cp_err, "resize: yhi %G -> %G\n\r",                    currentgraph->data.ymax,                    currentgraph->data.ymax +                      (currentgraph->data.ymax -                      currentgraph->data.ymin) * YFACTOR);                currentgraph->data.ymax +=                  (currentgraph->data.ymax -                  currentgraph->data.ymin) * YFACTOR;            }        }        if (changed) {            /* Redraw everything. */            gr_pmsg("Resizing screen", false);            gr_resize(currentgraph);            gr_redraw(currentgraph);        } else {            /* Just connect the last two points. This won't             * be done with curve interpolation, so it might             * look funny.             */            for (v = pl->pl_dvecs; v; v = v->v_next)                if (v->v_flags & VF_PLOT) {                    gr_point(v,                     (isreal(xs) ? xs->v_realdata[len - 1] :                    realpart(&xs->v_compdata[len - 1])),                    (isreal(v) ? v->v_realdata[len - 1] :                    realpart(&v->v_compdata[len - 1])),                    (isreal(xs) ? xs->v_realdata[len - 2] :                    realpart(&xs->v_compdata[len - 2])),                    (isreal(v) ? v->v_realdata[len - 2] :                    realpart(&v->v_compdata[len - 2])),                    len - 1);                }        }    }    Update();    return(inited);}static voidset(plot, db, unset, mode)struct plot *plot;struct dbcomm *db;bool unset;int mode;{    struct dvec *v;    struct dbcomm *dc;    if (db->db_type == DB_IPLOTALL || db->db_type == DB_TRACEALL) {      for (v = plot->pl_dvecs; v; v = v->v_next) {        if (unset)          v->v_flags &= ~mode;        else          v->v_flags |= mode;      }      return;    }    for (dc = db; dc; dc = dc->db_also) {       v = vec_fromplot(dc->db_nodename1, plot);        if (!v || v->v_plot != plot) {          if (!eq(dc->db_nodename1, "0") && !unset) {              fprintf(cp_err, "Warning: node %s non-existent in %s.\n",                  dc->db_nodename1, plot->pl_name);        /* note: XXX remove it from dbs, so won't get further errors */          }          continue;        }        if (unset)          v->v_flags &= ~mode;        else          v->v_flags |= mode;    }    return;}static char *getitright(buf, num)    char *buf;    double num;{    char *p;    int k;    sprintf(buf, "    % .5g", num);    p = index(buf, '.');    if (p) {	return p - 4;    } else {	k = strlen(buf);	if (k > 8)	    return buf + 4;	else /* k >= 4 */	    return buf + k - 4;    }}static int hit, hit2;reset_trace( ){	hit = -1;	hit2 = -1;}voidgr_iplot(plot)struct plot *plot;{    struct dbcomm *db;    int dontpop;        /* So we don't pop w/o push. */    char buf[30];    hit = 0;    for (db = dbs; db; db = db->db_next) {      if (db->db_type == DB_IPLOT || db->db_type == DB_IPLOTALL) {        if (db->db_graphid) PushGraphContext(FindGraph(db->db_graphid));        set(plot, db, false, VF_PLOT);        dontpop = 0;        if (iplot(plot, db->db_graphid)) {          /* graph just assigned */          db->db_graphid = currentgraph->graphid;          dontpop = 1;        }        set(plot, db, true, VF_PLOT);        if (!dontpop && db->db_graphid) PopGraphContext();      } else if (db->db_type == DB_TRACENODE || db->db_type == DB_TRACEALL) {	struct dvec *v, *u;	int len;        set(plot, db, false, VF_PRINT);	len = plot->pl_scale->v_length;	dontpop = 0;	for (v = plot->pl_dvecs; v; v = v->v_next) {	    if (v->v_flags & VF_PRINT) {		u = plot->pl_scale;		if (len <= 1 || hit <= 0 || hit2 < 0) {		    if (len <= 1 || hit2 < 0)			term_clear( );		    else			term_home( );		    hit = 1;		    hit2 = 1;		    printf(		     "\tExecution trace (remove with the \"delete\" command)");		    term_cleol( );		    printf("\n");		    if (u) {			printf("%12s:", u->v_name);			if (isreal(u)) {			    printf("%s",				getitright(buf, u->v_realdata[len - 1]));			} else {			    printf("%s",				getitright(buf, u->v_realdata[len - 1]));				printf(", %s",				    getitright(buf, u->v_realdata[len - 1]));			}			term_cleol( );			printf("\n");		    }		}		if (v == u)		    continue;		printf("%12s:", v->v_name);		if (isreal(v)) {		    printf("%s", getitright(buf, v->v_realdata[len - 1]));		} else {		    printf("%s", getitright(buf, v->v_realdata[len - 1]));		    printf(", %s", getitright(buf, v->v_realdata[len - 1]));		}		term_cleol( );		printf("\n");	    }	}        set(plot, db, true, VF_PRINT);      }    }}/* *  This gets called after iplotting is done.  We clear out the db_graphid *  fields.  Copy the dvecs, which we referenced by reference, so *  DestroyGraph gets to free its own copy.  Note:  This is a clear *  case for separating the linestyle and color fields from dvec. */voidgr_end_iplot(){    struct dbcomm *db, *prev, *next;    GRAPH *graph;    struct dveclist *link;    struct dvec *dv;    prev = NULL;    for (db = dbs; db; prev = db, db = next) {      next = db->db_next;      if (db->db_type == DB_DEADIPLOT) {	    if (db->db_graphid) {		DestroyGraph(db->db_graphid);		if (prev)		    prev->db_next = next;		else		    dbs = next;		dbfree(db);	    }      } else if (db->db_type == DB_IPLOT || db->db_type == DB_IPLOTALL) {        if (db->db_graphid) {          /* get private copy of dvecs */          graph = FindGraph(db->db_graphid);          link = graph->plotdata;          while (link) {            dv = link->vector;            link->vector = vec_copy(dv);            /* vec_copy doesn't set v_color or v_linestyle */            link->vector->v_color = dv->v_color;            link->vector->v_linestyle = dv->v_linestyle;            link->vector->v_flags |= VF_PERMANENT;	    link = link->next;          }          db->db_graphid = 0;        } else {          /* warn that this wasn't plotted */          fprintf(cp_err, "Warning: iplot %d was not executed.\n",		  db->db_number);        }      }    }#ifdef HAS_MFB   if (!strcmp( dispdev->name, "MFB" ))      MFBHalt();#endif    return;}double *readtics(string)char *string;{        int i, k;        char *words, *worde;        double *tics, *ticsk;        tics = (double *) tmalloc(MAXTICS * sizeof(double));        ticsk = tics;        words = string;        for (i = k = 0; *words && k < MAXTICS; words = worde) {	    while (isspace(*words))	       words++;	    worde = words;	    while (isalpha(*worde) || isdigit(*worde))	       worde++;	    if (*worde)		*worde++ = '\0';	    sscanf(words, "%lf", ticsk++);	    k++;        }        *ticsk = HUGE;        return(tics);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -