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

📄 agraf.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group**********//* * Line-printer (ASCII) plots. */#include "spice.h"#include "cpdefs.h"#include "ftedefs.h"#include "ftedata.h"#include "fteparse.h"#include "suffix.h"#define FUDGE		7#define MARGIN_BASE	11#define LCHAR		'.'#define MCHAR		'X'#define PCHARS		"+*=$%!0123456789"/* We should really deal with the xlog and delta arguments.  This routine is * full of magic numbers that make the formatting correct. *//* ARGSUSED */voidft_agraf(xlims, ylims, xscale, plot, vecs, xdel, ydel, xlog, ylog, nointerp)    double *xlims, *ylims;    struct dvec *xscale, *vecs;    struct plot *plot;    double xdel, ydel;    bool xlog, ylog, nointerp;{    int height;    bool nobreakp, novalue;    int maxx, maxy, omaxy;  /* The size of the plotting area. */    bool /* xlogscale = false, */ ylogscale = false;    char *field, buf[BSIZE_SP];    char *line1, *line2, c, cb;    double xrange[2], yrange[2], x1, x2, yy1, y2, x, y;    int mag, hmt, lmt, dst, spacing, nsp, ypt, upper, lower, curline;    double tenpowmag, diff, *values;    struct dvec *v;    int margin = MARGIN_BASE;    int omargin;    register int i, j, k;    int shift;    /* ANSI C does not specify how many digits are in an exponent for %c     * We assumed it was 2.  If it's more, shift starting position over.     */    (void) sprintf(buf, "%1.1e", 0.0);		/* expect 0.0e+00 */    shift = strlen(buf) - 7;    margin += shift;    /* Make sure the margin is correct */    omargin = margin;    if (!cp_getvar("noasciiplotvalue", VT_BOOL, (char *) &novalue) &&            !vec_eq(xscale, vecs)) {        margin *= 2;    } else        novalue = true;    if ((xscale->v_gridtype == GRID_YLOG) ||            (xscale->v_gridtype == GRID_LOGLOG))        ylogscale = true;    if (!cp_getvar("width", VT_NUM, (char *) &maxy)) {      maxy = DEF_WIDTH;    }    if (!cp_getvar("height", VT_NUM, (char *) &height))        height = DEF_HEIGHT;    if (ft_nopage)	nobreakp = true;    else   	cp_getvar("nobreak", VT_BOOL, (char *) &nobreakp);    maxy -= (margin + FUDGE);    maxx = xscale->v_length;    xrange[0] = xlims[0];    xrange[1] = xlims[1];    yrange[0] = ylims[0];    yrange[1] = ylims[1];    if (maxx < 2) {        fprintf(cp_err,             "Error: asciiplot can't handle scale with length < 2\n");        return;    }    if (maxx <= 0) {        fprintf(cp_err, "Note: no points to plot\n");        return;    }    for (v = vecs, i = 0; v; v = v->v_link2) {        v->v_linestyle = (PCHARS[i] ? PCHARS[i++] : '#');    }    /* Now allocate the field and stuff. */    field = tmalloc((maxy + 1) * (maxx + 1));    line1 = tmalloc(maxy + margin + FUDGE + 1);    line2 = tmalloc(maxy + margin + FUDGE + 1);    if (!novalue)        values = (double *) tmalloc(maxx * sizeof (double));        /* Clear the field, put the lines in the right places, and create     * the headers.     */    for (i = 0, j = (maxx + 1) * (maxy + 1); i < j; i++)        field[i] = ' ';    for (i = 0, j = maxy + margin + FUDGE; i < j; i++) {        line1[i] = '-';        line2[i] = ' ';    }    line1[j] = line2[j] = '\0';    /* The following is similar to the stuff in grid.c */    if ((xrange[0] > xrange[1]) || (yrange[0] > yrange[1])) {        fprintf(cp_err,     "ft_agraf: Internal Error: bad limits %lg, %lg, %lg, %lg\n",                xrange[0], xrange[1], yrange[0], yrange[1]);        return;    }    /* gcc doesn't like !double */    if (ylims[1] == 0.0) {        mag = (int) floor(mylog10(- ylims[0]));        tenpowmag = pow(10.0, (double) mag);    } else if (ylims[0] == 0.0) {         mag = (int) floor(mylog10(ylims[1]));        tenpowmag = pow(10.0, (double) mag);    } else {        diff = ylims[1] - ylims[0];        mag = (int) floor(mylog10(diff));        tenpowmag = pow(10.0, (double) mag);    }    lmt = (int) floor(ylims[0] / tenpowmag);    yrange[0] = ylims[0] = lmt * tenpowmag;    hmt = (int) ceil(ylims[1] / tenpowmag);    yrange[1] = ylims[1] = hmt * tenpowmag;    dst = hmt - lmt;    /* This is a strange case; I don't know why it's here. */    if (dst == 11)        dst = 12;    else if (dst == 1) {        dst = 10;        mag++;        hmt *= 10.0;        lmt *= 10.0;    } else if (dst == 0) {        dst = 2;	lmt -= 1;	hmt += 1;    }    for (nsp = 4; nsp < 8; nsp++)        if (!(dst % nsp))            break;    if (nsp == 8)        for (nsp = 2; nsp < 4; nsp++)            if (!(dst % nsp))                break;    spacing = maxy / nsp;    /* Reset the max X coordinate to deal with round-off error. */    omaxy = maxy + 1;    maxy = spacing * nsp;    for (i = 0, j = lmt; j <= hmt; i += spacing, j += dst / nsp) {        for (k = 0; k < maxx; k++)            field[k * omaxy + i] = LCHAR;        line1[i + margin + 2 * shift] = '|';        (void) sprintf(buf, "%.2e", j * pow(10.0, (double) mag));        bcopy(buf, &line2[i + margin - ((j < 0) ? 2 : 1) - shift],                strlen(buf));    }    line1[i - spacing + margin + 1] = '\0';    for (i = 1; i < omargin - 1 && xscale->v_name[i - 1]; i++)        line2[i] = xscale->v_name[i - 1];    if (!novalue)        for (i = omargin + 1;		i < margin - 2 && (vecs->v_name[i - omargin - 1]);		i++)            line2[i] = vecs->v_name[i - omargin - 1];    /* Now the buffers are all set up properly. Plot points for each     * vector using interpolation. For each point on the x-axis, find the     * two bracketing points in xscale, and then interpolate their     * y values for each vector.     */    upper = lower = 0;    for (i = 0; i < maxx; i++) {        if (nointerp)            x = isreal(xscale) ? xscale->v_realdata[i] :                    realpart(&xscale->v_compdata[i]);        else if (xlog && xrange[0] > 0.0 && xrange[1] > 0.0)	    x = xrange[0] * pow( 10.0, mylog10(xrange[1]/xrange[0])			* i / (maxx - 1));        else            x = xrange[0] + (xrange[1] - xrange[0]) * i /                    (maxx - 1);        while ((isreal(xscale) ? (xscale->v_realdata[upper] < x) :                (realpart(&xscale->v_compdata[upper]) < x)) &&                (upper < xscale->v_length - 1))            upper++;        while ((isreal(xscale) ? (xscale->v_realdata[lower] < x) :                (realpart(&xscale->v_compdata[lower]) < x)) &&                (lower < xscale->v_length - 1))            lower++;        if ((isreal(xscale) ? (xscale->v_realdata[lower] > x) :                (realpart(&xscale->v_compdata[lower]) > x)) &&                (lower > 0))            lower--;        x1 = (isreal(xscale) ? xscale->v_realdata[lower] :                realpart(&xscale->v_compdata[lower]));        x2 = (isreal(xscale) ? xscale->v_realdata[upper] :                realpart(&xscale->v_compdata[upper]));        if (x1 > x2) {            fprintf(cp_err, "Error: X scale (%s) not monotonic\n",                    xscale->v_name);            return;        }        for (v = vecs; v; v = v->v_link2) {            yy1 = (isreal(v) ? v->v_realdata[lower] :                    realpart(&v->v_compdata[lower]));            y2 = (isreal(v) ? v->v_realdata[upper] :                    realpart(&v->v_compdata[upper]));            if (x1 == x2)                y = yy1;            else                y = yy1 + (y2 - yy1) * (x - x1) / (x2 - x1);            if (!novalue && (v == vecs))                values[i] = y;            ypt = ft_findpoint(y, yrange, maxy, 0, ylogscale);            c = field[omaxy * i + ypt];            if ((c == ' ') || (c == LCHAR))                field[omaxy * i + ypt] = (char) v->v_linestyle;            else                field[omaxy * i + ypt] = MCHAR;        }    }        out_init();    for (i = 0; i < omaxy + margin; i++)        out_send("-");    out_send("\n");    i = (omaxy + margin - strlen(plot->pl_title)) / 2;    while (i-- > 0)        out_send(" ");    (void) strcpy(buf, plot->pl_title);    buf[maxy + margin] = '\0';  /* Cut off if too wide */    out_send(buf);    out_send("\n");    (void) sprintf(buf, "%s %s", plot->pl_name, plot->pl_date);    buf[maxy + margin] = '\0';    i = (omaxy + margin - strlen(buf)) / 2;    while (i-- > 0)        out_send(" ");    out_send(buf);    out_send("\n\n");    curline = 7;    out_send("Legend:  ");    i = 0;    j = (maxx + margin - 8) / 20;    if (j == 0)        j = 1;    for (v = vecs; v; v = v->v_link2) {	out_pbuf[0] = (char) v->v_linestyle;	out_pbuf[1] = '\0';/*        out_printf("%c = %-17s", (char) v->v_linestyle, v->v_name); */        out_printf("%s = %-17s", out_pbuf, v->v_name);        if (!(++i % j) && v->v_link2) {            out_send("\n         ");            curline++;        }    }    out_send("\n");    for (i = 0; i < omaxy + margin; i++)        out_send("-");    out_send("\n");    i = 0;    out_printf("%s\n%s\n", line2, line1);    curline += 2;    for (i = 0; i < maxx; i++) {        if (nointerp)          x = isreal(xscale) ? xscale->v_realdata[i] :                realpart(&xscale->v_compdata[i]);        else if (xlog && xrange[0] > 0.0 && xrange[1] > 0.0)	    x = xrange[0] * pow( 10.0, mylog10(xrange[1]/xrange[0])			* i / (maxx - 1));	else          x = xrange[0] + (xrange[1] - xrange[0]) * i / (maxx - 1);        if (x < 0.0) {	    sprintf(out_pbuf, "%.3e ", x);	    out_send(out_pbuf);/*             out_printf("%.3e ", x); */        } else {	    sprintf(out_pbuf, " %.3e ", x);	    out_send(out_pbuf);/*            out_printf(" %.3e ", x); */	}        if (!novalue) {            if (values[i] < 0.0) {	        sprintf(out_pbuf, "%.3e ", values[i]);	        out_send(out_pbuf);/*                out_printf("%.3e ", values[i]); */            } else {	        sprintf(out_pbuf, " %.3e ", values[i]);	        out_send(out_pbuf);/*                out_printf(" %.3e ", values[i]); */	    }        }        cb = field[(i + 1) * omaxy];        field[(i + 1) * omaxy] = '\0';        out_send(&field[i * omaxy]);        field[(i + 1) * omaxy] = cb;        out_send("\n");        if (((curline++ % height) == 0) && (i < maxx - 1) &&                 !nobreakp) {            out_printf("%s\n%s\n\014\n%s\n%s\n", line1, line2,                line2, line1);            curline += 5;        }    }    out_printf("%s\n%s\n", line1, line2);    tfree(field);    tfree(line1);    tfree(line2);    if (!novalue)        tfree(values);    return;}

⌨️ 快捷键说明

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