📄 grid.c
字号:
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 + -