Ejemplo n.º 1
0
Archivo: graf.c Proyecto: 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;
    }
}
Ejemplo n.º 2
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;
}