View Raw SPL
/*****************************************************************************
*                                                                            *
*   XYPOLARPLOT.SPL  Copyright (C) 2014 DSP Development Corporation          *
*                               All Rights Reserved                          *
*                                                                            *
*   Author:       Randy Race                                                 *
*                                                                            *
*   Synopsis:     Polar plot with polar grids                                *
*                                                                            *
*   Revisions:     1 Jan 2014   RRR  Creation                                *
*                                                                            *
*****************************************************************************/

#if @HELP_XYPOLARPLOT

    XYPOLARPLOT

    Purpose: Plots polar data on a polar grid.

    Syntax:  XYPOLARPLOT(theta, r, color, lstyle, rmax, dtheta, dr, rmin, rtheta, roff)


               theta - A series, the angle data in radians.

                   r - A series, the radius data.

               color - Optional. An integer, the grid color. Defaults
                       to light grey (LGREY).

              lstyle - Optional. An integer, the grid line style. Defaults
                       to 2, dotted.

                rmax - Optional. A real, the maximum radius of the polar
                       grid. Defaults to -1, automatic.

              dtheta - Optional. A real, the angle in degrees between polar
                       grids lines. Defaults to 30 degrees.

                  dr - Optional. A real, the tic spacing along the labeled
                       radial grid. Defaults to -1, automatic.

                rmin - Optional. A real, the minimum radius of the polar
                       grid. Defaults to -1, automatic.

              rtheta - Optional. A real, the angle of the labeled radial grid
                       in degrees. Defaults to 0 degrees (i.e. horizontal).

                roff - Optional. A real, the offset of the first tic mark on
                       the labeled radial grid. Defaults to 0.

    Returns: An XY series in polar coordinates.

    Example:
             W1: 2*pi*((1..500)/500)
             W2: 4 * sin(3 * W1)
             W3: xypolarplot(w1, w2)

             Creates an XY polar plot in W3. The polar grid has a radius of 6,
             the angle increment is 30 degrees and the radius increment is 1.0.

    Example:
             W4: xypolarplot(w2, w1)

             Same as above except the angle and radius series are swapped.

    Example:
             W1: gsin(1000, 1/1000, 2)
             W2: gcos(1000, 1/1000, 3) + 2
             W3: xypolarplot(w1, w2)
             W4: xypolarplot(w1, w2, grey, 0, 4, 45, 0.5, 0, 75, 1.0)

             W3 and W4 display the same polar plot except W4
             specifies grey grids with solid lines and maximum radius
             of 4, the angle increment is 45 degrees, the radius
             increment is 0.5, the minimum radius is 0, the labeled
             radial line is at 75 degrees and the first radial tic
             begins at 1.0.

    Remarks:
             XYPOLARPLOT creates a simple polar plot given angle and radius
             data. Polar grids are drawn and sized to the data.

             A value of -1 for any optional argument specifies the default
             value.

             See POLARGRID for more details on polar coordinate grids.

    See Also:
             Linedraw
             Polargrid
             Xy
#endif


/* polar plot given theta, r, polar inputs */
xypolarplot(theta, r = -1, color = -1, lstyle = -1, rmax = -1, dtheta = -1, dr = -1, rmin = -1, rtheta = -1, roff = -1)
{
        local xyp, sot, prange, range;

        /* parse args */
        (theta, r, color, lstyle, rmax, dtheta, dr, rmin, rtheta, roff) = 
                xypolarplot_parse_args(theta, r, color, lstyle, rmax, dtheta, dr, rmin, rtheta, roff);

        /* defaults */
        if (color  < 0)  color  = lgrey;
        if (lstyle < 0)  lstyle = 2;
        if (dtheta < 0)  dtheta = 30;
        if (rmin   < 0)  rmin   = 0;
        if (rtheta < 0)  rtheta = 0;
        if (roff   < 0)  roff   = rmin;
        
        setdeltax(r, deltax(theta));
        
        /* polar transformation */
        xyp = xy((r - rmin) * cos(theta), (r - rmin) * sin(theta));

        if (not(ascale(w0)))
        {
                /* no coord manipulation if not autoscaling */
                return(xyp);
        }

        /* no plot */        
        plotmode(w0, 0);

        /* clear previous */
        clear(w0, 1, 0);

        setxauto(w0, -1, -1);
        setyauto(w0, -1, -1);
        setplotstyle(w0, 0);
        
        /* first stick range series to get good tics */
        {0, max(abs(r + rmin))}; 

        /* set xy plot scaling on tics for good tic values */
        sot = setconfig("scale_on_tics", 3);
        autoscale(w0);
        setconfig("scale_on_tics", sot);

        /* find tic interval and max range */
        dr     = (dr < 0)   ? ytic(w0)  : dr;
        prange = (rmax < 0) ? getyt(w0) : (rmax - rmin);
        
        if ((prange / dr) % 2 == 0 && dr > 100)
        {
                /* less tics */
                dr *= 2;
        }
        
        /* stick polar data in window */
        xyp;

        /* expand display range */
        range = 1.4 * prange;

        setx(w0,     -range, range);
        sety(w0,     -range, range);
        setxauto(w0, -range, range);
        setyauto(w0, -range, range);

        /* square aspect. no scales */
        setaspect(w0, 1);
        scales(w0, 0);
        
        /* polar plot grids */
        polargrid(prange, dtheta, dr, color, lstyle, rmin, rtheta, roff);

        /* redraw window */
        plotmode(w0, 1, 2);
}


/* input args */
xypolarplot_parse_args(theta, r, color, lstyle, rmax, dtheta, dr, rmin, rtheta, roff)
{
        if (isunspecified(theta) || not(isarray(theta)))
        {
                error(sprintf("%s - input radius and angle series required", __CALLER__));
        }

        if (isunspecified(r) || not(isarray(r)))
        {
                if (numcols(theta) == 2)
                {
                        r     = col(theta, 2);
                        theta = col(theta, 1);
                }
                else
                {
                        error(sprintf("%s - input radius and angle series required", __CALLER__));
                }
        }

        return(theta, r, color, lstyle, rmax, dtheta, dr, rmin, rtheta, roff);
}


/* error handler */
xypolarplot_error(errnum, errmes)
{
        plotmode(w0, 1);
        error(errmes);
}