 /*
  * Khoros: $Id: axes3.c,v 1.2 1992/03/20 22:45:44 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: axes3.c,v 1.2 1992/03/20 22:45:44 dkhoros Exp $";
#endif

 /*
  * $Log: axes3.c,v $
 * Revision 1.2  1992/03/20  22:45:44  dkhoros
 * VirtualPatch5
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 *
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *---------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "xprism.h"


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: axes3.c
   >>>>               
   >>>>   description: routines to setup the axes for drawing 
   >>>>              
   >>>>      routines:
   >>>>			draw_axis_xp3
   >>>>			draw_axis_3D
   >>>>			xtics_xp3
   >>>>			ytics_xp3
   >>>>			ztics_xp3
   >>>>			axis_is_obscured
   >>>>              
   >>>> modifications:
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */

#define GENERAL	     0
#define Y_AXIS_LINE  1
#define OPP_Y_AXIS   2


/************************************************************
*
*  MODULE NAME: draw_axis_xp3
*
*      PURPOSE: draws axes on 3D plot; adds tics, numbers, labels
*
*        INPUT: gwin - pointer to the VPGraphicsWindow structure
*
*       OUTPUT: none
*
*    CALLED BY: plot_routine
*
*   WRITTEN BY: Danielle Argiro & Mike Lang
*
*
*************************************************************/

draw_axis_xp3(plot_type, do_obscure)
int plot_type, do_obscure;
{

	Coord    axes[3], center;
	int      tics(), axis_obscured;
        char 	 *xaxis_label = NULL;
	char   	 *yaxis_label = NULL;
	char	 *zaxis_label = NULL;
        char	 *add_power_axis_label();


        if (gwin_attr->draw_axes)
	   draw_axis_3D(do_obscure);

	center.x = ((gwin_attr->disp_scale_max.x - gwin_attr->disp_scale_min.x)
			/ 2.0 + gwin_attr->disp_scale_min.x);
	center.y = ((gwin_attr->disp_scale_max.y - gwin_attr->disp_scale_min.y)
			/ 2.0 + gwin_attr->disp_scale_min.y);
	center.z = ((gwin_attr->disp_scale_max.z - gwin_attr->disp_scale_min.z)
			/ 2.0 + gwin_attr->disp_scale_min.z);

	/*
	*  checking to see if the X Axis is obscured and if we want
	*  to obscure it (or if its not obscured and we *dont* want to 
	*  obscure it) and draw the axis
	*/
	axes[0].x = gwin_attr->disp_scale_min.x; 
	axes[1].x = gwin_attr->disp_scale_max.x;
	axes[0].y = axes[1].y = gwin_attr->disp_scale_min.y;
	axes[0].z = axes[1].z = gwin_attr->disp_scale_min.z;
	axis_obscured = axis_is_obscured(gwin->id, center, axes[0], axes[1], 
				    GENERAL);
	if (axis_obscured == do_obscure)
	{
	   xtics_xp3(gwin->plot_type);
                   /* print out X Axis title */
	   if (! gwin_attr->clear_labels)
           {
	       if (gwin_attr->draw_numlabels)
                  xaxis_label = add_power_axis_label(gwin_attr->xaxis,
                                           (int) gwin_attr->power_ten.x);
	       else
		  xaxis_label = VStrcpy(gwin_attr->xaxis);
	
	       write_label(gwin->plot_type,XAXIS, xaxis_label,
		        gwin_attr->current_colors[XTITLE_COLOR]);
	       if (xaxis_label != NULL)
		  free(xaxis_label);
           }
	}

	/*
	*  checking to see if the Z Axis is obscured and if we want
	*  to obscure it (or if its not obscured and we *dont* want to 
	*  obscure it) and draw the axis
	*/
	axes[0].x = axes[1].x = gwin_attr->disp_scale_min.x;
	axes[0].y = axes[1].y = gwin_attr->disp_scale_min.y; 
	axes[0].z = gwin_attr->disp_scale_min.z; 
	axes[1].z = gwin_attr->disp_scale_max.z;
	axis_obscured = axis_is_obscured(gwin->id, center, axes[0], axes[1], 
				    GENERAL);
	if (axis_obscured == do_obscure)
	{
	    ztics_xp3(gwin->plot_type);
	    if (! gwin_attr->clear_labels)
	    {
	       if (gwin_attr->draw_numlabels)
                  zaxis_label = add_power_axis_label(gwin_attr->zaxis,
                                           (int) gwin_attr->power_ten.z);
	       else
		  zaxis_label = VStrcpy(gwin_attr->zaxis);
	       write_label(gwin->plot_type,ZAXIS, zaxis_label, 
		     gwin_attr->current_colors[ZTITLE_COLOR]);
	       if (zaxis_label != NULL)
		  free(zaxis_label);
	    }
	}

	/*
	*  checking to see if the Y Axis is obscured and if we want
	*  to obscure it (or if its not obscured and we *dont* want to
	*  obscure it) and draw the axis
	*/
	axes[0].x = axes[1].x = gwin_attr->disp_scale_max.x;
	axes[0].y = gwin_attr->disp_scale_min.y; 
	axes[1].y = gwin_attr->disp_scale_max.y;
	axes[0].z = axes[1].z = gwin_attr->disp_scale_min.z;
	axis_obscured = axis_is_obscured(gwin->id, center, axes[0], axes[1], 
				    Y_AXIS_LINE);
	if (axis_obscured == do_obscure)
	{
	    ytics_xp3(gwin->plot_type);
	    if (! gwin_attr->clear_labels)
            {
	       if (gwin_attr->draw_numlabels)
                   yaxis_label = add_power_axis_label(gwin_attr->yaxis,
                                           (int) gwin_attr->power_ten.y);
	       else
		  yaxis_label = VStrcpy(gwin_attr->yaxis);
	         write_label(gwin->plot_type,YAXIS, yaxis_label, 
		        gwin_attr->current_colors[YTITLE_COLOR]);
	       if (yaxis_label != NULL)
		  free(yaxis_label);
            }
	}
	/* always print out the plot title */
	if (! gwin_attr->clear_labels)
	   write_label(gwin->plot_type,TITLE, gwin_attr->title, 
		       gwin_attr->current_colors[TITLE_COLOR]);

}



/************************************************************
*
*  MODULE NAME: draw_axis_3D
*
*      PURPOSE: draws axes on plot; adds tics, numbers, labels
*
*        INPUT: gwin - pointer to the VPGraphicsWindow structure
*		do_obscure - flag TRUE if looking for axes to draw
*		which will be obscured.  False if not.
*
*       OUTPUT: none
*
*
*   WRITTEN BY: Danielle Argiro
*
*
*************************************************************/


draw_axis_3D(do_obscure)

int    do_obscure;
{
	Coord    axes[2], center, min, max;
	int      tics(), colorindex, axis_obscured;

	center.x = ((gwin_attr->disp_scale_max.x - gwin_attr->disp_scale_min.x)
			/2.0 + gwin_attr->disp_scale_min.x);
	center.y = ((gwin_attr->disp_scale_max.y - gwin_attr->disp_scale_min.y)				/2.0 + gwin_attr->disp_scale_min.y);
	center.z = ((gwin_attr->disp_scale_max.z - gwin_attr->disp_scale_min.z)				/2.0 + gwin_attr->disp_scale_min.z);

	/* make the axes is as long as the tics (account for round up)*/
	max.x = gwin_attr->disp_scale_max.x;
	max.y = gwin_attr->disp_scale_max.y;
	max.z = gwin_attr->disp_scale_max.z;
	min.x = gwin_attr->disp_scale_min.x;
	min.y = gwin_attr->disp_scale_min.y;
	min.z = gwin_attr->disp_scale_min.z;

	/*
	 *  checking to see if the X Axis is obscured and if we want
	 *  to obscure it (or if its not obscured and we *dont* want to 
	 *  obscure it) and draw the axis
	 */
	axes[0].x = min.x; 
	axes[1].x = max.x;
	axes[0].y = axes[1].y = min.y;
	axes[0].z = axes[1].z = min.z;
	axis_obscured = axis_is_obscured(gwin->id, center, axes[0], axes[1], 
					 GENERAL);
        if (axis_obscured == do_obscure)
	{
	   /* set x axis color */
	   colorindex = gwin_attr->current_colors[XAXIS_COLOR];
	   if (xp_device != xpX11)
               X3D_set_line_width(gwin->id, ExtraWide);
	   X3D_draw_polyline(gwin->id, axes, 2, &Colors[colorindex]);
	 }

	/*
	 *  checking to see if the Z Axis is obscured and if we want
	 *  to obscure it (or if its not obscured and we *dont* want to 
	 *  obscure it) and draw the axis
	 */
	axes[0].x = axes[1].x = min.x;
	axes[0].y = axes[1].y = min.y; 
        axes[0].z = min.z; 
	axes[1].z = max.z;
	axis_obscured = axis_is_obscured(gwin->id, center, axes[0], axes[1], 
					 GENERAL);
        if (axis_obscured == do_obscure)
	{
	   /* set Z axis color */
	   colorindex = gwin_attr->current_colors[ZAXIS_COLOR];
	   if (xp_device != xpX11)
               X3D_set_line_width(gwin->id, ExtraWide); 
	   X3D_draw_polyline(gwin->id, axes, 2, &Colors[colorindex]);
	}


	/*
	 *  checking to see if the Y Axis is obscured and if we want
	 *  to obscure it (or if its not obscured and we *dont* want to 
	 *  obscure it) and draw the axis
	 */
	axes[0].x = axes[1].x = max.x; 
	axes[0].y = min.y; 
	axes[1].y = max.y; 
        axes[0].z = axes[1].z = min.z;
	axis_obscured = axis_is_obscured(gwin->id, center, axes[0], axes[1], 
					 Y_AXIS_LINE);
        if (axis_obscured == do_obscure)
	{
	   /* set Y axis color */
	   colorindex = gwin_attr->current_colors[YAXIS_COLOR];
	   if (xp_device != xpX11)
               X3D_set_line_width(gwin->id, ExtraWide); 
	   X3D_draw_polyline(gwin->id, axes, 2, &Colors[colorindex]);
	}

	/* back of X/Y plane - see above */
 	axes[0].x = min.x; 
	axes[1].x = max.x;
	axes[0].y = axes[1].y = max.y; 
	axes[0].z = axes[1].z = min.z;

	
	axis_obscured = axis_is_obscured(gwin->id,center,axes[0],axes[1],
					 GENERAL);
        if(axis_obscured == do_obscure)
	{
	   colorindex = gwin_attr->current_colors[XAXIS_COLOR];
	   if (xp_device != xpX11)
               X3D_set_line_width(gwin->id, ExtraWide);   
           X3D_draw_polyline(gwin->id, axes, 2, &Colors[colorindex]); 
	}

	/* side of X/Y plane - see above */
	axes[0].x = axes[1].x = min.x; 
	axes[0].y = min.y; 
	axes[1].y = max.y;
	axes[0].z = axes[1].z = min.z;

	axis_obscured = axis_is_obscured(gwin->id, center, 
					 axes[0], axes[1], OPP_Y_AXIS);
        if (axis_obscured == do_obscure)
	{
	     colorindex = gwin_attr->current_colors[YAXIS_COLOR];
	     if (xp_device != xpX11)
                 X3D_set_line_width(gwin->id, ExtraWide); 
             X3D_draw_polyline(gwin->id, axes, 2, &Colors[colorindex]); 
	}
}



/************************************************************
*
*  MODULE NAME: xtics_xp3
*
*      PURPOSE: draws tics, numbers on plots;
*
*        INPUT: gwin - pointer to the VPGraphicsWindow structure
*
*       OUTPUT: none
*
*    CALLED BY: draw_axes_3D
*
*   WRITTEN BY: Danielle Argiro & Mike Lang
*
*
*************************************************************/

xtics_xp3(plot_type)
int plot_type;
{
	Vector direction;
	Coord  *tic_lines, *text_coords;
	char tmp_str[100],scale[10];
	caddr_t *axes;
	float width, height, depth = 0;
	double x, minor_x;
	float tic_size, half_tic, minor_half_tic, half_tic2;
	char *get_axis_scale();
	double multiplier, last_tic_label, new_minor_tic_intv = 0.0;
	int  num_tics, j=0, i=0, num_minor_tics=0, colorindex;
	int  characters_displayed,decimal_places,power_ten;
        int need_end = 0, num_new_minor_tics = 0; 
	int last_major_tic, last_characters_displayed, new_index;
	int xprecision_err = False, index;

	direction.x = 1.0;
	direction.y = 0.0;
	direction.z = 0.0;

        if (gwin_attr->rescale_relabel == RELABEL)
            X3D_set_wc_min_max (gwin->id, gwin_attr->disp_label_min, 
                                          gwin_attr->disp_label_max);

	num_tics = (int)(gwin_attr->disp_label_num_tics.x);
	tic_size = 20.0;
	
	half_tic = (gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                   / tic_size;
	minor_half_tic = 0.5 * half_tic;

	/* set the width and height of characters */
	width = (gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                / (1.5 * tic_size);
	height = (gwin_attr->disp_label_max.z - gwin_attr->disp_label_min.z)
                / (1.5 * tic_size);  
	depth = (gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                / (1.5 * tic_size);  
	
	characters_displayed = (int)
	((((gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)/width)
            / gwin_attr->disp_label_num_tics.x) - 2);

	if(characters_displayed > 6) characters_displayed = 6;

	find_scale_factor(characters_displayed,
                          (double)gwin_attr->disp_label_max.x,
		          (double)gwin_attr->disp_label_min.x,
                          (double)gwin_attr->disp_label_major_intv.x,
		          &decimal_places,&multiplier,&power_ten);
            
        gwin_attr->power_ten.x = (float) power_ten;

	if ((characters_displayed >= 3) ||
		(characters_displayed >= 2 && decimal_places == 0))
	{
	   sprintf(scale,"%%.%df",decimal_places);
	}
   	else 	/* too many tics so we only draw first and last label */
   	{
	    /* compute a new interval since we only want to
             * label the first and laast points,
             * so, we say we have an 2 tics
             */
	   characters_displayed = (int)
                       ((((gwin_attr->disp_label_max.x - 
			   gwin_attr->disp_label_min.x)/width)
            			/ 2.0) - 2.0);

           if(characters_displayed > 6) characters_displayed = 6;

           find_scale_factor(characters_displayed,
                          (double)gwin_attr->disp_label_max.x,
                          (double)gwin_attr->disp_label_min.x,
                          (double)gwin_attr->disp_label_major_intv.x,
                          &decimal_places,&multiplier,&power_ten);

           gwin_attr->power_ten.x = (float) power_ten;
	   sprintf(scale,"%%.%df",decimal_places);
       	   xprecision_err = TRUE;
   	}


         /* set up for the last tic mark, we want to label the end point
          * on the axis. so must figure out how to do it
          */

	last_tic_label = (double)gwin_attr->disp_label_min.x + 
                       (((double) num_tics - 1.0) 
                       * (double)gwin_attr->disp_label_major_intv.x);
        
        if ( last_tic_label != (double)gwin_attr->disp_label_max.x)
        {
            need_end = True;
   
            last_major_tic = (int) (num_tics - 1.0);

             /* calculate the number of minor tics we need to add */

            x = gwin_attr->disp_label_max.x - last_tic_label;
            new_minor_tic_intv = ((double) gwin_attr->disp_label_major_intv.x / 
                           (double) ((int) (gwin_attr->minor_tics.x +0.5 + 1)));
	    if (new_minor_tic_intv == 0.0)
	        num_new_minor_tics = 0;
	    else
                num_new_minor_tics = (int) 
                      (((double)gwin_attr->disp_label_max.x - last_tic_label) / 
                         new_minor_tic_intv);
        }


	if (gwin_attr->minor_tics.x > 0)
	{
	   num_minor_tics += (int) ((num_tics - 1) * gwin_attr->minor_tics.x);
	}

	/* malloc memory for the coords and the labels
         * add the +1 to the malloc in case we need
         * room for the end point, if we dont need room
         * then we malloced and extra point. 
         */

	tic_lines =  (Coord *)malloc((unsigned)
		      (sizeof(Coord) * 2 * ( num_new_minor_tics + 
                       num_minor_tics + (num_tics + 1))));
	text_coords = (Coord *) malloc((unsigned) 
                      (sizeof(Coord) * (num_tics + 1)));
	axes = (caddr_t *)(malloc((unsigned)
                      (sizeof(caddr_t) * (num_tics + 1))));

	half_tic2 = (3.0 * half_tic);

	/* load the coords for the axes and print the number
	 * strings into an array.
	 */
	x = (double)gwin_attr->disp_label_min.x;
	if (! xprecision_err)
	{
	   for(i=0;i<num_tics;i++)
	   {
	      bzero(tmp_str,100);
	      (void) sprintf(tmp_str, scale, x * multiplier);
	      axes[i] = (caddr_t)VStrcpy(tmp_str);
	      text_coords[i].x = (float)x;
	      text_coords[i].y = gwin_attr->disp_label_min.y - half_tic2;
	      text_coords[i].z = gwin_attr->disp_label_min.z;
   
	      x += (double)gwin_attr->disp_label_major_intv.x;
           }
 
           if (need_end) 
           {
              bzero(tmp_str,100);
              (void) sprintf(tmp_str, scale, 
                             (double) gwin_attr->disp_label_max.x * multiplier);
              axes[i] = (caddr_t)VStrcpy(tmp_str);
              text_coords[i].x = (float) gwin_attr->disp_label_max.x;
              text_coords[i].y = gwin_attr->disp_label_min.y - half_tic2;
              text_coords[i].z = gwin_attr->disp_label_min.z;
           }
	}
	else
	{
            bzero(tmp_str,100);
            (void) sprintf(tmp_str, scale, x * multiplier);
            axes[0] = (caddr_t)VStrcpy(tmp_str);
            text_coords[0].x = (float)x;
            text_coords[0].y = gwin_attr->disp_label_min.y - half_tic2;
            text_coords[0].z = gwin_attr->disp_label_min.z;
	      
	    if(need_end)
		index = num_tics;
	    else
		index = num_tics - 1;

	    x = (double)gwin_attr->disp_label_max.x;
            bzero(tmp_str,100);
            (void) sprintf(tmp_str, scale, x * multiplier);
            axes[index] = (caddr_t)VStrcpy(tmp_str);
            text_coords[index].x = (float)x;
            text_coords[index].y = gwin_attr->disp_label_min.y - half_tic2;
            text_coords[index].z = gwin_attr->disp_label_min.z;
	
	    x = (double)gwin_attr->disp_label_major_intv.x +
		     (double)gwin_attr->disp_label_min.x;

	    bzero(scale,10);
            for(i=1;i<index;i++)
            {
               bzero(tmp_str,100);
               (void) sprintf(tmp_str, scale, x * multiplier);
               axes[i] = (caddr_t)VStrcpy(tmp_str);
               text_coords[i].x = (float)x;
               text_coords[i].y = gwin_attr->disp_label_min.y - half_tic2;
               text_coords[i].z = gwin_attr->disp_label_min.z;

               x += (double)gwin_attr->disp_label_major_intv.x;
            }
	}
	/* load the coords for the major and minor tics */

	x = (double)gwin_attr->disp_label_min.x;
	for(i=0; i < 2*(num_tics+num_minor_tics);)
	{
	   tic_lines[i].x = (float)x;
	   tic_lines[i].y = gwin_attr->disp_label_min.y;
	   tic_lines[i++].z = gwin_attr->disp_label_min.z;

	   tic_lines[i].x = (float)x;
	   tic_lines[i].y = gwin_attr->disp_label_min.y - half_tic;
	   tic_lines[i++].z = gwin_attr->disp_label_min.z;

	   if(gwin_attr->minor_tics.x > 0 && i < 2*(num_tics+num_minor_tics))
	   {
		minor_x = x;
		/* load in the minor tics (note I have to round up 
		 * because minor_tics is a Coord float)
		 */
		for(j=0;j<(int)(gwin_attr->minor_tics.x + 0.5);j++)
		{
		   minor_x += (double) (gwin_attr->disp_label_major_intv.x
					/ (gwin_attr->minor_tics.x + 1));

		   tic_lines[i].x = (float)minor_x;
		   tic_lines[i].y = gwin_attr->disp_label_min.y-minor_half_tic;
		   tic_lines[i++].z = gwin_attr->disp_label_min.z;

		   tic_lines[i].x = (float)minor_x;
		   tic_lines[i].y = gwin_attr->disp_label_min.y;
		   tic_lines[i++].z = gwin_attr->disp_label_min.z;
		}
	   }
	   x += (double)gwin_attr->disp_label_major_intv.x;
        }

           /* if the end point needs to be taken care of. for the
            * major tic and the minopr tics, we do it here.
            */

        if (need_end) 
        {
             /* Need to add the major tic line for the maximum value
              * on the axis
              */

	   tic_lines[i].x = (float) gwin_attr->disp_label_max.x;
	   tic_lines[i].y = gwin_attr->disp_label_min.y;
	   tic_lines[i++].z = gwin_attr->disp_label_min.z;

	   tic_lines[i].x = (float) gwin_attr->disp_label_max.x;
	   tic_lines[i].y = gwin_attr->disp_label_min.y - half_tic;
	   tic_lines[i++].z = gwin_attr->disp_label_min.z;
           num_tics++;
  
           /* need to add the minor tics in between the last 
            * major interval tic and the maximum tic
            */
  
           for ( j = 0; j < num_new_minor_tics; j++)
           {
 
                minor_x = last_tic_label + 
                          ((double) j + 1.0) * new_minor_tic_intv;

               tic_lines[i].x = (float)minor_x;
               tic_lines[i].y = gwin_attr->disp_label_min.y - minor_half_tic;
               tic_lines[i++].z = gwin_attr->disp_label_min.z;

               tic_lines[i].x = (float)minor_x;
               tic_lines[i].y = gwin_attr->disp_label_min.y;
               tic_lines[i++].z = gwin_attr->disp_label_min.z;
               num_minor_tics++;
           }


           /* now check to see if we have enough room to print the
            * label for the max value without running into the
            * previous major tics value. If ok then continue,
            * otherwise delete the major tic and the label closest 
            * to the maximum value (end point on the axis)
            */
        
           last_characters_displayed = (int) (((gwin_attr->disp_label_max.x - 
                              last_tic_label)/width) - 2);

           if (( last_characters_displayed < characters_displayed)
		&& (! xprecision_err))
           {
              bzero(scale,10);
              axes[last_major_tic] = (caddr_t)VStrcpy(scale);

              new_index = 
                   (last_major_tic + num_minor_tics - num_new_minor_tics) * 2;

              if ( gwin_attr->minor_tics.x > 0 )
              {
                  tic_lines[new_index].x = (float) last_tic_label;
                  tic_lines[new_index].y = 
				gwin_attr->disp_label_min.y - minor_half_tic;
                  tic_lines[new_index].z = gwin_attr->disp_label_min.z;

                  tic_lines[new_index + 1].x = (float) last_tic_label;
                  tic_lines[new_index + 1].y = gwin_attr->disp_label_min.y;
                  tic_lines[new_index + 1].z = gwin_attr->disp_label_min.z;
              }
              else
              {
                  tic_lines[new_index].x = (float) last_tic_label;
                  tic_lines[new_index].y = gwin_attr->disp_label_min.y;
                  tic_lines[new_index].z = gwin_attr->disp_label_min.z;

                  tic_lines[new_index + 1].x = (float) last_tic_label;
                  tic_lines[new_index + 1].y = gwin_attr->disp_label_min.y;
                  tic_lines[new_index + 1].z = gwin_attr->disp_label_min.z;
              }

           }
        }
 
        if (gwin_attr->draw_axes)
        {
	   colorindex = gwin_attr->current_colors[XAXIS_COLOR];
	   if (xp_device != xpX11)
               X3D_set_line_width(gwin->id, Fine);
	   X3D_draw_segments(gwin->id, tic_lines, 
			     2*(num_minor_tics+num_tics), &Colors[colorindex]);
        }

        if (gwin_attr->draw_numlabels)
	    label_tics(axes,text_coords,num_tics,plot_type,XNUMS_COLOR,
		       width,height,depth,direction);

        if (gwin_attr->rescale_relabel == RELABEL)
            X3D_set_wc_min_max (gwin->id, gwin_attr->disp_scale_min, 
                                          gwin_attr->disp_scale_max);

	free(tic_lines);
	free(axes);
	free(text_coords);
}

/************************************************************
*
*  MODULE NAME: ytics_xp3
*
*      PURPOSE: draws the major and minor tics on the y axis
*
*        INPUT:
*
*       OUTPUT: none
*
*    CALLED BY: draw_axis_xp3
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/
ytics_xp3(plot_type)

int plot_type;
{


	Vector direction;
	Coord *tic_lines, *text_coords;
	char tmp_str[100], scale[10];
	caddr_t *axes;
	float width, height, depth = 0;
	float tic_size, half_tic, half_tic2, minor_half_tic;
        char *get_axis_scale();
        double multiplier, last_tic_label, new_minor_tic_intv = 0.0, y, minor_y;
	int  num_tics, j=0, i=0, num_minor_tics=0, colorindex;
	int  characters_displayed, decimal_places, power_ten;
        int need_end = 0, num_new_minor_tics = 0;
        int last_major_tic, last_characters_displayed, new_index;
	int yprecision_err = False, index;


	direction.x = 0.0;
	direction.y = 1.0;
	direction.z = 0.0;

        if (gwin_attr->rescale_relabel == RELABEL)
            X3D_set_wc_min_max (gwin->id, gwin_attr->disp_label_min, 
                                          gwin_attr->disp_label_max);

	num_tics = (int)(gwin_attr->disp_label_num_tics.y);
	tic_size = 20.0;

	half_tic = (gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                   / tic_size;
	minor_half_tic = 0.5 * half_tic;

	width = (gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                / (1.5 * tic_size);
	height = (gwin_attr->disp_label_max.z - gwin_attr->disp_label_min.z)
                 / (1.5 * tic_size);  
	depth = (gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                 / (1.5 * tic_size);  

	characters_displayed = (int)
	((((gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                 / depth) / gwin_attr->disp_label_num_tics.y) - 6.0);

        if(characters_displayed > 6) characters_displayed = 6;

	find_scale_factor(characters_displayed,
                               (double)gwin_attr->disp_label_max.y,
	  		       (double)gwin_attr->disp_label_min.y,
                               (double)gwin_attr->disp_label_major_intv.y,
			       &decimal_places,&multiplier,&power_ten);

         gwin_attr->power_ten.y = (float) power_ten;

	if ((characters_displayed >= 3) ||
		(characters_displayed >= 2 && decimal_places == 0))
        {
	     sprintf(scale,"%%.%df",decimal_places);
        }
	else  /* too many tics so we only draw first and last label */
	{
	    /* compute a new interval since we only want to
             * label the first and laast points,
             * so, we say we have an 2 tics
             */

	    characters_displayed = (int)
                 ((((gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                            / depth) / 2.0) - 2.0);

            if (characters_displayed > 6) characters_displayed = 6;

	    find_scale_factor(characters_displayed,
                               (double)gwin_attr->disp_label_max.y,
                               (double)gwin_attr->disp_label_min.y,
                               (double)gwin_attr->disp_label_major_intv.y,
                               &decimal_places,&multiplier,&power_ten);

            gwin_attr->power_ten.y = (float) power_ten;
	    sprintf(scale,"%%.%df",decimal_places);
	    yprecision_err = TRUE;
	}

        last_tic_label = (double) gwin_attr->disp_label_min.y +
                         (((double) num_tics - 1.0) 
                         * (double) gwin_attr->disp_label_major_intv.y);

        if ( last_tic_label != (double) gwin_attr->disp_label_max.y )
        {
            need_end = True;

              /* calculate the last major tic mark */
            last_major_tic = (int) (num_tics - 1.0);

             /* calculate the number of minor tics we need to add */

            y = gwin_attr->disp_label_max.y - last_tic_label;
            new_minor_tic_intv = ((double) gwin_attr->disp_label_major_intv.y /
                           (double) ((int) (gwin_attr->minor_tics.y +0.5 + 1)));

	    if (new_minor_tic_intv == 0.0)
		num_new_minor_tics = 0;
	    else
                num_new_minor_tics = (int)
                      (((double)gwin_attr->disp_label_max.y - last_tic_label) /
                         new_minor_tic_intv);
        }

	if (gwin_attr->minor_tics.y > 0)
	   num_minor_tics += (int) ((num_tics - 1) 
			     * gwin_attr->minor_tics.y);

        /* malloc memory for the coords and the labels
         * add the +1 to the malloc in case we need
         * room for the end point, if we dont need room
         * then we malloced and extra point.
         */

	tic_lines =  (Coord *)malloc((unsigned) 
                      (sizeof(Coord) * 2 * (num_new_minor_tics + 
                                            num_minor_tics + num_tics + 1)));

	text_coords = (Coord *) malloc((unsigned) 
                       (sizeof(Coord) * (num_tics + 1)));
	axes = (caddr_t *)(malloc((unsigned)
                       (sizeof(caddr_t) * (num_tics + 1))));

	half_tic2 = 2.0 * half_tic;
	y = (double)gwin_attr->disp_label_min.y;
	if (! yprecision_err)
	{
	   for(i=0; i<num_tics; i++)
	   {
	      bzero(tmp_str,100);
	      (void) sprintf(tmp_str, scale, y*multiplier);
	      axes[i] = (caddr_t)VStrcpy(tmp_str);
	      text_coords[i].x = gwin_attr->disp_label_max.x + half_tic2;
	      text_coords[i].z = gwin_attr->disp_label_min.z;
	      text_coords[i].y = (float)y;
	      y += (double)gwin_attr->disp_label_major_intv.y;
	   }

           if (need_end)
           {
              bzero(tmp_str,100);
              (void) sprintf(tmp_str, scale, 
                            (double) gwin_attr->disp_label_max.y * multiplier);
              axes[i] = (caddr_t)VStrcpy(tmp_str);
              text_coords[i].x = gwin_attr->disp_label_max.x + half_tic2;
              text_coords[i].z = gwin_attr->disp_label_min.z;
              text_coords[i].y = (float) gwin_attr->disp_label_max.y;
           }
	}
	else
	{
 	   bzero(tmp_str,100);
           (void) sprintf(tmp_str, scale, y*multiplier);
           axes[0] = (caddr_t)VStrcpy(tmp_str);
           text_coords[0].x = gwin_attr->disp_label_max.x + half_tic2;
           text_coords[0].z = gwin_attr->disp_label_min.z;
           text_coords[0].y = (float)y;
	   if (need_end)
		index = num_tics;
	   else
		index = num_tics -1 ;

	  y = (double)gwin_attr->disp_label_max.y;

	  bzero(tmp_str,100);
	  (void) sprintf(tmp_str, scale, y*multiplier);
          axes[index] = (caddr_t)VStrcpy(tmp_str);
          text_coords[index].x = gwin_attr->disp_label_max.x + half_tic2;
          text_coords[index].z = gwin_attr->disp_label_min.z;
          text_coords[index].y = (float)y;

          y = (double)gwin_attr->disp_label_min.y
                        + (double)gwin_attr->disp_label_major_intv.y;

	  bzero(scale,10);
 	  for(i=1;i<index;i++)
	  {
	     bzero(tmp_str,100);
             (void) sprintf(tmp_str, scale, y*multiplier);
             axes[i] = (caddr_t)VStrcpy(tmp_str);
             text_coords[i].x = gwin_attr->disp_label_max.x + half_tic2;
             text_coords[i].z = gwin_attr->disp_label_min.z;
             text_coords[i].y = (float)y;

	     y += (double)gwin_attr->disp_label_major_intv.y;
	  }
	}

        /* load the coords for the major and minor tics */


	y = (double)gwin_attr->disp_label_min.y;
	for(i=0; i < 2*(num_tics+num_minor_tics);)
	{

	   tic_lines[i].x = gwin_attr->disp_label_max.x;
	   tic_lines[i].y = (float)y;
	   tic_lines[i++].z = gwin_attr->disp_label_min.z;

	   tic_lines[i].x = gwin_attr->disp_label_max.x + half_tic;
	   tic_lines[i].y = (float)y;
	   tic_lines[i++].z = gwin_attr->disp_label_min.z;

	   if(gwin_attr->minor_tics.y > 0 && i < 2*(num_tics+num_minor_tics))
	   {
		minor_y = y;
		for(j=0;j<(int)(gwin_attr->minor_tics.y + 0.5);j++)
		{
		   minor_y += (double) (gwin_attr->disp_label_major_intv.y
                                     / (gwin_attr->minor_tics.y + 1));

	    	   tic_lines[i].x = gwin_attr->disp_label_max.x;
		   tic_lines[i].y = (float)minor_y;
		   tic_lines[i++].z = gwin_attr->disp_label_min.z;

		   tic_lines[i].x = gwin_attr->disp_label_max.x 
					+ minor_half_tic;
		   tic_lines[i].y = (float)minor_y;
		   tic_lines[i++].z = gwin_attr->disp_label_min.z;
		}
	   }
	   y += (double)gwin_attr->disp_label_major_intv.y;

        }

        if (need_end)
        {
             /* Need to add the major tic line for the maximum value
              * on the axis
              */
	   tic_lines[i].x = gwin_attr->disp_label_max.x;
           tic_lines[i].y = gwin_attr->disp_label_max.y;
           tic_lines[i++].z = gwin_attr->disp_label_min.z;

           tic_lines[i].x = (float) gwin_attr->disp_label_max.x + half_tic;
           tic_lines[i].y = (float) gwin_attr->disp_label_max.y;
           tic_lines[i++].z = (float) gwin_attr->disp_label_min.z;
           num_tics++;

           /* need to add the minor tics in between the last
            * major interval tic and the maximum tic
            */

          for ( j = 0; j < num_new_minor_tics; j++)
           {

                minor_y = last_tic_label +
                          ((double) j + 1.0) * new_minor_tic_intv;

	        tic_lines[i].x = gwin_attr->disp_label_max.x;
	        tic_lines[i].y = (float)minor_y;
	        tic_lines[i++].z = gwin_attr->disp_label_min.z;

	        tic_lines[i].x = gwin_attr->disp_label_max.x + minor_half_tic;
	        tic_lines[i].y = (float)minor_y;
	        tic_lines[i++].z = gwin_attr->disp_label_min.z;

               num_minor_tics++;
           }

           /* now check to see if we have enough room to print the
            * label for the max value without running into the
            * previous major tics value. If ok then continue,
            * otherwise delete the major tic and the label closest
            * to the maximum value (end point on the axis)
            */

           last_characters_displayed = (int) (((gwin_attr->disp_label_max.y -
                              last_tic_label)/depth) - 2 );

           if ((last_characters_displayed <= characters_displayed)
		&& (! yprecision_err))
           {
              bzero(scale,10);
              axes[last_major_tic] = (caddr_t)VStrcpy(scale);

              new_index = 
                   (last_major_tic + num_minor_tics - num_new_minor_tics) * 2;

              if ( gwin_attr->minor_tics.y > 0 )
              {
                 tic_lines[new_index].x = gwin_attr->disp_label_max.x;
                 tic_lines[new_index].y = (float) last_tic_label;
                 tic_lines[new_index].z = gwin_attr->disp_label_min.z;

                 tic_lines[new_index + 1].x = 
	        		gwin_attr->disp_label_max.x + minor_half_tic;
                 tic_lines[new_index + 1].y = (float) last_tic_label;
                 tic_lines[new_index + 1].z = gwin_attr->disp_label_min.z;
              }
              else
              {
                 tic_lines[new_index].x = 
				gwin_attr->disp_label_max.x + minor_half_tic;
                 tic_lines[new_index].y = (float) last_tic_label;
                 tic_lines[new_index].z = gwin_attr->disp_label_min.z;;

                 tic_lines[new_index + 1].x = 
	        		gwin_attr->disp_label_max.x + minor_half_tic;
                 tic_lines[new_index + 1].y = (float) last_tic_label;
                 tic_lines[new_index + 1].z = gwin_attr->disp_label_min.z;
              }
           }
        }

        if (gwin_attr->draw_axes)
        {
	   colorindex = gwin_attr->current_colors[YAXIS_COLOR];
	   if (xp_device != xpX11)
               X3D_set_line_width(gwin->id, Fine);
	   X3D_draw_segments(gwin->id, tic_lines,
			     2*(num_minor_tics + num_tics), 
			     &Colors[colorindex]);
        } 

        if (gwin_attr->draw_numlabels)
	   label_tics(axes,text_coords,num_tics,plot_type,YNUMS_COLOR,
		      width,height,depth,direction);

        if (gwin_attr->rescale_relabel == RELABEL)
            X3D_set_wc_min_max (gwin->id, gwin_attr->disp_scale_min, 
                                          gwin_attr->disp_scale_max);
	free(tic_lines);
	free(axes);
	free(text_coords);
}




/************************************************************
*
*  MODULE NAME: ztics_xp3
*
*      PURPOSE: draws the major and minor tics on the y axis
*
*        INPUT:
*
*       OUTPUT: none
*
*    CALLED BY: draw_axis_xp3
*
*   WRITTEN BY: Mike Lang
*
*************************************************************/
ztics_xp3(plot_type)

int plot_type;
{


	Vector direction;
	Coord *tic_lines, *text_coords;
	char tmp_str[100], scale[10];
	caddr_t *axes;
	float width, height, depth = 0;
	float tic_size, half_tic, half_tic2, minor_half_tic;
        char *get_axis_scale();
        double multiplier, last_tic_label, new_minor_tic_intv = 0.0, z, minor_z;
	int  num_tics, j=0, i=0, num_minor_tics=0, colorindex;
	int  characters_displayed, decimal_places, power_ten;
        int need_end = 0, num_new_minor_tics = 0;
        int last_major_tic, last_characters_displayed, new_index;
	int zprecision_err = False, index;


	direction.x = 0.0;
	direction.y = 0.0;
	direction.z = 1.0;

        if (gwin_attr->rescale_relabel == RELABEL)
            X3D_set_wc_min_max (gwin->id, gwin_attr->disp_label_min, 
                                          gwin_attr->disp_label_max);

	num_tics = (int)(gwin_attr->disp_label_num_tics.z);
	tic_size = 20.0;

	half_tic = (gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                   / tic_size;
	minor_half_tic = 0.5 * half_tic;

	width = (gwin_attr->disp_label_max.x - gwin_attr->disp_label_min.x)
                / (1.5 * tic_size);
	height = (gwin_attr->disp_label_max.z - gwin_attr->disp_label_min.z)
                 / (1.5 * tic_size);  
	depth = (gwin_attr->disp_label_max.y - gwin_attr->disp_label_min.y)
                 / (1.5 * tic_size);  

	characters_displayed = (int)
	((((gwin_attr->disp_label_max.z - gwin_attr->disp_label_min.z)
                 / height) / gwin_attr->disp_label_num_tics.z) - 3.0);

        if(characters_displayed > 6) characters_displayed = 6;

	find_scale_factor(characters_displayed,
                               (double)gwin_attr->disp_label_max.z,
	  		       (double)gwin_attr->disp_label_min.z,
                               (double)gwin_attr->disp_label_major_intv.z,
			       &decimal_places,&multiplier,&power_ten);

         gwin_attr->power_ten.z = (float) power_ten;


	/* for nice data this should work */

	if ((characters_displayed >= 3) ||
		(characters_displayed >= 2 && decimal_places == 0))
        {
	    sprintf(scale,"%%.%df",decimal_places);
        }
	else   /* too many tics so we only draw first and last label */ 
	{
            /* compute a new interval since we only want to
             * label the first and laast points,
             * so, we say we have an 2 tics
             */

	   characters_displayed = (int)
	   ((((gwin_attr->disp_label_max.z - gwin_attr->disp_label_min.z)
                 / height) / 2.0) - 3.0);

           if(characters_displayed > 6) characters_displayed = 6;


                /* find a new scale factor based on an interval
                 * of two
                 */

	   find_scale_factor(characters_displayed,
                               (double)gwin_attr->disp_label_max.z,
	  		       (double)gwin_attr->disp_label_min.z,
                               (double)gwin_attr->disp_label_major_intv.z,
			       &decimal_places,&multiplier,&power_ten);

            gwin_attr->power_ten.z = (float) power_ten;
	    sprintf(scale,"%%.%df",decimal_places);
	    zprecision_err = TRUE;
	}


        last_tic_label = (double) gwin_attr->disp_label_min.z +
                         (((double) num_tics - 1.0) 
                         * (double) gwin_attr->disp_label_major_intv.z);

        if ( last_tic_label != (double) gwin_attr->disp_label_max.z )
        {
            need_end = True;

              /* calculate the last major tic mark */
            last_major_tic = (int) (num_tics - 1.0);

             /* calculate the number of minor tics we need to add */

            z = gwin_attr->disp_label_max.z - last_tic_label;
            new_minor_tic_intv = ((double) gwin_attr->disp_label_major_intv.z /
                           (double) ((int) (gwin_attr->minor_tics.z +0.5 + 1)));

	    if (new_minor_tic_intv == 0.0)
		num_new_minor_tics = 0;
	    else
                num_new_minor_tics = (int)
                      (((double)gwin_attr->disp_label_max.z - last_tic_label) /
                         new_minor_tic_intv);
        }

	if (gwin_attr->minor_tics.z > 0)
	   num_minor_tics += (int) ((num_tics - 1) 
			     * gwin_attr->minor_tics.z);

        /* malloc memory for the coords and the labels
         * add the +1 to the malloc in case we need
         * room for the end point, if we dont need room
         * then we malloced and extra point.
         */

	tic_lines =  (Coord *)malloc((unsigned) 
                      (sizeof(Coord) * 2 * (num_new_minor_tics + 
                                            num_minor_tics + num_tics + 1)));

	text_coords = (Coord *) malloc((unsigned) 
                       (sizeof(Coord) * (num_tics + 1)));
	axes = (caddr_t *)(malloc((unsigned)
                       (sizeof(caddr_t) * (num_tics + 1))));

	half_tic2 = 2.0 * half_tic;
	z = (double)gwin_attr->disp_label_min.z;
	if (! zprecision_err)
	{
	   for(i=0,j=0; i<num_tics; i++)
	   {
	      bzero(tmp_str,100);
	      (void) sprintf(tmp_str, scale, z*multiplier);
	      axes[i] = (caddr_t)VStrcpy(tmp_str);
	      text_coords[i].x = gwin_attr->disp_label_min.x - half_tic2;
	      text_coords[i].y = gwin_attr->disp_label_min.y;
	      text_coords[i].z = (float)z;
	      z += (double)gwin_attr->disp_label_major_intv.z;
	   }

           if (need_end)
           {
              bzero(tmp_str,100);
              (void) sprintf(tmp_str, scale, 
                         (double) gwin_attr->disp_label_max.z * multiplier);
              axes[i] = (caddr_t)VStrcpy(tmp_str);
              text_coords[i].x = gwin_attr->disp_label_min.x - half_tic2;
              text_coords[i].y = gwin_attr->disp_label_min.y;
              text_coords[i].z = gwin_attr->disp_label_max.z;
           }
	}
	else
	{
	   bzero(tmp_str,100);
           (void) sprintf(tmp_str, scale, z*multiplier);
           axes[0] = (caddr_t)VStrcpy(tmp_str);
           text_coords[0].x = gwin_attr->disp_label_min.x - half_tic2;
           text_coords[0].y = gwin_attr->disp_label_min.y;
           text_coords[0].z = (float)z;

	   if (need_end)
		index = num_tics;
	   else
		index = num_tics - 1;

	   z = (double)gwin_attr->disp_label_max.z;
	   bzero(tmp_str,100);
	   (void) sprintf(tmp_str, scale, z*multiplier);
           axes[index] = (caddr_t)VStrcpy(tmp_str);
           text_coords[index].x = gwin_attr->disp_label_min.x - half_tic2;
           text_coords[index].y = gwin_attr->disp_label_min.y;
           text_coords[index].z = (float)z;
	
	   z = (double)gwin_attr->disp_label_min.z +
		(double)gwin_attr->disp_label_major_intv.z;

	   bzero(scale,10);
	   for(i=1;i<index;i++)
           {
	      bzero(tmp_str,100);
              (void) sprintf(tmp_str, scale, z*multiplier);
              axes[i] = (caddr_t)VStrcpy(tmp_str);
              text_coords[i].x = gwin_attr->disp_label_min.x - half_tic2;
              text_coords[i].y = gwin_attr->disp_label_min.y;
              text_coords[i].z = (float)z;
              z += (double)gwin_attr->disp_label_major_intv.z;
	   }
	}

        /* load the coords for the major and minor tics */


	z = (double)gwin_attr->disp_label_min.z;
	for(i=0; i < 2*(num_tics+num_minor_tics);)
	{

	   tic_lines[i].x = gwin_attr->disp_label_min.x - half_tic;
	   tic_lines[i].y = gwin_attr->disp_label_min.y;
	   tic_lines[i++].z = (float)z;

	   tic_lines[i].x = gwin_attr->disp_label_min.x;
	   tic_lines[i].y = gwin_attr->disp_label_min.y;
	   tic_lines[i++].z = (float)z;

	   if(gwin_attr->minor_tics.z > 0 && i < 2*(num_tics+num_minor_tics))
	   {
		minor_z = z;
		for(j=0;j<(int)(gwin_attr->minor_tics.z + 0.5);j++)
		{
		   minor_z += (double) (gwin_attr->disp_label_major_intv.z
                                     / (gwin_attr->minor_tics.z + 1));

	    	   tic_lines[i].x = gwin_attr->disp_label_min.x-minor_half_tic;
	    	   tic_lines[i].y = gwin_attr->disp_label_min.y;
		   tic_lines[i++].z = (float)minor_z;
		   tic_lines[i].x = gwin_attr->disp_label_min.x;
		   tic_lines[i].y = gwin_attr->disp_label_min.y;
		   tic_lines[i++].z = (float)minor_z;
		}
	   }
	   z += (double)gwin_attr->disp_label_major_intv.z;

        }
        
        if (need_end)
        {
             /* Need to add the major tic line for the maximum value
              * on the axis
              */

	   tic_lines[i].x = gwin_attr->disp_label_min.x - half_tic;
	   tic_lines[i].y = gwin_attr->disp_label_min.y;
           tic_lines[i++].z = gwin_attr->disp_label_max.z;

           tic_lines[i].x =  gwin_attr->disp_label_min.x;
           tic_lines[i].y =  gwin_attr->disp_label_min.y;
           tic_lines[i++].z = gwin_attr->disp_label_max.z;
           num_tics++;

           /* need to add the minor tics in between the last
            * major interval tic and the maximum tic
            */

          for ( j = 0; j < num_new_minor_tics; j++)
           {

                minor_z = last_tic_label +
                          ((double) j + 1.0) * new_minor_tic_intv;

	       tic_lines[i].x = gwin_attr->disp_label_min.x - minor_half_tic;
	       tic_lines[i].y = gwin_attr->disp_label_min.y;
	       tic_lines[i++].z = (float)minor_z;

	       tic_lines[i].x = gwin_attr->disp_label_min.x;
	       tic_lines[i].y = gwin_attr->disp_label_min.y;
	       tic_lines[i++].z = (float)minor_z;
               num_minor_tics++;
           }

           /* now check to see if we have enough room to print the
            * label for the max value without running into the
            * previous major tics value. If ok then continue,
            * otherwise delete the major tic and the label closest
            * to the maximum value (end point on the axis)
            */

           last_characters_displayed = (int) (((gwin_attr->disp_label_max.z -
                              last_tic_label)/height) - 1.0);

           if ((last_characters_displayed <= characters_displayed)
		&& (! zprecision_err))
           {
              bzero(scale,10);
              axes[last_major_tic] = (caddr_t)VStrcpy(scale);

              new_index = 
                   (last_major_tic + num_minor_tics - num_new_minor_tics) * 2;

              if ( gwin_attr->minor_tics.z > 0 )
              {
                 tic_lines[new_index].x = 
                            gwin_attr->disp_label_min.x  - minor_half_tic;
                 tic_lines[new_index].y = gwin_attr->disp_label_min.y;
                 tic_lines[new_index].z = (float) last_tic_label;
                 tic_lines[new_index + 1].x = gwin_attr->disp_label_min.x;
                 tic_lines[new_index + 1].y = gwin_attr->disp_label_min.y;
                 tic_lines[new_index + 1].z = (float) last_tic_label;
              }
              else
              {
                 tic_lines[new_index].x = gwin_attr->disp_label_min.x;
                 tic_lines[new_index].y = gwin_attr->disp_label_min.y;
                 tic_lines[new_index].z = (float) last_tic_label;
                 tic_lines[new_index + 1].x = gwin_attr->disp_label_min.x;
                 tic_lines[new_index + 1].y = gwin_attr->disp_label_min.y;
                 tic_lines[new_index + 1].z = (float) last_tic_label;
              }
           }
        }

        if (gwin_attr->draw_axes)
        {
	   colorindex = gwin_attr->current_colors[ZAXIS_COLOR];
	   if (xp_device != xpX11)
               X3D_set_line_width(gwin->id, Fine);
	   X3D_draw_segments(gwin->id, tic_lines,
			     2*(num_minor_tics + num_tics), 
			     &Colors[colorindex]);
        } 

        if (gwin_attr->draw_numlabels)
	   label_tics(axes,text_coords,num_tics,plot_type,ZNUMS_COLOR,
		      width,height,depth,direction);

        if (gwin_attr->rescale_relabel == RELABEL)
            X3D_set_wc_min_max (gwin->id, gwin_attr->disp_scale_min, 
                                          gwin_attr->disp_scale_max);
	free(tic_lines);
	free(axes);
	free(text_coords);
}


/************************************************************
*
*  MODULE NAME: axis_is_obscured
*
*      PURPOSE: returns TRUE or FALSE depending on whether the
*		line passed in will be obscured by the plot
*		(used for drawing axes on mesh plots)
*
*
*        INPUT: 1) id     -- id of this gwin
*		2) pt1    -- 1st point in WC's
*		3) pt2    -- 2nd point in WC's
*
*		4) flag   -- flag telling if the line passed in is:
*		   a) Y_AXIS_LINE:
*		      y axis which will be marked with tics (special case)
*		   b) OPP_Y_AXIS:
*		      opposite the y axis - side of the XY plane (special case)
*		   b) GENERAL: anything else (general case)
*
*
*       OUTPUT: TRUE - if line is obscured; FALSE otherwise
*
*    CALLED BY: 
*
*   WRITTEN BY: Mark Young and Danielle Argiro
*
*
*************************************************************/

int axis_is_obscured(id, center, pt1, pt2, flag)

int	id;
Coord	center, pt1, pt2;
short	flag;
{
	Real alpha, theta, eye_dist;

        X3D_inquire_viewpoint (id, &alpha, &theta, &eye_dist);

	if (flag == GENERAL)
	{
     	   if ((alpha >= 0) && (alpha <= 180))  
     	   { 
     	      if ((theta >= 270) || (theta <= 90))  
     	      {
                 if ((pt1.y > center.y) || (pt2.y > center.y))   
     		    return(TRUE);
     		 else
		    return(FALSE);
     	      }
      	      else 
     	      {
     		 if ((pt1.y < center.y) || (pt2.y < center.y))
     		     return(TRUE);
     		 else
		     return(FALSE);
              }
     	   } 
     	   else
	   {
     	      if ((theta >= 270) || (theta <= 90))  
     	      {
                 if ((pt1.y < center.y) || (pt2.y < center.y))   
     		    return(TRUE);
     		 else
		    return(FALSE);
     	      }
      	      else 
     	      {
     		 if ((pt1.y > center.y) || (pt2.y > center.y))
     		    return(TRUE);
     		 else
		    return(FALSE);
     	      }
     	   }	
        } /* end if flag == GENERAL */


	/*  doing the side of the XY plane - opposite the Y axis */
	else  if (flag == OPP_Y_AXIS)
	{
     	   if ((alpha <= 90) ||(alpha >= 270))  
	   {
     	          if ((pt1.x < center.x) || (pt2.x < center.x))
		     return(TRUE);
	          else
		     return(FALSE);
	   }
	   else 
	   {
     	      if ((pt1.x > center.x) || (pt2.x > center.x))
		 return(TRUE);
	      else
		 return(FALSE);
	    }
	}

	/* doing the Y axis */
	else  
	{
     	   if (( alpha <= 90) || (alpha >= 270))
	   {
     	         if ((pt1.x > center.x) || (pt2.x > center.x))
		    return(TRUE);
	         else
		    return(FALSE);
	   }
	   else 
	   {
     	      if ((pt1.x < center.x) || (pt2.x < center.x))
		 return(TRUE);
	      else
		 return(FALSE);
	   }
	}
}  /* end axis_is_obscured */
