/*
   2DTrans.c

   Here is a program that performs several transformations
   on a box in 2-D space.  It uses Matrix.library.

   This code is FREELY DISTRIBUTABLE but NOT PUBLIC DOMAIN
   (written by Randy Finch)
*/

#include "Test.h"

/*---------------
      main()
-----------------*/

void main(argc,argv)
   int argc;
   char **argv;
{
   LONG i;		   /* Index variable */
   DOUBLE *corner[4];	   /* Coordinates of 4 box corners */
   DOUBLE *newcorner[4];   /* Coordinates of 4 box corners */
   DOUBLE **translate1;    /* First translation matrix */
   DOUBLE **translate2;    /* Second translation matrix */
   DOUBLE **scale;	   /* Scale matrix */
   DOUBLE **rotate;	   /* Rotation matrix */
   DOUBLE **transform;	   /* Complete transformation matrix */
   DOUBLE **alttransform;  /* For intermediate calcs */

   puts("\nOpening Matrix.library\n");
   Matrix = OpenLibrary("Matrix.library",1);
   printf("\nMatrix = %x\n",Matrix);

   if(!Matrix) {
      printf("\nCould not open Matrix.library!\n");
      exit(0);
   }

   /* Allocate necessary vectors and matrices */
   for (i=0 ; i<4 ; i++) {
      if (!(corner[i] = (DOUBLE *)AllocDVector(3))) {
	 printf("\nCould not allocate CORNER vectors.\n");
	 exit(0);
      }
   }

   if(!(translate1 = (DOUBLE **)AllocDMatrix(3,3))) {
	 printf("\nCould not allocate TRANSLATE1 matrix.\n");
	 exit(0);
   }

   if(!(translate2 = (DOUBLE **)AllocDMatrix(3,3))) {
	 printf("\nCould not allocate TRANSLATE2 matrix.\n");
	 exit(0);
   }

   if(!(scale = (DOUBLE **)AllocDMatrix(3,3))) {
	 printf("\nCould not allocate SCALE matrix.\n");
	 exit(0);
   }

   if(!(rotate = (DOUBLE **)AllocDMatrix(3,3))) {
	 printf("\nCould not allocate ROTATE matrix.\n");
	 exit(0);
   }

   /* Assign coordinates to corner vectors */
   (corner[0])[0] = 5.0;
   (corner[0])[1] = 6.0;  /* Lower left */
   (corner[0])[2] = 1.0;

   (corner[1])[0] = 5.0;
   (corner[1])[1] = 9.0;  /* Upper left */
   (corner[1])[2] = 1.0;

   (corner[2])[0] = 9.0;
   (corner[2])[1] = 9.0;  /* Upper right */
   (corner[2])[2] = 1.0;

   (corner[3])[0] = 9.0;
   (corner[3])[1] = 6.0;  /* Lower right */
   (corner[3])[2] = 1.0;

   /* Assign values to translate matrices
      Zero elements do not need to be assigned */
   (translate1[0])[0] = (translate2[0])[0] = 1.0;
   (translate1[1])[1] = (translate2[1])[1] = 1.0;
   (translate1[2])[2] = (translate2[2])[2] = 1.0;
   /* Center half way between corners */
   (translate1[2])[0] = -( (corner[0])[0] + (corner[2])[0] )/2.0;
   (translate1[2])[1] = -( (corner[0])[1] + (corner[1])[1] )/2.0;
   (translate2[2])[0] = ( (corner[0])[0] + (corner[2])[0] )/2.0;
   (translate2[2])[1] = ( (corner[0])[1] + (corner[1])[1] )/2.0;

   /* Assign values to scale matrix */
   (scale[0])[0] = 1.5;
   (scale[1])[1] = 2.0;
   (scale[2])[2] = 1.0;

   /* Assign values to rotate matrix */
   (rotate[0])[0] = cos(PI/4.0);
   (rotate[0])[1] = sin(PI/4.0);
   (rotate[1])[0] = -sin(PI/4.0);
   (rotate[1])[1] = cos(PI/4.0);
   (rotate[2])[2] = 1.0;

#define MDM MultDMatrices

   /* transform and alttransform created by MDM */
   transform = MDM( (alttransform = MDM( (transform = MDM(translate1,
							  scale,NULL,3,3,3)),
					  rotate,NULL,3,3,3)),
		     translate2,transform,3,3,3);

/* The above statement is equivalent to following statments:
transform = MultDMatrices(translate1, scale, NULL, 3, 3, 3);

alttransform = MultDMatrices(transform, rotate, NULL, 3, 3, 3);

transform = MultDMatrices(alttransform, translate2, transform, 3, 3, 3);
*/

   /* Get NEWCORNER[] from TRANSFORM and CORNER[]
      NEWCORNER[i] created by MultDVectorMatrix */
   for (i=0 ; i<4 ; i++) {
      newcorner[i] = MultDVectorMatrix(corner[i],transform,NULL,3,3);
   }

   /* Print results */
   printf("\nCORNER[] =");
   for (i=0 ; i<4 ; i++) {
      DisplayDVector(corner[i],3);
   }

   printf("\nTRANSFORM =");
   DisplayDMatrix(transform,3,3);

   printf("\nNEWCORNER[] =");
   for (i=0 ; i<4 ; i++) {
      DisplayDVector(newcorner[i],3);
   }

   /* Free vectors and matrices */
   for (i=0 ; i<4 ; i++) {
      FreeDVector(corner[i],3);
   }

   for (i=0 ; i<4 ; i++) {
      FreeDVector(newcorner[i],3);
   }

   FreeDMatrix(translate1,3,3);
   FreeDMatrix(translate2,3,3);
   FreeDMatrix(scale,3,3);
   FreeDMatrix(rotate,3,3);
   FreeDMatrix(transform,3,3);
   FreeDMatrix(alttransform,3,3);

   /* Finally, close the library */
   CloseLibrary(Matrix);

} /* main */

