Esempio n. 1
0
/* PN static */
void
drawlingrid(GRAPH *graph, char *units, int spacing, int nsp, double dst, double lmt, double hmt, bool onedec, int mult, 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);

	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();

}
Esempio n. 2
0
File: graf.c Progetto: imr/ngspice
/* PN  static */
void
drawlegend(GRAPH *graph, int plotno, struct dvec *dv)
{
    int x, y, i;
    char buf[16];

    x = ((plotno % 2) ? graph->viewportxoff :
         ((graph->viewport.width) / 2));
    y = graph->absolute.height - graph->fontheight
        - ((plotno + 2) / 2) * (graph->fontheight);
    i = y + graph->fontheight / 2 + 1;
    SetColor(dv->v_color);
    if (graph->plottype == PLOT_POINT) {
        (void) sprintf(buf, "%c : ", dv->v_linestyle);
        DevDrawText(buf, x + graph->viewport.width / 20
                    - 3 * graph->fontwidth, y, 0);
    } else {
        SetLinestyle(dv->v_linestyle);
        DevDrawLine(x, i, x + graph->viewport.width / 20, i);
    }
    SetColor(1);
    DevDrawText(dv->v_name, x + graph->viewport.width / 20
                + graph->fontwidth, y, 0);
}
Esempio n. 3
0
File: tick.c Progetto: PNCG/genesis
void
DrawXTicks(Graph *graph)
{
    int   sx1, sy1;
    int   sx2, sy2;
    int   i;
    float yint;
    float val;
    float scale;
    int   tmp;
    int   axisx;
    int   j;


    if (graph->xaxis_desired_nticks == 0)
    {
        graph->xaxis_nticks = 1;
        return;
    }

    /*
     * Get the screen coordinates of the axis.
     */

    SetColor(graph->foreground);
    yint = graph->xaxis_yintcpt;
    ScreenTransform(graph, graph->wxmin, yint, &sx1, &sy1);
    ScreenTransform(graph, graph->wxmax, yint, &sx2, &sy2);

    scale = 1.0 / pow((double) 10.0, (double) graph->xaxis_exponent);
    ScreenTransform(graph, graph->yaxis_xintcpt, 0.0, &axisx, &tmp);

    for (i = 0; i < graph->xaxis_nticks; i++)
    {
        for (j = 0; j < graph->xaxis_nsubticks + 1; j++)
        {
            val = i * graph->xaxis_tickinc + graph->xaxis_tickstart +
                j * graph->xaxis_tickinc / (graph->xaxis_nsubticks + 1);
            ScreenTransform(graph, val, graph->xaxis_yintcpt, &sx1, &sy1);

            /*
             * Either draw a grid or just tick marks at the tick intervals.
             */

            if (graph->show_xgrid)
            {
                SetColor(graph->gridcolor);
                SetLinestyle((BasicWindow *)graph, 1);
                DrawLine(sx1, 0, sx1, graph->wheight);
                SetLinestyle((BasicWindow *)graph, 0);
                SetColor(graph->foreground);
            }

            if (!(graph->quadrants & 0x1) && !(graph->quadrants & 0x4))
                continue;

            /*
             * Check for quadrants I.
             */

            if (!(graph->quadrants & 0x1) && sx1 > axisx)
                continue;

            /*
             * Check for quadrants III.
             */

            if (!(graph->quadrants & 0x4) && sx1 < axisx)
                continue;

            if (j == 0)
            {
                DrawLine(sx1, sy1 - graph->ticksize, sx1,
                         sy2 + graph->ticksize);

                /*
                 * label the ticks
                 */

                if (graph->show_xlabels)
                {
                    DrawXTickLabel(graph, sx1, sy1,
                                   val, scale,
                                   graph->xaxis_leftdp, graph->xaxis_rightdp);
                }
            }
            else
            {
                DrawLine(sx1, sy1 - (int) (0.5 * graph->ticksize), sx1,
                         sy2 + (int) (0.5 * graph->ticksize));
            }
        }
    }
}
Esempio n. 4
0
File: tick.c Progetto: PNCG/genesis
void
DrawYTicks(Graph *graph)
{
    int   sx1, sy1;
    int   sx2, sy2;
    int   i;
    float xint;
    float val;
    float scale;
    int   tmp;
    int   axisy;
    int   j;

    if (graph->yaxis_desired_nticks == 0)
    {
        graph->yaxis_nticks = 1;
        return;
    }

    /*
     * Get the screen coordinates of the axis.
     */

    SetColor(graph->foreground);
    xint = graph->yaxis_xintcpt;
    ScreenTransform(graph, xint, graph->wymin, &sx1, &sy1);
    ScreenTransform(graph, xint, graph->wymax, &sx2, &sy2);

    /*
     * Get the axis exponent.
     */

    scale = 1.0 / pow((double) 10.0, (double) graph->yaxis_exponent);
    ScreenTransform(graph, 0.0, graph->xaxis_yintcpt, &tmp, &axisy);

    /*
     * Loop over all the tick marks.
     */

    for (i = 0; i < graph->yaxis_nticks; i++)
    {
        for (j = 0; j < graph->yaxis_nsubticks + 1; j++)
        {
            /*
             * Get the actual value of the tick.
             */

            val = i * graph->yaxis_tickinc +
                graph->yaxis_tickstart +
                j * graph->yaxis_tickinc / (graph->yaxis_nsubticks + 1);

            /*
             * Locate its screen position in the window.
             */

            ScreenTransform(graph, graph->yaxis_xintcpt, val, &sx1, &sy1);

            /*
             * Either draw a grid or just tick marks at the tick intervals.
             */

            if (graph->show_ygrid)
            {
                SetColor(graph->gridcolor);
                SetLinestyle((BasicWindow *)graph, 1);
                DrawLine(0, sy1, graph->wwidth, sy1);
                SetLinestyle((BasicWindow *)graph, 0);
                SetColor(graph->foreground);
            }

            if (!(graph->quadrants & 0x2) && !(graph->quadrants & 0x8))
                continue;

            /*
             * Check for quadrants II.
             */

            if (!(graph->quadrants & 0x2) && sy1 < axisy)
                continue;

            /*
             * Check for quadrants IV.
             */

            if (!(graph->quadrants & 0x8) && sy1 > axisy)
                continue;

            if (j == 0)
            {
                DrawLine(sx1 - graph->ticksize, sy1,
                         sx2 + graph->ticksize, sy1);

                /*
                 * Label the ticks.
                 */

                if (graph->show_ylabels)
                {
                    DrawYTickLabel(graph, sx1, sy1,
                                   val, scale,
                                   graph->yaxis_leftdp, graph->yaxis_rightdp);
                }
            }
            else
            {
                DrawLine(sx1 - (int) (0.5 * graph->ticksize), sy1,
                         sx2 + (int) (0.5 * graph->ticksize), sy1);
            }
        }
    }
}
Esempio n. 5
0
File: graf.c Progetto: imr/ngspice
/*
 *  Add a point to the curve we're currently drawing.
 *  Should be in between a gr_init() and a gr_end()
 *    expect when iplotting, very bad hack
 *  Differences from old gr_point:
 *    We save points here, instead of in lower levels.
 *    Assume we are in right context
 *  Save points in data space (not screen space).
 *  We pass two points in so we can multiplex plots.
 *
 */
void
gr_point(struct dvec *dv,
         double newx, double newy,
         double oldx, double oldy,
         int np)
{
    int oldtox, oldtoy;     /* value before clipping */

    char pointc[2];

    int fromx, fromy, tox, toy;
    int ymin, dummy;

    DatatoScreen(currentgraph, oldx, oldy, &fromx, &fromy);
    DatatoScreen(currentgraph, newx, newy, &tox, &toy);

    /* note: we do not particularly want to clip here */
    oldtox = tox; oldtoy = toy;
    if (!currentgraph->grid.circular) {
        if (clip_line(&fromx, &fromy, &tox, &toy,
                      currentgraph->viewportxoff, currentgraph->viewportyoff,
                      currentgraph->viewport.width + currentgraph->viewportxoff,
                      currentgraph->viewport.height + currentgraph->viewportyoff))
            return;
    } else {
        if (clip_to_circle(&fromx, &fromy, &tox, &toy,
                           currentgraph->grid.xaxis.circular.center,
                           currentgraph->grid.yaxis.circular.center,
                           currentgraph->grid.xaxis.circular.radius))
            return;
    }

    if (currentgraph->plottype != PLOT_POINT) {
        SetLinestyle(dv->v_linestyle);
    } else {
        /* if PLOT_POINT,
           don't want to plot an endpoint which have been clipped */
        if (tox != oldtox || toy != oldtoy)
            return;
    }
    SetColor(dv->v_color);

    switch (currentgraph->plottype) {
        double    *tics;
    case PLOT_LIN:
    case PLOT_MONOLIN:
        /* If it's a linear plot, ignore first point since we don't
           want to connect with oldx and oldy. */
        if (np)
            DevDrawLine(fromx, fromy, tox, toy);
        if ((tics = currentgraph->ticdata) != NULL) {
            for (; *tics < HUGE; tics++)
                if (*tics == (double) np) {
                    DevDrawText("x", (int) (tox - currentgraph->fontwidth / 2),
                                (int) (toy - currentgraph->fontheight / 2), 0);
                    /* gr_redraw will redraw this w/o our having to save it
                       Guenther Roehrich 22-Jan-99 */
                    /*    SaveText(currentgraph, "x",
                          (int) (tox - currentgraph->fontwidth / 2),
                          (int) (toy - currentgraph->fontheight / 2)); */
                    break;
                }
        } else if ((currentgraph->ticmarks >0) && (np > 0) &&
                   (np % currentgraph->ticmarks == 0))
        {
            /* Draw an 'x' */
            DevDrawText("x", (int) (tox - currentgraph->fontwidth / 2),
                        (int) (toy - currentgraph->fontheight / 2), 0);
            /* gr_redraw will redraw this w/o our having to save it
               Guenther Roehrich 22-Jan-99 */
            /*  SaveText(currentgraph, "x",
                (int) (tox - currentgraph->fontwidth / 2),
                (int) (toy - currentgraph->fontheight / 2)); */
        }
        break;
    case PLOT_COMB:
        DatatoScreen(currentgraph,
                     0.0, currentgraph->datawindow.ymin,
                     &dummy, &ymin);
        DevDrawLine(tox, ymin, tox, toy);
        break;
    case PLOT_POINT:
        /* Here, gi_linestyle is the character used for the point.  */
        pointc[0] = (char) dv->v_linestyle;
        pointc[1] = '\0';
        DevDrawText(pointc, (int) (tox - currentgraph->fontwidth / 2),
                    (int) (toy - currentgraph->fontheight / 2), 0);
    default:
        break;
    }
}
Esempio n. 6
0
static void
drawpolargrid(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;
}
Esempio n. 7
0
/* PN static */
void
drawloggrid(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();
}
Esempio n. 8
0
void
gr_fixgrid(GRAPH *graph, double xdelta, double ydelta, int xtype, int ytype)
{
    double *dd;

    if (graph->grid.gridtype == GRID_NONE) {
        graph->grid.gridtype = GRID_LIN;
    }

    SetColor(1);
    SetLinestyle(1);

    if ((graph->data.xmin > graph->data.xmax)
            || (graph->data.ymin > graph->data.ymax)) {
      fprintf(cp_err, 
        "gr_fixgrid: Internal Error - bad limits: %g, %g, %g, %g\r\n",
        graph->data.xmin, graph->data.xmax, 
        graph->data.ymin, graph->data.ymax);
      return;
    }

    if (graph->grid.gridtype == GRID_POLAR) {
        graph->grid.circular = TRUE;
        polargrid(graph);
        return;
    } else if (graph->grid.gridtype == GRID_SMITH
        || graph->grid.gridtype == GRID_SMITHGRID)
    {
        graph->grid.circular = TRUE;
        smithgrid(graph);
        return;
    }
    graph->grid.circular = FALSE;

    if ((graph->grid.gridtype == GRID_YLOG)
            || (graph->grid.gridtype == GRID_LOGLOG))
        dd = loggrid(graph, graph->data.ymin, graph->data.ymax,
                ytype, y_axis);
    else
        dd = lingrid(graph, graph->data.ymin, graph->data.ymax,
                ydelta, ytype, y_axis);

    graph->datawindow.ymin = dd[0];
    graph->datawindow.ymax = dd[1];

    if ((graph->grid.gridtype == GRID_XLOG)
            || (graph->grid.gridtype == GRID_LOGLOG))
        dd = loggrid(graph, graph->data.xmin, graph->data.xmax,
                xtype, x_axis);
    else
        dd = lingrid(graph, graph->data.xmin, graph->data.xmax,
                xdelta, xtype, x_axis);

    graph->datawindow.xmin = dd[0];
    graph->datawindow.xmax = dd[1];

/* do we really need this? */
/*
    SetLinestyle(0);
    DrawLine(graph->viewportxoff, graph->viewportyoff,
            graph->viewport.width + graph->viewportxoff,
            graph->viewportyoff);
    DrawLine(graph->viewportxoff, graph->viewportyoff,
            graph->viewportxoff,
            graph->viewport.height + graph->viewportyoff);
    SetLinestyle(1);
*/

    return;
}
Esempio n. 9
0
void
gr_redrawgrid(GRAPH *graph)
{

    SetColor(1);
    SetLinestyle(1);
    /* draw labels */
    if (graph->grid.xlabel) {
      Text(graph->grid.xlabel,
          (int) (graph->absolute.width * 0.35),
          graph->fontheight);
    }
    if (graph->grid.ylabel) {
    	  if (graph->grid.gridtype == GRID_POLAR 
    	          || graph->grid.gridtype == GRID_SMITH
    	          || graph->grid.gridtype == GRID_SMITHGRID) {
              Text(graph->grid.ylabel,
                   graph->fontwidth,
		   (graph->absolute.height * 3) / 4 );
	  } else {
              Text(graph->grid.ylabel,
                   graph->fontwidth,
		   graph->absolute.height / 2 );
	  }
    }

    switch( graph->grid.gridtype ) {
	case GRID_POLAR:
        	drawpolargrid(graph);
		break;
	case GRID_SMITH:
        	drawsmithgrid(graph);
		break;
	case GRID_SMITHGRID:
        	drawsmithgrid(graph);
		break;
		

    	case GRID_XLOG:
        case GRID_LOGLOG:
        	drawloggrid(graph,
               		graph->grid.xaxis.log.units,
			graph->grid.xaxis.log.hmt,
               		graph->grid.xaxis.log.lmt,
                	graph->grid.xaxis.log.decsp,
                	graph->grid.xaxis.log.subs,
                	graph->grid.xaxis.log.pp, x_axis);
		break;
	default:
        	drawlingrid(graph,
               		graph->grid.xaxis.lin.units,
               		graph->grid.xaxis.lin.spacing,
               		graph->grid.xaxis.lin.numspace,
               		graph->grid.xaxis.lin.distance,
               		graph->grid.xaxis.lin.lowlimit,
               		graph->grid.xaxis.lin.highlimit,
               		graph->grid.xaxis.lin.onedec,
               		graph->grid.xaxis.lin.mult,
               		graph->grid.xaxis.lin.tenpowmag
               		/ graph->grid.xaxis.lin.tenpowmagx,
               		graph->grid.xaxis.lin.digits,
               		x_axis);
		break;
     }

    switch( graph->grid.gridtype ) {
	case GRID_POLAR:
	case GRID_SMITH:
	case GRID_SMITHGRID:
		break;

    	case GRID_YLOG:
        case GRID_LOGLOG:
        	drawloggrid(graph,
                	graph->grid.yaxis.log.units,
			graph->grid.yaxis.log.hmt,
                	graph->grid.yaxis.log.lmt,
                	graph->grid.yaxis.log.decsp,
                	graph->grid.yaxis.log.subs,
                	graph->grid.yaxis.log.pp, y_axis);
		break;
	default:
        	drawlingrid(graph,
                	graph->grid.yaxis.lin.units,
                	graph->grid.yaxis.lin.spacing,
                	graph->grid.yaxis.lin.numspace,
                	graph->grid.yaxis.lin.distance,
                	graph->grid.yaxis.lin.lowlimit,
                	graph->grid.yaxis.lin.highlimit,
                	graph->grid.yaxis.lin.onedec,
                	graph->grid.yaxis.lin.mult,
               		graph->grid.yaxis.lin.tenpowmag
               		/ graph->grid.yaxis.lin.tenpowmagx,
               		graph->grid.yaxis.lin.digits,
                	y_axis);
		break;
     }

}
Esempio n. 10
0
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;
}
Esempio n. 11
0
static void
smithgrid(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;

    /* 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");
    }

}