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