#ifndef lint static char SccsId[] = "%W% %G%"; #endif /* Module: crdinvrt.c (Coordinate Invert) * Purpose: Compute reverse transform and unknown transform parameters * Subroutine: invert_matrix() returns: void * Subroutine: compute_iadd_invert() returns: void * Xlib calls: none * Copyright: 1988 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. * Modified: {0} Michael VanHilst initial version 16 March 1988 * {n} -- -- */ #include /* stderr, NULL, etc */ #include /* get trig functions, sqrt, and fabs */ #include "hfiles/coord.h" /* Transform and other coord structs */ #define N 3 /* all matrices are 3x3 */ /* * Subroutine: invert_matrix * Purpose: Compute parameters of the inverse transform * Method: Uses LU decomposition method */ void invert_matrix ( old, new ) Transform *old, *new; { float scratch[3][3], column[3]; int pivots[3]; static void lu_decompose(), lu_backsub(); scratch[0][0] = old->inx_outx; scratch[1][0] = old->iny_outx; scratch[2][0] = old->add_outx; scratch[0][1] = old->inx_outy; scratch[1][1] = old->iny_outy; scratch[2][1] = old->add_outy; scratch[0][2] = scratch[1][2] = 0.0; scratch[2][2] = 1.0; lu_decompose(scratch, pivots); /* solve for out X */ column[1] = column[2] = 0.0; column[0] = 1.0; lu_backsub(scratch, pivots, column); new->inx_outx = column[0]; new->iny_outx = column[1]; new->add_outx = column[2]; /* solve for out Y */ column[0] = column[2] = 0.0; column[1] = 1.0; lu_backsub(scratch, pivots, column); new->inx_outy = column[0]; new->iny_outy = column[1]; new->add_outy = column[2]; } /* * Subroutine: compute_iadd_invert * Purpose: Compute the offsets used for integer transforms * Method: Uses matrix inversion */ void compute_iadd_invert ( old, new, ioff ) Transform *old, *new; float ioff; { float scratch[3][3], column[3]; int pivots[3]; static void lu_decompose(), lu_backsub(); /* set transform equations in matrix form */ scratch[0][0] = old->inx_outx; scratch[1][0] = old->iny_outx; scratch[2][0] = old->add_outx + ioff; scratch[0][1] = old->inx_outy; scratch[1][1] = old->iny_outy; scratch[2][1] = old->add_outy + ioff; scratch[0][2] = scratch[1][2] = 0.0; scratch[2][2] = 1.0; lu_decompose(scratch, pivots); /* solve for out X */ column[1] = column[2] = 0.0; column[0] = 1.0; lu_backsub(scratch, pivots, column); new->iadd_outx = column[2]; /* solve for out Y */ column[0] = column[2] = 0.0; column[1] = 1.0; lu_backsub(scratch, pivots, column); new->iadd_outy = column[2]; } /* * Subroutine: lu_decompose * Purpose: lower upper decompose matrix (in place) for matrix inversion */ static void lu_decompose ( mtrx, pivots ) float mtrx[3][3]; int pivots[3]; { int i, j, k, imax; double sum, mag, column_max; float merit; float rescale[3]; /* find the maximum values in each column */ for( i=0; i column_max ) column_max = mag; } /* save scaling value */ rescale[i] = 1.0 / column_max; } /* loop through columns for Crouts method */ for( j=0; j 0 ) { for( i=0; i 0 ) { for( k=0; k 0 ) { for( k=0; k= column_max ) { column_max = merit; imax = i; } } /* need to interchange rows? */ if( j != imax ) { for( k=0; k=0 ) { for( j=index; j=0; i-- ) { sum = result[i]; if( i < (N-1) ) { for( j=i+1; j