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

📄 grid.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    graph->datawindow.xmax = graph->data.xmax;    graph->datawindow.ymin = graph->data.ymin;    graph->datawindow.ymax = graph->data.ymax;    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;    }    /* Range is square with upper bound maxrad */#ifdef notdef    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;#endif#ifdef notdef    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;	graph->grid.xaxis.circular.lmt = lmt;	graph->grid.yaxis.circular.lmt = step;#endif    graph->grid.xaxis.circular.hmt = hmt;    graph->grid.xaxis.circular.lmt = lmt;    graph->grid.xaxis.circular.mag = mag;#ifdef notdef    graph->datawindow.xmin = xx - maxrad;    graph->datawindow.xmax = xx + maxrad;    graph->datawindow.ymin = yy - maxrad;    graph->datawindow.ymax = yy + maxrad;#endif}static voiddrawpolargrid(graph)GRAPH *graph;{    double mx, my, rad, tenpowmag, theta;    int hmt, lmt, i, step, mag;    int relcx, relcy, relrad, dist, degs;    int x1, y1, x2, y2;    double minrad, maxrad, pixperunit, xx, yy;    char buf[64];#ifdef notdef    step = graph->grid.yaxis.circular.lmt;    mag = floor(mylog10(maxrad));    tenpowmag = pow(10.0, (double) mag);    pixperunit = graph->grid.xaxis.circular.radius / (maxrad - minrad);#endif    hmt = graph->grid.xaxis.circular.hmt;    lmt = graph->grid.xaxis.circular.lmt;    mag = graph->grid.xaxis.circular.mag;    tenpowmag = pow(10.0, (double) mag);    maxrad = hmt * tenpowmag;    minrad = lmt * tenpowmag;     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 * 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;    /* The distance from the center of the plotting area to the center of     * the logical area.     */    dist = sqrt((double) (relcx * relcx + relcy * relcy));    SetLinestyle(0);    Arc(graph->grid.xaxis.circular.center,            graph->grid.yaxis.circular.center,            graph->grid.xaxis.circular.radius,            (double) 0.0, (double) 0.0);    SetLinestyle(1);    /* Now draw the circles. */    for (i = lmt;	(relrad = i * tenpowmag * pixperunit)	<= dist + graph->grid.xaxis.circular.radius;	i += step)    {        cliparc((double) graph->grid.xaxis.circular.center + relcx,                (double) graph->grid.yaxis.circular.center + relcy,                (double) relrad, 0.0, 0.0,                graph->grid.xaxis.circular.center,                graph->grid.yaxis.circular.center,                graph->grid.xaxis.circular.radius, 0);        /* Toss on the label */        if (relcx || relcy)            theta = atan2((double) relcy, (double) relcx);        else            theta = M_PI;        if (i && (relrad > dist - graph->grid.xaxis.circular.radius))            addradlabel(graph, 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 * M_PI / 6);            y2 = y1 + graph->grid.xaxis.circular.radius * 2                    * sin(i * M_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 */		/*XXXX*/                adddeglabel(graph, i * 30, x2, y2, x1, y1,		    graph->grid.xaxis.circular.center,		    graph->grid.yaxis.circular.center);            }        }    } else {        /* Figure out the angle that we have to fill up */        theta = 2 * asin((double) graph->grid.xaxis.circular.radius                / dist);        theta = theta * 180 / M_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 * M_PI / 180);            y2 = y1 + dist * 2 * sin(i * M_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(graph, i, x2, y2, x1, y1,		    graph->grid.xaxis.circular.center,		    graph->grid.yaxis.circular.center);            }        }    }    (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.circular.radius);    Update();    return;}/* Put a degree label on the screen, with 'deg' as the label, near point (x, y) * such that the perpendicular to (cx, cy) and (x, y) doesn't overwrite the * label.  If the distance between the center and the point is * too small, don't put the label on. */#define LOFF    5#define MINDIST 10static voidadddeglabel(graph, deg, x, y, cx, cy, lx, ly)    GRAPH *graph;    int deg, x, y, cx, cy, lx, ly;{    char buf[8];    int d, w, h;    double angle;    if (sqrt((double) (x - cx) * (x - cx) + (y - cy) * (y - cy)) < 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;}/* 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. */static voidaddradlabel(graph, lab, theta, x, y)    GRAPH *graph;    double theta;    int lab, x, y;{    char buf[32];    (void) sprintf(buf, "%d", lab);    if (theta == M_PI) {        y = y - graph->fontheight - 2;        x = x - graph->fontwidth * strlen(buf) - 3;    } else	x = x - graph->fontwidth * strlen(buf) - 3;    Text(buf, x, y);    return;}/* Smith charts. */#define gr_xcenter	graph->grid.xaxis.circular.center#define gr_ycenter	graph->grid.yaxis.circular.center#define gr_radius	graph->grid.xaxis.circular.radius#define gi_fntwidth	graph->fontwidth#define gi_fntheight	graph->fontheight#define gi_maxx		graph->viewport.width+graph->viewportxoff#define gr_xmargin	graph->viewportxoff#define gr_ymargin	graph->viewportyoffstatic voidsmithgrid(graph)GRAPH *graph;{    double mx, my;    bool centered = false;    SetLinestyle(0);    /* 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;    }    /* Make sure that the borders are even */    if (graph->viewport.width & 1) {	graph->viewport.width += 1;	graph->viewport.height += 1;    }    graph->grid.xaxis.circular.center = graph->viewport.width / 2                        + graph->viewportxoff;    graph->grid.yaxis.circular.center = graph->viewport.height / 2                        + graph->viewportyoff;    graph->grid.xaxis.circular.radius = graph->viewport.width / 2;    /* We have to make sure that the range is square. */    graph->datawindow.xmin = graph->data.xmin;    graph->datawindow.xmax = graph->data.xmax;    graph->datawindow.ymin = graph->data.ymin;    graph->datawindow.ymax = graph->data.ymax;    if (graph->datawindow.ymin > 0)	graph->datawindow.ymin *= -1;    if (graph->datawindow.xmin > 0)	graph->datawindow.xmin *= -1;    if (graph->datawindow.ymax < 0)	graph->datawindow.ymax *= -1;    if (graph->datawindow.xmax < 0)	graph->datawindow.xmax *= -1;    if (fabs(graph->datawindow.ymin) > fabs(graph->datawindow.ymax))        graph->datawindow.ymax = - graph->datawindow.ymin;    else        graph->datawindow.ymin = - graph->datawindow.ymax;    if (fabs(graph->datawindow.xmin) > fabs(graph->datawindow.xmax))        graph->datawindow.xmax = - graph->datawindow.xmin;    else        graph->datawindow.xmin = - graph->datawindow.xmax;    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;#ifdef notdef    /* 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;#endif    /* Issue a warning if our data range is not normalized */    if (graph->datawindow.ymax > 1.1) {	printf("\nwarning: exceeding range for smith chart");	printf("\nplease normalize your data to -1 < r < +1\n");    }}/* maximum number of circles */#define CMAX  50static voiddrawsmithgrid(graph)GRAPH *graph;{    double mx, my, rad, tenpowmag, d, dphi[CMAX], minrad, maxrad, rnorm[CMAX];    double pixperunit;    int mag, i, j, k;    double ir[CMAX], rr[CMAX], ki[CMAX], kr[CMAX], ks[CMAX];    int xoff, yoff, zheight;    int basemag, plen;    char buf[64], plab[32], nlab[32];    /* 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 = graph->viewport.width / (graph->datawindow.xmax -             graph->datawindow.xmin);    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;

⌨️ 快捷键说明

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