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

📄 graf.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
{    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 */voidgr_redraw(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();}voidgr_restoretext(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. There are 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. * * FIXME: 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 ?? */static intiplot(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) {	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;            }	/* 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");            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(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(char *buf, double num){    char *p;    int k;    sprintf(buf, "    % .5g", num);    p =strchr(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;void reset_trace(void){	hit = -1;	hit2 = -1;}voidgr_iplot(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 {			    			    /* MW. Complex data here, realdata is NULL 			    		(why someone use realdata here again) */			    printf("%s",				getitright(buf, u->v_compdata[len - 1].cx_real));				printf(", %s",				    getitright(buf, u->v_compdata[len - 1].cx_imag));			}			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 {							/* MW. Complex data again */		    printf("%s", getitright(buf, v->v_compdata[len - 1].cx_real));		    printf(", %s", getitright(buf, v->v_compdata[len - 1].cx_imag));		}		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(void){    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);        }      }    }    return;}double *readtics(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 + -