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

📄 grid.c

📁 支持数字元件仿真的SPICE插件
💻 C
📖 第 1 页 / 共 3 页
字号:
            (void) sprintf(buf, "%.1lf", (double) j / 10);        else            (void) sprintf(buf, "%d", j * mult);        if (axis == x_axis)            Text(buf, graph->viewportxoff + i -                    strlen(buf) / 2 * graph->fontwidth,                    (int) (graph->fontheight * 2.5));        else            Text(buf, graph->viewportxoff -                    graph->fontwidth * (strlen(buf) + 1),                    graph->viewportyoff + i -                    graph->fontheight / 2);        /* This is to make sure things work when delta > hi - lo. */        if (nsp == 1)            j++;    }    if (axis == x_axis)        Text(units,            graph->absolute.width -                (strlen(units) + 10) * graph->fontwidth,            graph->fontheight);    else        Text(units, graph->fontwidth,            (int) (graph->absolute.height * 0.75));    Update();}/* Plot a log grid.  Note that we pay no attention to x- and y-delta here. *//* ARGSUSED */static double *loggrid(graph, lo, hi, type, axis)    GRAPH *graph;    double lo, hi;    int type;    Axis axis;{    static double dd[2];    int margin;    int max;    int decs, subs, pp, decsp, lmt, hmt;    if (axis == x_axis) {      margin = graph->viewportxoff;      max = graph->viewport.width + graph->viewportxoff;    } else {      margin = graph->viewportyoff;      max = graph->viewport.height + graph->viewportyoff;    }    /* How many orders of magnitude... We are already guaranteed that hi     * and lo are positive. We want to have something like 8 grid lines     * total, so if there are few orders of magnitude put in intermediate     * lines...     */    lmt = floor(mylog10(lo));    hmt = ceil(mylog10(hi));    dd[0] = pow(10.0, (double) lmt);    dd[1] = pow(10.0, (double) hmt);    decs = hmt - lmt;    subs = 8 / decs;    if (decs > 10)        pp = decs / 8 + 1;    else        pp = 1;        decsp = (max - margin) * pp / decs;    if (axis == x_axis) {      graph->grid.xaxis.log.hmt = hmt;      graph->grid.xaxis.log.lmt = lmt;      graph->grid.xaxis.log.decsp = decsp;      graph->grid.xaxis.log.subs = subs;      graph->grid.xaxis.log.pp = pp;    } else {      graph->grid.yaxis.log.hmt = hmt;      graph->grid.yaxis.log.lmt = lmt;      graph->grid.yaxis.log.decsp = decsp;      graph->grid.yaxis.log.subs = subs;      graph->grid.yaxis.log.pp = pp;    }    return (dd);}staticdrawloggrid(graph, hmt, lmt, decsp, subs, pp, axis)GRAPH *graph;int hmt, lmt, decsp, subs, pp;Axis axis;{    int i, j, k, l, m;    char buf[16];    /* Now plot every pp'th decade line, with subs lines between them. */    for (i = 0, j = lmt; j <= hmt; i += decsp, j += pp) {        /* Draw the decade line... */        if (graph->grid.gridtype != GRID_NONE) {            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);        }        (void) sprintf(buf, "e%d", j);        if (axis == x_axis)            Text(buf, graph->viewportxoff + i - strlen(buf) / 2,                    (int) (graph->fontheight * 2.5));        else            Text(buf, graph->viewportxoff - graph->fontwidth *                    (strlen(buf) + 1),                    graph->viewportyoff + i -                    graph->fontheight / 2);        if (j == hmt)            break;        /* Now draw the other lines... */        for (k = 1; k <= subs; k++) {            l = ceil((double) k * 10 / subs);            if (l == 10)                break;            m = decsp * log10((double ) l) + i;            if (graph->grid.gridtype != GRID_NONE) {                if (axis == x_axis)                    DrawLine(graph->viewportxoff + m,                        graph->viewportyoff,                        graph->viewportxoff + m,                        graph->viewport.height                          + graph->viewportyoff);                else                    DrawLine(graph->viewportxoff,                        graph->viewportyoff + m,                        graph->viewport.width                          + graph->viewportxoff,                        graph->viewportyoff + m);            }        }    }    Update();}/* Polar grids... */static voidpolargrid(){#ifdef notdef    double mx, my, rad, tenpowmag, theta;    int hmt, lmt, mag, i, step;    int relcx, relcy, relrad, dist, degs;    int x1, y1, x2, y2;    double minrad, maxrad, pixperunit, xx, yy;    bool centered = false;    /* Make sure that our area is square. */    if (graph->viewport.width > graph->viewport.height) {        graph->viewport.width =  graph->viewport.height;    } else {        graph->viewport.height = graph->viewport.width;    }    graph->grid.xaxis.circular.center = (graph->viewport.width                        + graph->viewportxoff) / 2;    graph->grid.yaxis.circular.center = (graph->viewport.height                        + graph->viewportyoff) / 2;    graph->grid.xaxis.circular.radius = graph->viewport.width / 2;    /* Figure out the minimum and maximum radii we're dealing with. */    minrad = HUGE;    maxrad = - HUGE;    rad = sqrt(graph->datawindow.xmin * graph->datawindow.xmin            + graph->datawindow.ymin * graph->datawindow.ymin);    if (rad > maxrad)        maxrad = rad;    if (rad < minrad)        minrad = rad;    rad = sqrt(graph->datawindow.xmin * graph->datawindow.xmin            + graph->datawindow.ymax * graph->datawindow.ymax);    if (rad > maxrad)        maxrad = rad;    if (rad < minrad)        minrad = rad;    rad = sqrt(graph->datawindow.xmax * graph->datawindow.xmax            + graph->datawindow.ymin * graph->datawindow.ymin);    if (rad > maxrad)        maxrad = rad;    if (rad < minrad)        minrad = rad;    rad = sqrt(graph->datawindow.xmax * graph->datawindow.xmax            + graph->datawindow.ymax * graph->datawindow.ymax);    if (rad > maxrad)        maxrad = rad;    if (rad < minrad)        minrad = rad;        if (maxrad == 0.0) {        fprintf(cp_err, "Error: 0 radius in polargrid\n");        return;    }    if ((graph->datawindow.xmin < 0) && (graph->datawindow.ymin < 0) &&             (graph->datawindow.xmax > 0) && (graph->datawindow.ymax > 0))        minrad = 0;    if ((graph->datawindow.xmin == - graph->datawindow.xmax)            && (graph->datawindow.ymin == -graph->datawindow.ymax)            && (graph->datawindow.xmin == graph->datawindow.ymin))        centered = true;    mag = floor(mylog10(maxrad));    tenpowmag = pow(10.0, (double) mag);    hmt = maxrad / tenpowmag;    lmt = minrad / tenpowmag;    if (hmt * tenpowmag < maxrad)        hmt++;    if (lmt * tenpowmag > minrad)        lmt--;    maxrad = hmt * tenpowmag;    minrad = lmt * tenpowmag;    xx = graph->datawindow.xmin + graph->datawindow.xmax;    yy = graph->datawindow.ymin + graph->datawindow.ymax;    graph->datawindow.xmin = xx - maxrad;    graph->datawindow.xmax = xx + maxrad;    graph->datawindow.ymin = yy - maxrad;    graph->datawindow.ymax = yy + maxrad;    if (ft_grdb)        printf("polar: maxrad = %g, center = (%g, %g)\n",                maxrad, xx, yy);    if ((minrad == 0) && ((hmt - lmt) > 5)) {        if (!((hmt - lmt) % 2))            step = 2;        else if (!((hmt - lmt) % 3))            step = 3;        else             step = 1;    } else        step = 1;        pixperunit = graph->grid.xaxis.circular.radius / (maxrad - minrad);    relcx = - (graph->datawindow.xmin + graph->datawindow.xmax) / 2            * pixperunit;    relcy = - (graph->datawindow.ymin + graph->datawindow.ymax) / 2            * pixperunit;    /* The distance from the center of the plotting area to the center of     * the logical area.     */    dist = sqrt((double) (relcx * relcx + relcy * relcy));drawpolargrid(graph)GRAPH *graph;{    double mx, my, rad, tenpowmag, theta;    int hmt, lmt, mag, i, step;    int relcx, relcy, relrad, dist, degs;    int x1, y1, x2, y2;    double minrad, maxrad, pixperunit, xx, yy;    char buf[64];    Setlinestyle(0);    Arc(graph->grid.xaxis.circular.center,            graph->grid.yaxis.circular.center,            graph->grid.xaxis.circular.radius,            0, 0);    Setlinestyle(1);    /* Now draw the circles. */    for (i = lmt; (relrad = i * tenpowmag * pixperunit) <=             dist + graph->grid.xaxis.circular.radius; i += step) {        cliparc(graph->grid.xaxis.circular.center + relcx,                graph->grid.yaxis.circular.center + relcy,                relrad, 0.0, 0.0,                graph->grid.xaxis.circular.center,                graph->grid.yaxis.circular.center,                graph->grid.xaxis.circular.radius);        /* Toss on the label... */        if (relcx || relcy)            theta = atan2((double) relcy, (double) relcx);        else            theta = PI;        if (i && (relrad > dist - graph->grid.xaxis.circular.radius))            addradlabel(i, theta,                (int) (graph->grid.xaxis.circular.center -                    (relrad - dist) * cos(theta)),                (int) (graph->grid.yaxis.circular.center                    - (relrad - dist) * sin(theta)));    }    /* Now draw the spokes.  We have two possible cases -- first, the     * origin may be inside the area -- in this case draw 12 spokes.     * Otherwise, draw several spokes at convenient places.     */    if ((graph->datawindow.xmin <= 0.0)            && (graph->datawindow.xmax >= 0.0)            && (graph->datawindow.ymin <= 0.0)            && (graph->datawindow.ymax >= 0.0)) {        for (i = 0; i < 12; i++) {            x1 = graph->grid.xaxis.circular.center + relcx;            y1 = graph->grid.yaxis.circular.center + relcy;            x2 = x1 + graph->grid.xaxis.circular.radius * 2                    * cos(i * PI / 6);            y2 = y1 + graph->grid.xaxis.circular.radius * 2                    * sin(i * PI / 6);            if (!clip_to_circle(&x1, &y1, &x2, &y2,                    graph->grid.xaxis.circular.center,                    graph->grid.yaxis.circular.center,                    graph->grid.xaxis.circular.radius))                Drawline(x1, y1, x2, y2); {                /* Add a label here... */                adddeglabel(i * 30, x2, y2, x1, y1);            }        }    } else {        /* Figure out the angle that we have to fill up... */        theta = 2 * asin((double) graph->grid.xaxis.circular.radius                / dist);        theta = theta * 180 / PI;   /* Convert to degrees. */                /* See if we should put lines at 30, 15, 5, or 1 degree          * increments.         */        if (theta / 30 > 3)            degs = 30;        else if (theta / 15 > 3)            degs = 15;        else if (theta / 5 > 3)            degs = 5;        else            degs = 1;        /* We'll be cheap... */        for (i = 0; i < 360; i+= degs) {            x1 = graph->grid.xaxis.circular.center + relcx;            y1 = graph->grid.yaxis.circular.center + relcy;            x2 = x1 + dist * 2 * cos(i * PI / 180);            y2 = y1 + dist * 2 * sin(i * PI / 180);            if (!clip_to_circle(&x1, &y1, &x2, &y2,                    graph->grid.xaxis.circular.center,                    graph->grid.yaxis.circular.center,                    graph->grid.xaxis.circular.radius)) {                Drawline(x1, y1, x2, y2);                /* Put on the label... */                adddeglabel(i, x2, y2, x1, y1);            }        }    }    (void) sprintf(buf, "e%d", mag);    Text(buf, graph->grid.xaxis.circular.center              + graph->grid.xaxis.circular.radius,            graph->grid.yaxis.circular.center              - graph->grid.xaxis.radius);    Update();    return;#endif}/* Put a degree label on the screen, with 'deg' as the label, near point (x, y) * such that the perpendicular to (lx, ly) and (x, y) doesn't overwrite the * label... Sort of...  If the distance between the center and the point is * too small, don't put the label on... */#ifdef notdef#define LOFF    5#define MINDIST 10static voidadddeglabel(deg, x, y, lx, ly)    int deg, x, y, lx, ly;{    char buf[8];    int d, w, h;    double angle;    if (sqrt((double) (x - lx) * (x - lx) + (y - ly) * (y - ly)) < MINDIST)        return;    (void) sprintf(buf, "%d", deg);    w = graph->fontwidth * (strlen(buf) + 1);    h = graph->fontheight * 1.5;    angle = atan2((double) (y - ly), (double) (x - lx));    d = fabs(cos(angle)) * w / 2 + fabs(sin(angle)) * h / 2 + LOFF;    x = x + d * cos(angle) - w / 2;    y = y + d * sin(angle) - h / 2;    Text(buf, x, y);    Text("o", x + strlen(buf) * graph->fontwidth,            y + graph->fontheight / 2, 0);    return;}

⌨️ 快捷键说明

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