//int //ft_findpoint(double pt, double *lims, int maxp, int minp, bool islog) int ft_findpoint(double pt, double *lims, int maxp, int minp, int islog) { double tl, th; if (pt < lims[0]) pt = lims[0]; if (pt > lims[1]) pt = lims[1]; if (islog) { tl = mylog10(lims[0]); th = mylog10(lims[1]); return (int)(((mylog10(pt) - tl) / (th - tl)) * (maxp - minp) + minp); } else { return (int)(((pt - lims[0]) / (lims[1] - lims[0])) * (maxp - minp) + minp); } }
int mylog10(int param) { if (param < 10) return 0; if (param < 100) return 1; if (param < 1000) return 2; if (param < 10000) return 3; if (param < 100000) return 4; if (param < 1000000) return 5; if (param < 10000000) return 6; if (param < 100000000) return 7; return mylog10(param / 10) + 1; }
/* 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); }
static void polargrid(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 void drawsmithgrid(GRAPH *graph) { double mx, my, tenpowmag, d, dphi[CMAX], minrad, maxrad, rnorm[CMAX]; double pixperunit; int mag, i = 0, j = 0, 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; } else if (i > 2) { j = 5; break; } } k = 1; /* SetLinestyle(1); takes too long */ /* Problems with Suns on very large radii && linestyle */ SetLinestyle(0); /* Now plot all the arc sets. Go as high as 5 times the radius that * will fit on the screen. The base magnitude is one more than * the least magnitude that will fit... */ if (i > 20) basemag = mag; else basemag = mag + 1; /* Go back one order of magnitude and have a closer look */ mag -= 2; j *= 10; while (mag < 20) { i = j * pow(10.0, (double) mag) * pixperunit / 2; if (i / 5 > gr_radius + ((xoff > 0) ? xoff : - xoff)) break; rnorm[k] = j * pow(10.0, (double) (mag - basemag)); dphi[k] = 2.0 * atan(rnorm[k]); ir[k] = pixperunit * (1 + cos(dphi[k])) / sin(dphi[k]); rr[k] = pixperunit * 0.5 * (((1 - rnorm[k]) / (1 + rnorm[k])) + 1); (void) sprintf(plab, "%g", rnorm[k]); plen = strlen(plab); /* See if the label will fit on the upper xaxis */ /* wait for some k, so we don't get fooled */ if (k > 6) { if ((int) (gr_radius - xoff - pixperunit + 2 * rr[k]) < plen * gi_fntwidth + 2) break; } /* See if the label will fit on the lower xaxis */ /* First look at the leftmost circle possible*/ if ((int) (pixperunit - 2 * rr[k] + gr_radius + xoff + fabs((double) yoff)) < plen * gi_fntwidth + 4) { if (j == 95) { j = 10; mag++; } else { if (j < 20) j += 1; else j += 5; } continue; } /* Then look at the circles following in the viewport */ if (k>1 && (int) 2 * (rr[k-1] - rr[k]) < plen * gi_fntwidth + 4) { if (j == 95) { j = 10; mag++; } else { if (j < 20) j += 1; else j += 5; } continue; } if (j == 95) { j = 10; mag++; } else { if (j < 20) j += 1; else j += 5; } ki[k-1] = ir[k]; kr[k-1] = rr[k]; k++; if (k == CMAX) { printf("drawsmithgrid: grid too complex\n"); break; } } k--; /* Now adjust the clipping radii */ for (i = 0; i < k; i++) ks[i] = ki[i]; for (i = k-1, j = k-1; i >= 0; i -= 2, j--) { ki[i] = ks[j]; if (i > 0) ki[i-1] = ks[j]; } for (i = 0; i < k; i++) ks[i] = kr[i]; for (i = k-1, j = k-1; (i >= 0) && (dphi[i] > M_PI / 2); i -= 2, j--) { kr[i] = ks[j]; if (i > 0) kr[i-1] = ks[j]; } for ( ; i >= 0; i--, j--) kr[i] = ks[j]; if ((yoff > - gr_radius) && (yoff < gr_radius)) { zheight = gr_radius * cos(asin((double) yoff / gr_radius)); zheight = (zheight > 0) ? zheight : - zheight; } else { zheight = gr_radius; } for (ki[k] = kr[k] = (double) 0; k > 0; k--) { (void) sprintf(plab, "%g", rnorm[k]); (void) sprintf(nlab, "-%g", rnorm[k]); arcset(graph, rr[k], kr[k], ir[k], ki[k], pixperunit, gr_radius, gr_xcenter, gr_ycenter, xoff, yoff, plab, nlab, (int) (0.5 + RAD_TO_DEG * (M_PI - dphi[k])), (int) (0.5 + RAD_TO_DEG * (M_PI + dphi[k])), gr_xcenter - zheight, gr_xcenter + zheight); } if (mag == 20) { fprintf(cp_err, "smithgrid: Internal Error: screwed up\n"); return; } SetLinestyle(0); Arc(gr_xcenter, gr_ycenter, gr_radius, 0.0, 0.0); /* if ((xoff > - gr_radius) && (xoff < gr_radius)) { zheight = gr_radius * sin(acos((double) xoff / gr_radius)); if (zheight < 0) zheight = - zheight; DrawLine(gr_xcenter + xoff, gr_ycenter - zheight, gr_xcenter + xoff, gr_ycenter + zheight); } */ if ((yoff > - gr_radius) && (yoff < gr_radius)) { zheight = gr_radius * cos(asin((double) yoff / gr_radius)); if (zheight < 0) zheight = - zheight; DrawLine(gr_xcenter - zheight, gr_ycenter + yoff, gr_xcenter + zheight, gr_ycenter + yoff); Text("0", gr_xcenter + zheight + gi_fntwidth, gr_ycenter + yoff - gi_fntheight / 2); Text("o", gr_xcenter + zheight + gi_fntwidth * 2, gr_ycenter + yoff); Text("180", gr_xcenter - zheight - gi_fntwidth * 5, gr_ycenter + yoff - gi_fntheight / 2); Text("o", gr_xcenter - zheight - gi_fntwidth * 2, gr_ycenter + yoff); } /* (void) sprintf(buf, "e%d", basemag); */ (void) sprintf(buf, "e%d", 0); Text(buf, gr_xcenter + gr_radius, gr_ycenter - gr_radius); Update(); return; }