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

📄 graf.c

📁 支持数字元件仿真的SPICE插件
💻 C
📖 第 1 页 / 共 2 页
字号:
voidgr_clean(){    Update();    return;}/* call this routine after viewport size changes */gr_resize(graph)GRAPH *graph;{    double oldxratio, oldyratio;    double scalex, scaley;    struct _keyed *k;    oldxratio = graph->aspectratiox;    oldyratio = graph->aspectratioy;    gr_resize_internal(graph);    /* X also generates an expose after a resize    This is handled in X10 by not redrawing on resizes and waiting for    the expose event to redraw.  In X11, the expose routine tries to    be clever and only redraws the region specified in an expose    event, which does not cover the entire region of the plot if the    resize was from a small window to a larger window.  So in order    to keep the clever X11 expose event handling, we have the X11    resize routine pull out expose events for that window, and we    redraw on resize also.    */#ifndef GI_X    gr_redraw(graph);#endif    /* scale keyed text */    scalex = oldxratio / graph->aspectratiox;    scaley = oldyratio / graph->aspectratioy;    for (k = graph->keyed; k; k = k->next) {      k->x = (k->x - graph->viewportxoff) * scalex + graph->viewportxoff;      k->y = (k->y - graph->viewportyoff) * scaley + graph->viewportyoff;    }}static gr_resize_internal(graph)GRAPH *graph;{    graph->viewport.width = graph->absolute.width -            2 * graph->viewportxoff;    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 */staticiplot(pl)    struct plot *pl;{    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];    int inited = 0;    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) {        /* 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] = - HUGE;        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.*/        (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,            "", "iplot");        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 {        /* 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 = - HUGE;        }        while (dy < currentgraph->datawindow.xmin) {            changed = true;            if (ft_grdb)              fprintf(cp_err, "resize: xlo %G -> %G\n\r",                  currentgraph->datawindow.xmin,                  currentgraph->datawindow.xmin -                    (currentgraph->datawindow.xmax -                    currentgraph->datawindow.xmin)                * XFACTOR);            currentgraph->datawindow.xmin -=              (currentgraph->datawindow.xmax -              currentgraph->datawindow.xmin)              * XFACTOR;            if (currentgraph->datawindow.xmin < start) {                currentgraph->datawindow.xmin = start;                break;            }        }        if (currentgraph->datawindow.xmax <                currentgraph->datawindow.xmin)            currentgraph->datawindow.xmax =                    currentgraph->datawindow.xmin;        while (dy > currentgraph->datawindow.xmax) {            changed = true;            if (ft_grdb)                fprintf(cp_err, "resize: xhi %G -> %G\n\r",                  currentgraph->datawindow.xmax,                  currentgraph->datawindow.xmax +                    (currentgraph->datawindow.xmax -                     currentgraph->datawindow.xmin) * XFACTOR);            currentgraph->datawindow.xmax +=                    (currentgraph->datawindow.xmax -                    currentgraph->datawindow.xmin) *                    XFACTOR;            if (currentgraph->datawindow.xmax > stop) {                currentgraph->datawindow.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->datawindow.ymin) {                changed = true;                if (ft_grdb)                  fprintf(cp_err, "resize: ylo %G -> %G\n\r",                    currentgraph->datawindow.ymin,                    currentgraph->datawindow.ymin -                    (currentgraph->datawindow.ymax -                     currentgraph->datawindow.ymin) * YFACTOR);                currentgraph->datawindow.ymin -=                  (currentgraph->datawindow.ymax -                  currentgraph->datawindow.ymin) * YFACTOR;            }            if (currentgraph->datawindow.ymax <                    currentgraph->datawindow.ymin)                currentgraph->datawindow.ymax =                        currentgraph->datawindow.ymin;            while (dy > currentgraph->datawindow.ymax) {                changed = true;                if (ft_grdb)                  fprintf(cp_err, "resize: yhi %G -> %G\n\r",                    currentgraph->datawindow.ymax,                    currentgraph->datawindow.ymax +                      (currentgraph->datawindow.ymax -                      currentgraph->datawindow.ymin) * YFACTOR);                currentgraph->datawindow.ymax +=                  (currentgraph->datawindow.ymax -                  currentgraph->datawindow.ymin) * YFACTOR;            }        }        if (changed) {            /* Redraw everything. */#ifdef notdef            gr_pmsg("Resizing screen...", false);            DevClear();/*            gr_fixgrid(currentgraph, xdelta, ydelta,                    xtype, ytype);*//*            currentgraph->grid.xdatatype = xtype;            currentgraph->grid.ydatatype = ytype;            currentgraph->grid.xdelta = xdelta;            currentgraph->grid.ydelta = ydelta;*/            gr_resize_internal(currentgraph);            gr_redrawgrid(currentgraph);            /* Now replot everything. */            plotno = 0;            curlst = 1;            curcolor = 1;            for (v = plot_cur->pl_dvecs; v; v = v->v_next)                if (v->v_flags & VF_PLOT)                    ft_graf(v, xs, true);#endif            gr_resize_internal(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)struct plot *plot;struct dbcomm *db;bool unset;{    struct dvec *v;    struct dbcomm *dc;    if (db->db_type == DB_IPLOTALL) {      for (v = plot->pl_dvecs; v; v = v->v_next) {        if (unset)          v->v_flags &= ~VF_PLOT;        else          v->v_flags |= VF_PLOT;      }      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")) {        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 &= ~VF_PLOT;        else          v->v_flags |= VF_PLOT;    }    return;}voidgr_iplot(plot)struct plot *plot;{    struct dbcomm *db;    int dontpop;        /* So we don't pop w/o push. */    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);        dontpop = 0;        if (iplot(plot)) {          /* graph just assigned */          db->db_graphid = currentgraph->graphid;          dontpop = 1;  /* Boy, now I really have to rewrite iplot. */        }        set(plot, db, true);        if (!dontpop && db->db_graphid) PopGraphContext();      }    }}/* *  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;    GRAPH *graph;    struct dveclist *link;    struct dvec *dv;    for (db = dbs; db; db = db->db_next) {      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;}

⌨️ 快捷键说明

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