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

📄 grid.c

📁 支持数字元件仿真的SPICE插件
💻 C
📖 第 1 页 / 共 3 页
字号:
/*     Routines to draw the various sorts of grids -- linear, log, polar.        (no smiths)*/#include "prefix.h"#include "FTEgraph.h"#include "CPdefs.h"#include "FTEdefs.h"#include "FTEdata.h"#include "FTEparse.h"/* gtri - delete - wbk - 10/8/90 - duplicates include in CPdefs.h:CPstd.h *//* #include <math.h> */          /* for modf() *//* gtri - end - wbk - 10/8/90 */#include "suffix.h"#define PI 3.1415926535897932384static double *lingrid(), *loggrid();static void polargrid(), smithgrid();#ifdef notdefstatic void arcset(), cliparc();static void adddeglabel(), addradlabel();#endiftypedef enum { x_axis, y_axis } Axis;/* note: scaleunits is static and never changed in this file    ie, can get rid of it */static bool scaleunits = true;voidgr_fixgrid(graph, xdelta, ydelta, xtype, ytype)    GRAPH *graph;    double xdelta, ydelta;    int xtype, ytype;{    double *dd;    if (graph->grid.gridtype == GRID_NONE) {        graph->grid.gridtype = GRID_LIN;    }    SetColor(1);    SetLinestyle(1);    if ((graph->datawindow.xmin > graph->datawindow.xmax)            || (graph->datawindow.ymin > graph->datawindow.ymax)) {      fprintf(cp_err,         "gr_fixgrid: Internal Error: bad limits %lg, %lg, %lg, %lg...\r\n",        graph->datawindow.xmin, graph->datawindow.xmax,         graph->datawindow.ymin, graph->datawindow.xmax);      return;    }    if (graph->grid.gridtype == GRID_POLAR) {        graph->grid.circular = true;        polargrid();        return;    } else if (graph->grid.gridtype == GRID_SMITH) {        graph->grid.circular = true;        smithgrid();        return;    }    graph->grid.circular = false;    if ((graph->grid.gridtype == GRID_XLOG)            || (graph->grid.gridtype == GRID_LOGLOG))        dd = loggrid(graph, graph->datawindow.xmin,                graph->datawindow.xmax,                xtype, x_axis);    else        dd = lingrid(graph, graph->datawindow.xmin,                graph->datawindow.xmax,                xdelta, xtype, x_axis);    graph->datawindow.xmin = dd[0];    graph->datawindow.xmax = dd[1];    if ((graph->grid.gridtype == GRID_YLOG)            || (graph->grid.gridtype == GRID_LOGLOG))        dd = loggrid(graph, graph->datawindow.ymin,                graph->datawindow.ymax,                ytype, y_axis);    else        dd = lingrid(graph, graph->datawindow.ymin,                graph->datawindow.ymax,                ydelta, ytype, y_axis);    graph->datawindow.ymin = dd[0];    graph->datawindow.ymax = dd[1];/* do we really need this? *//*    SetLinestyle(0);    DrawLine(graph->viewportxoff, graph->viewportyoff,            graph->viewport.width + graph->viewportxoff,            graph->viewportyoff);    DrawLine(graph->viewportxoff, graph->viewportyoff,            graph->viewportxoff,            graph->viewport.height + graph->viewportyoff);    SetLinestyle(1);*/    return;}gr_redrawgrid(graph)GRAPH *graph;{    SetColor(1);    SetLinestyle(1);    /* draw labels */    if (graph->grid.xlabel) {      Text(graph->grid.xlabel,          graph->absolute.width -              (strlen(graph->grid.xlabel) + 3) * graph->fontwidth,          graph->fontheight);    }    if (graph->grid.ylabel) {      Text(graph->grid.ylabel,          graph->fontwidth,          graph->absolute.height / 2);    }    if ((graph->grid.gridtype == GRID_XLOG)            || (graph->grid.gridtype == GRID_LOGLOG))        drawloggrid(graph, graph->grid.xaxis.log.hmt,                graph->grid.xaxis.log.lmt,                graph->grid.xaxis.log.decsp,                graph->grid.xaxis.log.subs,                graph->grid.xaxis.log.pp, x_axis);    else        drawlingrid(graph,                graph->grid.xaxis.lin.units,                graph->grid.xaxis.lin.spacing,                graph->grid.xaxis.lin.numspace,                graph->grid.xaxis.lin.distance,                graph->grid.xaxis.lin.lowlimit,                graph->grid.xaxis.lin.highlimit,                graph->grid.xaxis.lin.onedec,                graph->grid.xaxis.lin.mult,                x_axis);    if ((graph->grid.gridtype == GRID_YLOG)            || (graph->grid.gridtype == GRID_LOGLOG))        drawloggrid(graph, graph->grid.yaxis.log.hmt,                graph->grid.yaxis.log.lmt,                graph->grid.yaxis.log.decsp,                graph->grid.yaxis.log.subs,                graph->grid.yaxis.log.pp, y_axis);    else        drawlingrid(graph,                graph->grid.yaxis.lin.units,                graph->grid.yaxis.lin.spacing,                graph->grid.yaxis.lin.numspace,                graph->grid.yaxis.lin.distance,                graph->grid.yaxis.lin.lowlimit,                graph->grid.yaxis.lin.highlimit,                graph->grid.yaxis.lin.onedec,                graph->grid.yaxis.lin.mult,                y_axis);}/* Plot a linear grid. Returns the new hi and lo limits. */static double *lingrid(graph, lo, hi, delta, type, axis)    GRAPH *graph;    double lo, hi;    double delta;    int type;    Axis axis;{    int mag, hmt, lmt, nsp, spacing, dst;    double tenpowmag;    bool onedec = false;    int margin;    int max;    static double dd[2];    int mult = 1;    char buf[16], *s;    if (axis == x_axis) {      margin = graph->viewportxoff;      max = graph->viewport.width + graph->viewportxoff;    } else {      margin = graph->viewportyoff;      max = graph->viewport.height + graph->viewportyoff;    }    if (delta < 0.0) {        fprintf(cp_err, "Warning: %cdelta is negative -- ignored\n",                (axis == x_axis) ? 'x' : 'y');        delta = 0;    }/* note: not idempotent, fix some other way XXX */    /* This is a hack to fix a problem on the HP 9000 ... */    if (!((axis == x_axis) ? graph->grid.xaxis.lin.hacked                  : graph->grid.yaxis.lin.hacked)            && hi - lo < 1e-6) {        if (axis == x_axis)          graph->grid.xaxis.lin.hacked = 1;        else          graph->grid.yaxis.lin.hacked = 1;        hi += 1e-6 * fabs(hi);        lo -= 1e-6 * fabs(lo);    }    /* Express the difference between the high and low values as     * diff = d * 10^mag. We know diff >= 0.0...  If scaleunits is     * set then make sure that mag is a multiple of 3.     */    mag = floor(mylog10(hi - lo));    tenpowmag = pow(10.0, (double) mag);    if (scaleunits) {        if ((mag % 3) && !((mag - 1) % 3)) {            mult = 10;            mag--;        } else if ((mag % 3) && !((mag + 1) % 3)) {            onedec = true;            mag++;        }    }    /* Now we have to round lo down, and hi up... */    lmt = (int) floor(lo / tenpowmag);    hmt = (int) ceil(hi / tenpowmag);    if (fabs(hi - tenpowmag) < 10e-20) {        /* This is a hack to fix a strange case... */        hmt = 1;    }    dst = hmt - lmt;    /* This is a strange case. */    if (dst == 1) {        dst = 10;        mag--;        tenpowmag /= 10;        hmt *= 10.0;        lmt *= 10.0;    }    dd[0] = lo = lmt * tenpowmag;    dd[1] = hi = hmt * tenpowmag;    /* We have to go from lmt to hmt, so think of some useful places     * to put grid lines. We will have a total of nsp lines, one     * every spacing pixels, which is every dst / nsp units.     */    if (delta == 0.0) {        for (nsp = 5; nsp < 10; nsp++)            if (!(dst % nsp))                break;        if (nsp == 10)            for (nsp = 2; nsp < 5; nsp++)                if (!(dst % nsp))                    break;        /* Aaaaaghhh... */        if ((dst == 11) || (dst == 13) || (dst == 17) || (dst == 19))            nsp = dst;        spacing = (max - margin) / nsp;    } else {        /* The user told us where to put the grid lines... They will         * not be equally spaced in this case (i.e, the right edge         * won't be a line).         */        nsp = (hi - lo) / delta;        spacing = (max - margin) * delta / (hi - lo);    }    /* In case we have a relatively small delta... */    while (nsp > dst) {        dst *= 10;        mag--;        hmt *= 10.0;        lmt *= 10.0;    }    /* Reset the max X coordinate to deal with round-off error. */    if (nsp && (delta == 0.0)) {        if (axis == x_axis)            graph->viewport.width = spacing * nsp;        else            graph->viewport.height = spacing * nsp;    } else if (!nsp) {        nsp = 1;    }    if (scaleunits) {        /* Figure out what to put here... */        switch (mag) {            case -18:   /* atto */                (void) strcpy(buf, "a");                break;            case -15:   /* femto */                (void) strcpy(buf, "f");                break;            case -12:   /* pico */                (void) strcpy(buf, "p");                break;            case -9:    /* nano */                (void) strcpy(buf, "n");                break;            case -6:    /* micro */                (void) strcpy(buf, "u");                break;            case -3:    /* milli */                (void) strcpy(buf, "m");                break;            case 0:     /* -- */                (void) strcpy(buf, "");                break;            case 3:     /* kilo */                (void) strcpy(buf, "K");                break;            case 6:     /* mega */                (void) strcpy(buf, "M");                break;            case 9:     /* giga */                (void) strcpy(buf, "G");                break;            case 12:    /* terra */                (void) strcpy(buf, "T");                break;            case 15:    /* peta */                (void) strcpy(buf, "P");                break;            case 18:    /* exa */                (void) strcpy(buf, "E");                break;            default:                (void) sprintf(buf, "e%d", mag);                break;        }        if (s = ft_typabbrev(type))            (void) strcat(buf, s);        else            /* Get rid of the prefix... */            (void) sprintf(buf, "e%d", mag);    } else        (void) sprintf(buf, "e%d", mag);    /* have to save non-intuitive variables left over        from old algorithms for redraws */    if (axis == x_axis) {      graph->grid.xaxis.lin.spacing = spacing;      graph->grid.xaxis.lin.numspace = nsp;      graph->grid.xaxis.lin.distance = dst;      graph->grid.xaxis.lin.lowlimit = lmt;      graph->grid.xaxis.lin.highlimit = hmt;      graph->grid.xaxis.lin.onedec = onedec;      graph->grid.xaxis.lin.mult = mult;      (void) strcpy(graph->grid.xaxis.lin.units, buf);    } else {      graph->grid.yaxis.lin.spacing = spacing;      graph->grid.yaxis.lin.numspace = nsp;      graph->grid.yaxis.lin.distance = dst;      graph->grid.yaxis.lin.lowlimit = lmt;      graph->grid.yaxis.lin.highlimit = hmt;      graph->grid.yaxis.lin.onedec = onedec;      graph->grid.yaxis.lin.mult = mult;      (void) strcpy(graph->grid.yaxis.lin.units, buf);    }    return (dd);}staticdrawlingrid(graph, units, spacing, nsp, dst, lmt, hmt, onedec, mult, axis)GRAPH *graph;char units[16];bool onedec;int hmt, lmt, nsp, spacing, dst, mult;Axis axis;{    int i, j;    char buf[16];    /* i counts how many pixels we have drawn, and j counts which unit     * we are at.     */    for (i = 0, j = lmt; j <= hmt; i += spacing, j += dst / nsp) {        if (j == 0)            SetLinestyle(0);        if (graph->grid.gridtype != GRID_NONE) {/* note: get rid of this parameter and draw both axes at once */            if (axis == x_axis)                DrawLine(graph->viewportxoff + i,                  graph->viewportyoff, graph->viewportxoff + i,                  graph->viewport.height + graph->viewportyoff);            else                DrawLine(graph->viewportxoff,                  graph->viewportyoff + i,                  graph->viewport.width + graph->viewportxoff,                  graph->viewportyoff + i);        }        if (j == 0)            SetLinestyle(1);        if (onedec)

⌨️ 快捷键说明

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