 /*
  * Khoros: $Id: convert_2D.c,v 1.3 1992/03/20 22:46:46 dkhoros Exp $
  */

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

 /*
  * $Log: convert_2D.c,v $
 * Revision 1.3  1992/03/20  22:46:46  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 "X3D.h"


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name: convert_2D.c
   >>>>                           
   >>>>   description: 2D conversion routines           
   >>>>                  
   >>>>      routines: 	
   >>>>			_X2D_convert_wc_to_dc()	      	
   >>>>			_X2D_convert_wc_to_dc_seg()   	 
   >>>>			_X2D_convert_wc_coord_to_dc_seg() 
   >>>>			X2D_convert_point_wc_to_dc() 
   >>>>			X2D_convert_point_dc_to_wc() 
   >>>>                                             
   >>>>                
   >>>> modifications:
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


/************************************************************
*
*  MODULE NAME: _X2D_convert_wc_to_dc
*
*      PURPOSE: Converts a array of 2D world coordinate points 
*               to device coordinates and stores them as XPoints 
*		for later calls to X11 routines
*
*        INPUT: graphics - the graphics structure
*	        coords   - array of world coordinates input
*		size     - number of points to convert
*
*       OUTPUT: points   - XPoint array of device coordinates
*
*    CALLED BY: X2D_draw_polyline(), X2D_draw_marker(), 
*		X2D_draw_polygon
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/



int _X2D_convert_wc_to_dc (graphics, coords, points, size)

X3DGraphics	*graphics;
Coord		*coords;
XPoint		*points;
int		size;
{
	int	i;
	Real	x, y, w;
	Coord	*scale;

	if(!(_X2D_scale_wc_coords(graphics->scale, coords, &scale, size)))
	   return(FALSE);

	for (i = 0; i < size; i++)
	{
	    _X2D_vector_mult(scale[i], graphics->matrix2D, x, y, w);
	    points[i].x = (short) (int)( (double) (x + 0.5));
	    points[i].y = (short) (int)( (double) (y + 0.5));
	}

	if (coords != scale)
	   free(scale);

	return(TRUE);
}



/************************************************************
*
*  MODULE NAME: _X2D_convert_wc_to_dc_seg
*
*      PURPOSE: Converts a array of 2D world coordinate segments 
*               to device coordinates and stores them as XSegments 
*		for later calls to X11 routines
*
*        INPUT: graphics - the graphics structure
*	        coords   - array of world coordinates input
*		size     - number of points to convert
*
*       OUTPUT: segments   - XSegment array of device coordinates
*
*    CALLED BY: X2D_draw_segment
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/



int _X2D_convert_wc_to_dc_seg (graphics, coords, segments, size)

X3DGraphics	*graphics;
Coord		*coords;
XSegment	*segments;
int		size;
{
	int	i, j;
	Real	x, y, w;
	Coord	*scale;

	if(!(_X2D_scale_wc_coords(graphics->scale, coords, &scale, size)))
	   return(FALSE);

	j = 0;
	for (i = 0; i < size; i += 2)
	{
	    _X2D_vector_mult(scale[i], graphics->matrix2D, x, y, w);
	    segments[j].x1 = (short) (int)( (double) (x + 0.5));
	    segments[j].y1 = (short) (int)( (double) (y + 0.5));

	    _X2D_vector_mult(scale[i +1], graphics->matrix2D, x, y, w);
	    segments[j].x2 = (short) (int)( (double) (x + 0.5));
	    segments[j].y2 = (short) (int)( (double) (y + 0.5));

	    j++;
	}

	if (coords != scale)
	   free(scale);

	return(TRUE);
}



/************************************************************
*
*  MODULE NAME: _X2D_convert_wc_coord_to_dc_seg
*
*      PURPOSE: Converts a array of 2D world coordinate polylines 
*               to device coordinates and stores them as XSegments 
*		for later calls to X11 routines
*
*        INPUT: graphics - the graphics structure
*	        coords   - array of world coordinates input
*		size     - number of points to convert
*
*       OUTPUT: segments   - XSegment array of device coordinates
*
*    CALLED BY: X2D_draw_segment
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/



int _X2D_convert_wc_coord_to_dc_seg (graphics, coords, segments, size)

X3DGraphics	*graphics;
Coord		*coords;
XSegment	*segments;
int		size;
{
	int	i, j;
	Real	x, y, w;
	Coord	*scale;

	if(!(_X2D_scale_wc_coords(graphics->scale, coords, &scale, size)))
	   return(FALSE);

	j = 0;
	for (i = 0; i < (size-1); i ++)
	{
	    _X2D_vector_mult(scale[i], graphics->matrix2D, x, y, w);
	    segments[j].x1 = (short) (int)( (double) (x + 0.5));
	    segments[j].y1 = (short) (int)( (double) (y + 0.5));

	    _X2D_vector_mult(scale[i +1], graphics->matrix2D, x, y, w);
	    segments[j].x2 = (short) (int)( (double) (x + 0.5));
	    segments[j].y2 = (short) (int)( (double) (y + 0.5));

	    j++;
	}

	if (coords != scale)
	   free(scale);

	return(TRUE);
}



/************************************************************
*
*  MODULE NAME: X2D_convert_point_wc_to_dc
*
*      PURPOSE: Converts a 2D world coordinate point
*               to device coordinates and stores it the
*		X and Y variables.
*
*        INPUT: id	- the X2D graphics structure
*	        coord   - array of world coordinates input
*
*       OUTPUT: x, y    - the dc result.
*
*    CALLED BY: application program
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/



int X2D_convert_point_wc_to_dc (id, coord, x_out, y_out)

int	id;
Coord	coord;
Real	*x_out, *y_out;
{
	Real	    w;
	Coord	    scale;
	X3DGraphics *graphics;

        if (!(graphics = _X3D_get_graphics(id)))
        {
           (void) fprintf (stderr,"X2D_convert_point_wc_to_dc:");
           (void) fprintf (stderr,"\t unknown graphics id %d\n",id);
           return(FALSE);
        }

	if(!(_X2D_scale_wc_coord(graphics->scale, coord, &scale)))
	   return(FALSE);

        _X2D_vector_mult(scale, graphics->matrix2D, *x_out, *y_out, w);
	return(TRUE);
}



/************************************************************
*
*  MODULE NAME: X2D_convert_point_dc_to_wc
*
*      PURPOSE: Converts a device coordinates point to a 2D
*		world coordinate point and stores it in the
*		supplied coordinate
*
*        INPUT: id	- the X2D graphics structure
*		x, y    - the dc result.
*
*       OUTPUT: coord   - array of world coordinates input
*
*    CALLED BY: application program
*
*   WRITTEN BY: Mark Young
*
*
*************************************************************/



int X2D_convert_point_dc_to_wc (id, x, y, coord)

int	id;
Real	x, y;
Coord	*coord;
{
	X3DGraphics *graphics;

	Real	    w;
	Coord	    temp;
	Matrix_2D   imatrix;


        if (!(graphics = _X3D_get_graphics(id)))
        {
           (void) fprintf (stderr,"X2D_convert_point_dc_to_wc:");
           (void) fprintf (stderr,"\t unknown graphics id %d\n",id);
           return(FALSE);
        }

	temp.x = x; temp.y = y;
	if (X2D_matrix_set_inverse(graphics->matrix2D, imatrix) == FALSE)
	   return(FALSE);
        else
	   _X2D_vector_mult(temp, imatrix, coord->x, coord->y, w);

	return(TRUE);
}
