/*                    Listing 1                     */
/*****************************************************
                Name: SRF_TRNS.C
         Description: Library of functions for the
                      rotation and translation of
                      surface equation coefficients
Global Function List: srf_rotate, srf_trans
         Portability: Standard C
*****************************************************/

#include <stdlib.h>
#include <srf_trns.h>

/*****************************************************
       Name: srf_rotate
 Parameters: Co - 4x4 matrix of original coefficients
             Cr - 4x4 matrix of rotated coefficients
             R - 3x3 matrix of coordinant rotation of
             new system with respect to the original
Description: Rotate a surface by a given coordinant
             transformation.  Second order surfaces
             are in the form,
             0 = C00 + C01x + C02y + C03z + C11x +
             C22y + C33z + C12xy + C23yz + C13xz
             First order are in the form,
             0 = C00 + C01x + C02y + C03z 
*****************************************************/
void srf_rotate( double **Co, double **Cr,
      double **R )
   {
   size_t i, j, k, m;

   /* Get the constant term. */
   Cr[0][0] = Co[0][0];

   /* The squared terms. C11, C22, C33 */
   for ( i = 1; i < 4; i++ )
      for ( j = 1; j < 4; j++ )
         for ( k = 1; k < 4; k++ )
            Cr[i][i] += R[i - 1][j - 1] *
                  R[i - 1][k - 1] * Co[j][k];

   /* The mixed terms. C12, C13, C23 */
   for ( i = 1; i < 4; i++ )
      for ( j = i + 1; j < 4; j++ )
         for ( k = 1; k < 4; k++ )
            for ( m = 1; m < 4; m++ )
               Cr[i][j] += R[i - 1][k - 1] *
                     R[j - 1][m - 1] *
                     Co[k][m] *
                     (( k == m ) ? 2 : 1 );

   /* The linear terms. C01, C02, C03 */
   for ( i = 1; i < 4; i++ )
      for ( j = 1; j < 4; j++ )
         Cr[0][i] += R[i - 1][j - 1] * Co[0][j];

   /* Fill up the diagonals, make matrix symetric */
   for ( i = 0; i < 4; i++ )
      for ( j = i + 1; j < 4; j++ )
         Cr[j][i] = Cr[i][j];

   }   /* function surf_rotate */

/*****************************************************
       Name: srf_trans
 Parameters: Co - 4x4 matrix of original coefficients
             T - array of translation vector
     Return: Co is modified
Description: Translate a surface by a given distance
             vector.  The distance vector is defined
             the the coordinate system the surface is
             currently in. Second order surfaces
             are in the form,
             0 = C00 + C01x + C02y + C03z + C11x +
             C22y + C33z + C12xy + C23yz + C13xz
             First order are in the form,
             0 = C00 + C01x + C02y + C03z 
*****************************************************/
void srf_trans( double **Co, double *T )
   {
   size_t i, j;

   /* Get the constant term. C00 */
   for ( i = 0; i < 4; i++ )
      for ( j = i; j < 4; j++ )
         Co[0][0] += (( i == 0 ) ? 1.0 :
               T[i - 1] ) * (( j == 0 ) ? 0.0 :
               T[j - 1] ) * Co[i][j];

   /* Get the single terms.  C01, C02, C03 */
   for ( i = 1; i < 4; i++ )
      for ( j = 1; j < 4; j++ )
         Co[0][i] += T[j - 1] * Co[j][i] *
               (( i == j ) ? 2.0 : 1.0 );

   /* Fill up the diagonals, make matrix symetric */
   for ( i = 0; i < 4; i++ )
      for ( j = i + 1; j < 4; j++ )
         Co[j][i] = Co[i][j];

   }   /* function surf_tran */
/* End of File */
