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

📄 grid.c

📁 支持数字元件仿真的SPICE插件
💻 C
📖 第 1 页 / 共 3 页
字号:
/* This is kind of wierd. If dist = 0, then this is the normal case, where * the labels should go along the positive X-axis.  Otherwise, to make * sure that all circles drawn have labels, put the label near the circle * along the line from the logical center to the physical center. */voidaddradlabel(lab, theta, x, y)    double theta;    int lab, x, y;{    char buf[32];    (void) sprintf(buf, "%d", lab);    if (theta == PI) {        y = y - graph->fontheight - 2;        x = x - graph->fontwidth * strlen(buf) - 3;    }    Text(buf, x, y);    return;}#endif/* ... and smith charts. */static voidsmithgrid(){#ifdef notdef    double mx, my, rad, tenpowmag, d, minrad, maxrad;    double pixperunit;    int relcx, relcy;    int mt, mag, i, j, k, sp, xoff, yoff, zheight;    int basemag;    char buf[64], plab[32], nlab[32];    bool centered = false;    gi_resetcolor(2, "Coral");    gi_resetcolor(3, "MediumAquamarine");    gi_setlinestyle(0);    gi_maxx -= 2 * gi_fntwidth;    gi_maxy -= 2 * gi_fntheight;    /* Make sure that our area is square, etc. */    if ((gi_maxx - gr_xmargin) > (gi_maxy - gr_ymargin)) {        i = (gi_maxx - gr_xmargin - gi_maxy + gr_ymargin) / 2;        gi_maxx -= i;        gr_xmargin += i;    } else {        i = (gi_maxy - gr_ymargin - gi_maxx + gr_xmargin) / 2;        gi_maxy -= i;        gr_ymargin += i;    }    gr_xcenter = (gi_maxx + gr_xmargin) / 2;    gr_ycenter = (gi_maxy + gr_ymargin) / 2;    gr_radius = (gi_maxx - gr_xmargin) / 2;    /* We don't handle cases where the range isn't centered about the     * X-axis.  This is something that has to be fixed...     */    if (fabs(graph->datawindow.ymin) > fabs(graph->datawindow.ymax))        graph->datawindow.ymax = - graph->datawindow.ymin;    else        graph->datawindow.ymin = - graph->datawindow.ymax;        /* What a hassle. */    graph->datawindow.xmin *= sqrt(2.0);    graph->datawindow.xmax *= sqrt(2.0);    graph->datawindow.ymin *= sqrt(2.0);    graph->datawindow.ymax *= sqrt(2.0);    /* We have to make sure that the range is square... */    mx = graph->datawindow.xmax - graph->datawindow.xmin;    my = graph->datawindow.ymax - graph->datawindow.ymin;    if (mx > my) {        graph->datawindow.ymin -= (mx - my) / 2;        graph->datawindow.ymax += (mx - my) / 2;    } else if (mx < my) {        graph->datawindow.xmin -= (my - mx) / 2;        graph->datawindow.xmax += (my - mx) / 2;    }    if ((graph->datawindow.xmin == - graph->datawindow.xmax) &&             (graph->datawindow.ymin == -            graph->datawindow.ymax) && (graph->datawindow.xmin ==             graph->datawindow.ymin))        centered = true;    /* Figure out the minimum and maximum radii we're dealing with. */    mx = (graph->datawindow.xmin + graph->datawindow.xmax) / 2;    my = (graph->datawindow.ymin + graph->datawindow.ymax) / 2;    d = sqrt(mx * mx + my * my);    maxrad = d + (graph->datawindow.xmax - graph->datawindow.xmin) / 2;    minrad = d - (graph->datawindow.xmax - graph->datawindow.xmin) / 2;    mag = floor(mylog10(maxrad));    tenpowmag = pow(10.0, (double) mag);    pixperunit = gr_radius * 2 / (graph->datawindow.xmax -             graph->datawindow.xmin);    relcx = - (graph->datawindow.xmin + graph->datawindow.xmax) / 2 *             pixperunit;    relcy = - (graph->datawindow.ymin + graph->datawindow.ymax) / 2 *             pixperunit;    xoff = - pixperunit * (graph->datawindow.xmin + graph->datawindow.xmax) / 2;    yoff = - pixperunit * (graph->datawindow.ymin + graph->datawindow.ymax) / 2;    /* Sweep the range from 10e-20 to 10e20.  If any arcs fall into the     * picture, plot the arc set.     */    for (mag = -20; mag < 20; mag++) {        i = gr_radius * pow(10.0, (double) mag) / maxrad;        if (i > 10) {            j = 1;            break;        } else if (i > 5) {            j = 2;            break;        } else if (i > 2) {            j = 5;            break;        }    }    k = 0;    /* Now plot all the arc sets.  Go as high as 5 times the radius that     * will fit on the screen.  The base magnitude is one more than      * the least magnitude that will fit...     */    if (i > 20)        basemag = mag;    else        basemag = mag + 1;    while (mag < 20) {        /*        i = j * gr_radius * pow(10.0, (double) mag) / (maxrad * 2);        */        i = j * pow(10.0, (double) mag) * pixperunit / 2;        if (i / 5 > gr_radius + ((xoff > 0) ? xoff : - xoff))            break;        (void) sprintf(plab, "%lg", j * pow(10.0,                 (double) (mag - basemag)));        (void) sprintf(nlab, "-%lg", j * pow(10.0,                (double) (mag - basemag)));        arcset(i, k, gr_radius, gr_xcenter, gr_ycenter, xoff, yoff,                plab, nlab);        if (i * 2.5 < gr_radius + ((xoff > 0) ? xoff : - xoff))            k = i;        if (j == 5) {            j = 1;            mag++;        } else if (j == 2)            j = 5;        else if (j == 1)            j = 2;    }    if (mag == 20) {        fprintf(cp_err, "smithgrid: Internal Error: screwed up\n");        return;    }    gi_arc(gr_xcenter, gr_ycenter, gr_radius, 0.0, 0.0);    if ((xoff > - gr_radius) && (xoff < gr_radius)) {        zheight = gr_radius * sin(acos((double) xoff / gr_radius));        if (zheight < 0)            zheight = - zheight;        gi_drawline(gr_xcenter + xoff, gr_ycenter - zheight,                gr_xcenter + xoff, gr_ycenter + zheight);    }    if ((yoff > - gr_radius) && (yoff < gr_radius)) {        zheight = gr_radius * cos(asin((double) yoff / gr_radius));        if (zheight < 0)            zheight = - zheight;        gi_drawline(gr_xcenter - zheight, gr_ycenter + yoff,                gr_xcenter + zheight, gr_ycenter + yoff);    }    (void) sprintf(buf, "e%d", basemag);    gi_text(buf, gr_xcenter + gr_radius, gr_ycenter - gr_radius, 0, false);#ifdef notdef    gi_text("0", gr_xcenter + gr_radius + gi_fntwidth, gr_ycenter -             gi_fntheight / 2, 0, false);    gi_text("o", gr_xcenter + gr_radius + gi_fntwidth * 2, gr_ycenter, 0,             false);    gi_text("90", gr_xcenter - gi_fntwidth, gr_ycenter + gr_radius +             gi_fntheight / 2, 0, false);    gi_text("o", gr_xcenter + gi_fntwidth, gr_ycenter + gr_radius +             gi_fntheight, 0, false);    gi_text("180", gr_xcenter - gr_radius - gi_fntwidth * 5, gr_ycenter             - gi_fntheight / 2, 0, false);    gi_text("o", gr_xcenter - gr_radius - gi_fntwidth * 2, gr_ycenter, 0,             false);    gi_text("-90", gr_xcenter - gi_fntwidth * 2, gr_ycenter - gr_radius -            2 * gi_fntheight, 0, false);    gi_text("o", gr_xcenter + gi_fntwidth, gr_ycenter - gr_radius -            gi_fntheight - gi_fntheight / 2, 0, false);#endif    gi_update();    return;#endif}/* Draw one arc set.  The arcs should have radius rad. The outermost circle is * described by (centx, centy) and maxrad, and the distance from the right side * of the bounding circle to the logical center of the other circles in pixels * is xoffset (positive brings the negative plane into the picture). * plab and nlab are the labels to put on the positive and negative X-arcs, * respectively...  If the X-axis isn't on the screen, then we have to be * clever... */#ifdef notdefstatic voidarcset(rad, prevrad, maxrad, centx, centy, xoffset, yoffset, plab, nlab)    int rad, prevrad, maxrad, centx, centy, xoffset, yoffset;    char *plab, *nlab;{    double angle = atan((double) prevrad / rad);    int x;    /* Let's be lazy and just draw everything -- we won't get called too     * much and the circles get clipped anyway...     */    gi_setcolor(2);    cliparc(centx + xoffset - rad, centy + yoffset, rad, 2 * angle,            2 * PI - 2 * angle, centx, centy, maxrad);    cliparc(centx + xoffset + rad, centy + yoffset, rad, PI + 2 *             angle, PI - 2 * angle, centx, centy, maxrad);    /* Draw the upper and lower circles.  */    gi_setcolor(3);    cliparc(centx + xoffset, centy + yoffset + rad, rad, PI * 1.5 + 2 *            angle, PI * 1.5 - 2 * angle, centx, centy, maxrad);    cliparc(centx + xoffset, centy + yoffset - rad, rad, PI / 2 + 2 *            angle, PI / 2 - 2 * angle, centx, centy, maxrad);        /* Now toss the labels on... */    gi_setcolor(1);    x = centx + xoffset - 2 * rad - gi_fntwidth * strlen(plab) - 2;    if ((x > gr_xmargin) && (x < gi_maxx))        gi_text(plab, x, centy - gi_fntheight - 1, false, false);    x = centx + xoffset + 2 * rad - gi_fntwidth * strlen(nlab) - 2;    if ((x > gr_xmargin) && (x < gi_maxx))        gi_text(nlab, x, centy - gi_fntheight - 1, false, false);    return;}/* This routine draws an arc and clips it to a circle.  It's hard to figure * out how it works without looking at the piece of scratch paaper I have * in front of me, so let's hope it doesn't break... */static voidcliparc(cx, cy, rad, start, end, clipx, clipy, cliprad)    int cx, cy, rad, clipx, clipy, cliprad;    double start, end;{    int x, y, tx, ty, dist;    double alpha, theta, phi, a1, a2, d, l;    bool in;    x = cx - clipx;    y = cy - clipy;    dist = sqrt((double) (x * x + y * y));    if (!rad || !cliprad)        return;    if (dist + rad < cliprad) {        /* The arc is entirely in the boundary. */        gi_arc(cx, cy, rad, start, end);        return;    } else if ((dist - rad >= cliprad) || (rad - dist >= cliprad)) {        /* The arc is outside of the boundary. */        return;    }    /* Now let's figure out the angles at which the arc crosses the     * circle. We know dist != 0.     */    if (x)        phi = atan((double) y / x);    else if (y > 0)        phi = PI * 1.5;    else        phi = PI / 2;    if (cx > clipx)        theta = PI + phi;    else        theta = phi;    alpha = acos((double) (dist * dist + rad * rad - cliprad * cliprad) /            (2 * dist * rad));    a1 = theta + alpha;    a2 = theta - alpha;    while (a1 < 0)        a1 += PI * 2;    while (a2 < 0)        a2 += PI * 2;    while (a1 >= PI * 2)        a1 -= PI * 2;    while (a2 >= PI * 2)        a2 -= PI * 2;    tx = cos(start) * rad + x;    ty = sin(start) * rad + y;    d = sqrt((double) tx * tx + ty * ty);    in = (d > cliprad) ? false : true;    /* Now begin with start.  If the point is in, draw to either end, a1,     * or a2, whichever comes first.     */    d = PI * 3;    if ((end < d) && (end > start))        d = end;    if ((a1 < d) && (a1 > start))        d = a1;    if ((a2 < d) && (a2 > start))        d = a2;    if (d == PI * 3) {        d = end;        if (a1 < d)            d = a1;        if (a2 < d)            d = a2;    }    if (in)        gi_arc(cx, cy, rad, start, d);    if (d == end)        return;    if (a1 != a2)        in = in ? false : true;    /* Now go from here to the next point. */    l = d;    d = PI * 3;    if ((end < d) && (end > l))        d = end;    if ((a1 < d) && (a1 > l))        d = a1;    if ((a2 < d) && (a2 > l))        d = a2;    if (d == PI * 3) {        d = end;        if (a1 < d)            d = a1;        if (a2 < d)            d = a2;    }    if (in)        gi_arc(cx, cy, rad, l, d);    if (d == end)        return;    in = in ? false : true;        /* And from here to the end. */    if (in)        gi_arc(cx, cy, rad, d, end);    return;}#endif#ifdef notdef/* These routines are wrong on a lot of systems. */doublefloor(d)    double d;{    double fp, ip;    if (d >= 0.0) {        fp = modf(d, &ip);        return (ip);    } else {        /* This is the case that lattice C screws up... */        fp = modf(-d, &ip);        if (fp != 0.0)            return (-ip - 1);        else            return (-ip);    }}doubleceil(d)    double d;{    return (- floor(-d));}#endif

⌨️ 快捷键说明

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