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

📄 grid.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 3 页
字号:
	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)),		    graph->viewportyoff + i -		    graph->fontheight / 2);        /* This is to make sure things work when delta > hi - lo. */        if (nsp == 1)            j += 1000;    }    if (axis == x_axis)        Text(units, (int) (graph->absolute.width * 0.6),            graph->fontheight);    else        Text(units, graph->fontwidth,            (int) (graph->absolute.height - 2 * graph->fontheight));    Update();}/* Plot a log grid.  Note that we pay no attention to x- and y-delta here. */static double *loggrid(GRAPH *graph, double lo, double hi, int type, Axis axis){    static double dd[2];    int margin;    int max;    int subs, pp, decsp, lmt, hmt;    int i, j;    double k;    double decs;    char buf[LABEL_CHARS], *s;    if (axis == x_axis && graph->grid.xsized) {      lmt = graph->grid.xaxis.log.lmt;      hmt = graph->grid.xaxis.log.hmt;      dd[0] = pow(10.0, (double) lmt);      dd[1] = pow(10.0, (double) hmt);      return dd;    } else if (axis == y_axis && graph->grid.ysized) {      lmt = graph->grid.yaxis.log.lmt;      hmt = graph->grid.yaxis.log.hmt;      dd[0] = pow(10.0, (double) lmt);      dd[1] = pow(10.0, (double) hmt);      return dd;    }    if (axis == x_axis) {      margin = graph->viewportxoff;      max = graph->absolute.width - graph->viewportxoff;    } else {      margin = graph->viewportyoff;      max = graph->absolute.height - graph->viewportyoff;    }    /* How many orders of magnitude.  We are already guaranteed that hi     * and lo are positive.     */    lmt = floor(mylog10(lo));    hmt = ceil(mylog10(hi));    decs = hmt - lmt;    pp = 1;    decsp = (max - margin) / decs;    if (decsp < 20) {	pp = ceil(20.0 / decsp);	decsp *= pp;	subs = 1;    } else if (decsp > 50) {	static int divs[ ] = { 20, 10, 5, 4, 2, 1 };	k = 5.0 / decsp;	for (i = 0; i < NUMELEMS(divs) - 1; i++) {		j = divs[i];		if (-log10(((double) j - 1.0) / j) > k)			break;	}	subs = divs[i];    } else	subs = 1;    /* Start at a line */    lmt = floor((double) lmt / pp) * pp;    decs = hmt - lmt;    decsp = (max - margin) / decs;    dd[0] = pow(10.0, (double) lmt);    dd[1] = pow(10.0, (double) hmt);    if ((s = ft_typabbrev(type))) {	(void) strcpy(buf, s);    } else {	(void) strcpy(buf, "Units");    }    if (axis == x_axis) {      (void) strcpy(graph->grid.xaxis.log.units, buf);      graph->viewport.width = decs * decsp;      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;      graph->grid.xsized = 1;    } else {      (void) strcpy(graph->grid.yaxis.log.units, buf);      graph->viewport.height = decs * decsp;      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;      graph->grid.ysized = 1;    }    return (dd);}/* PN static */voiddrawloggrid(GRAPH *graph, char *units, int hmt, int lmt, int decsp, int subs, int pp, Axis axis){    int i, j, k, m;    double t;    char buf[LABEL_CHARS];    /* Now plot every pp'th decade line, with subs lines between them. */    if (subs > 1)	SetLinestyle(0);    for (i = 0, j = lmt; j <= hmt; i += decsp * pp, 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);	}	if (j == -2)	    (void) sprintf(buf, "0.01");	else if (j == -1)	    (void) sprintf(buf, "0.1");	else if (j == 0)	    (void) sprintf(buf, "1");	else if (j == 1)	    (void) sprintf(buf, "10");	else if (j == 2)	    (void) sprintf(buf, "100");	else	    (void) sprintf(buf, "10^%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 subdivision lines */	if (subs > 1) {            SetLinestyle(1);	    t = 10.0 / subs;	    for (k = ceil(subs / 10.0) + 1; k < subs; k++) {		m = i + decsp * log10((double) t * k);		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);		}	    }            SetLinestyle(0);	}    }    if (axis == x_axis)        Text(units, (int) (graph->absolute.width * 0.6),            graph->fontheight);    else        Text(units, graph->fontwidth,            (int) (graph->absolute.height - 2 * graph->fontheight));    Update();}/* Polar grids */static voidpolargrid(GRAPH *graph){    double d, mx, my, tenpowmag;    int hmt, lmt, mag;    double minrad, maxrad;    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;    }    /* 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;    /* Figure out the minimum and maximum radii we're dealing with. */    mx = (graph->data.xmin + graph->data.xmax) / 2;    my = (graph->data.ymin + graph->data.ymax) / 2;    d = sqrt(mx * mx + my * my);    maxrad = d + (graph->data.xmax - graph->data.xmin) / 2;    minrad = d - (graph->data.xmax - graph->data.xmin) / 2;    if (maxrad == 0.0) {        fprintf(cp_err, "Error: 0 radius in polargrid\n");        return;    }    if ((graph->data.xmin < 0) && (graph->data.ymin < 0) &&             (graph->data.xmax > 0) && (graph->data.ymax > 0))        minrad = 0;    if ((graph->data.xmin == - graph->data.xmax)            && (graph->data.ymin == -graph->data.ymax)            && (graph->data.xmin == graph->data.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;    /* Make sure that the range is square */    mx = graph->data.xmax - graph->data.xmin;    my = graph->data.ymax - graph->data.ymin;    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 (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 */    graph->grid.xaxis.circular.hmt = hmt;    graph->grid.xaxis.circular.lmt = lmt;    graph->grid.xaxis.circular.mag = mag;}static voiddrawpolargrid(GRAPH *graph){    double tenpowmag, theta;    int hmt, lmt, i, step, mag;    int relcx, relcy, relrad, dist, degs;    int x1, y1, x2, y2;    double minrad, maxrad, pixperunit;    char buf[64];    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 *graph, int deg, int x, int y, int cx, int cy, int lx, int 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);    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 *graph, int lab, double theta, int x, int 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){    double mx, my;

⌨️ 快捷键说明

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