📄 grid.c
字号:
hmt = ceil(hmt / step) * step; dst = hmt - lmt; lo = lmt * tenpowmag2; hi = hmt * tenpowmag2; nsp = (dst + step - 0.0001) / step; } else { /* The user told us where to put the grid lines. They will * not be equally spaced in this case (i.e, the right edge * won't be a line). */ nsp = (hi - lo) / delta; if (nsp > 100) nsp = 100; step = (max - margin) * delta / (hi - lo); } spacing = (max - margin) / nsp; dd[0] = lo; dd[1] = hi; /* Reset the max coordinate to deal with round-off error. */ if (nsp && (delta == 0.0)) { if (axis == x_axis) graph->viewport.width = spacing * nsp; else graph->viewport.height = spacing * nsp; } else if (!nsp) { nsp = 1; } /* have to save non-intuitive variables left over from old algorithms for redraws */ if (axis == x_axis) { graph->grid.xsized = 1; graph->grid.xaxis.lin.onedec = onedec; graph->grid.xaxis.lin.mult = mult; graph->grid.xaxis.lin.tenpowmag = tenpowmag2; graph->grid.xaxis.lin.tenpowmagx = tenpowmag; graph->grid.xaxis.lin.digits = digits; (void) strcpy(graph->grid.xaxis.lin.units, buf); graph->grid.xaxis.lin.distance = dst; graph->grid.xaxis.lin.lowlimit = lmt; graph->grid.xaxis.lin.highlimit = hmt; graph->grid.xaxis.lin.spacing = spacing; graph->grid.xaxis.lin.numspace = nsp; } else { graph->grid.ysized = 1; graph->grid.yaxis.lin.onedec = onedec; graph->grid.yaxis.lin.mult = mult; graph->grid.yaxis.lin.tenpowmag = tenpowmag2; graph->grid.yaxis.lin.tenpowmagx = tenpowmag; graph->grid.yaxis.lin.digits = digits; (void) strcpy(graph->grid.yaxis.lin.units, buf); graph->grid.yaxis.lin.distance = dst; graph->grid.yaxis.lin.lowlimit = lmt; graph->grid.yaxis.lin.highlimit = hmt; graph->grid.yaxis.lin.spacing = spacing; graph->grid.yaxis.lin.numspace = nsp; } return (dd);}staticdrawlingrid(graph, units, spacing, nsp, dst, lmt, hmt, onedec, mult, mag, digits, axis) GRAPH *graph; char *units; bool onedec; int nsp, spacing, mult; double hmt, lmt, dst; double mag; int digits; Axis axis;{ int i, j; double m, step; char buf[LABEL_CHARS]; /* i counts how many pixels we have drawn, and j counts which unit * we are at. */ SetLinestyle(1); step = floor((double) dst / nsp * 100.0 + 0.000001); for (i = 0, m = lmt * 100.0; m - 0.001 <= hmt * 100.0; i += spacing, m += step) { j = m; if (j == 0) SetLinestyle(0); 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 == 0) SetLinestyle(1); (void) sprintf(buf, "%.*f", digits + 1, m * mag / 100.0);#ifdef notdef if (floor(step/10.0) != step/10.0) (void) sprintf(buf, "%.*lf", mag, m * mag / 100.0); else if (floor(step/100.0) != step/100.0) (void) sprintf(buf, "%.1lf", m * mag / 100.0); else (void) sprintf(buf, "%lg", j * mag / 100);#endif 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. *//* 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 subs, pp, decsp, lmt, hmt; int i, j; double k; double decs; double mag, gain; 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);}staticdrawloggrid(graph, units, hmt, lmt, decsp, subs, pp, axis) GRAPH *graph; char *units; int hmt, lmt; int decsp, subs, pp; Axis axis;{ int i, j, k, l, 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 *graph;{ double d, mx, my, rad, tenpowmag; int hmt, lmt, mag; double minrad, maxrad, 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; } /* 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -