示例#1
0
void   make_rots(float **xmat, float rot_x, float rot_y, float rot_z)
{
   float
      **TRX,
      **TRY,
      **TRZ,
      **T1;
   
   ALLOC2D(TRX  ,5,5);
   ALLOC2D(TRY  ,5,5);
   ALLOC2D(TRZ  ,5,5);
   ALLOC2D(T1   ,5,5);

   nr_rotxf(TRX, rot_x);             /* create the rotate X matrix */
   nr_rotyf(TRY, rot_y);             /* create the rotate Y matrix */
   nr_rotzf(TRZ, rot_z);             /* create the rotate Z matrix */
   
   nr_multf(TRY,1,4,1,4,  TRX,1,4,1,4,  T1); /* apply rx and ry */
   nr_multf(TRZ,1,4,1,4,  T1,1,4,1,4,   xmat); /* apply rz */


   FREE2D(TRX);
   FREE2D(TRY);
   FREE2D(TRZ);
   FREE2D(T1 );

}
示例#2
0
/*
   function getparams will get the trnsform  parameters from a 
   transformation matrix 'tran' (that has already had the translation 
   componants removed).
   in description below, I assume that tran is a forward xform, from 
   native space to talairach space.
   I assume that trans is a 4x4 homogeneous matrix, with the 
   principal axis stored in the upper left 3x3 matrix.  The first col
   of tran represents is the coordinate of (1,0,0)' mapped through the
   transformation.  (this means  vec2 = tran * vec1).
  
   trans = [scale][shear][rot]
         = [scale][shear][rz][ry][rx];

   the shear matrix is constrained to be of the form:
     shear = [1 0 0 0
              f 1 0 0
              g h 1 0
              0 0 0 1];
     where f,g,h can take on any value.

   the scale matrix is constrained to be of the form:
     scale = [sx 0  0  0
              0  sy 0  0
              0  0  sz 0
              0  0  0  1];
     where sx,sy,sz must be positive.
   
  all rotations are assumed to be in the range -pi/2..pi/2

  the rotation angles are returned as radians and are applied 
  counter clockwise, when looking down the axis (from the positive end
  towards the origin).

  trans is assumed to be invertible.

  i assume a coordinate system:
             ^ y
             |
             |
             |
             |_______> x
            /
           /
          /z  (towards the viewer).

  
  
  procedure: 
          start with t = inv(tran) (after removing translation from tran )
  
          t = inv(r)*inv(sh)*inv(sc)
                  t maps the talairach space unit vectors into native
                space, which means that the columns of T are the
                direction cosines of these vectors x,y,z

   (1)  the length of the vectors x,y,z give the inverse scaling
        parameters:
             sx = 1/norm(x); sy = 1/norm(y); sz = 1/norm(z);

   (2)  with the constraints on the form of sh above, inv(sh) has the
        same form.  let inv(sh) be as above in terms of a,b and c.
          inv(sh) = [1 0 0 0; a 1 0 0; b c 1 0; 0 0 0 1];

        for c: project y onto z and normalize:

                  /     |y.z|^2     \(1/2)
             c = <  ---------------  >
                  \ |y|^2 - |y.z|^2 /

        for b: project x onto z and normalize

                  /        |x.z|^2        \(1/2)
             b = <  ---------------------  >
                  \ |x|^2 - |x.z|^2 - a^2 /
     
          where a is the projection of x onto the coordinate sys Y axis.

        for a: project x onto z and normalize
           a is taken from (b) above, and normalized... see below

  (3) rots are returned by getrots by giving the input transformation:
        rot_mat = [inv(sh)][inv(sc)][trans]

  (4) once completed, the parameters of sx,sy,sz and a,b,c are
      adjusted so that they maintain the matrix contraints above.


*/
VIO_BOOL extract2_parameters_from_matrix(VIO_Transform *trans,
                                               double *center,
                                               double *translations,
                                               double *scales,
                                               double *shears,
                                               double *rotations)
{
  int 
    i,j;

  float 
    n1,n2,
    magnitude, magz, magx, magy, ai,bi,ci,scalar,a1,
    **center_of_rotation,
    **result,
    **unit_vec,
    *ang,*tmp,**x,**y,**z, **nz, **y_on_z, **ortho_y,
    **xmat,**T,**Tinv,**C,**Sinv,
    **R,**SR,**SRinv,**Cinv,**TMP1,**TMP2;

  ALLOC2D(xmat  ,5,5); nr_identf(xmat ,1,4,1,4);
  ALLOC2D(TMP1  ,5,5); nr_identf(TMP1 ,1,4,1,4);
  ALLOC2D(TMP2  ,5,5); nr_identf(TMP2 ,1,4,1,4);
  ALLOC2D(Cinv  ,5,5); nr_identf(Cinv ,1,4,1,4);
  ALLOC2D(SR    ,5,5); nr_identf(SR   ,1,4,1,4);
  ALLOC2D(SRinv ,5,5); nr_identf(SRinv,1,4,1,4);
  ALLOC2D(Sinv  ,5,5); nr_identf(Sinv ,1,4,1,4); 
  ALLOC2D(T     ,5,5); nr_identf(T    ,1,4,1,4);
  ALLOC2D(Tinv  ,5,5); nr_identf(Tinv ,1,4,1,4);
  ALLOC2D(C     ,5,5); nr_identf(C    ,1,4,1,4);
  ALLOC2D(R     ,5,5); nr_identf(R    ,1,4,1,4);

  ALLOC2D(center_of_rotation ,5,5);        /* make column vectors */
  ALLOC2D(result             ,5,5);
  ALLOC2D(unit_vec           ,5,5);
  ALLOC2D(x                  ,5,5);
  ALLOC2D(y                  ,5,5);
  ALLOC2D(z                  ,5,5);
  ALLOC2D(nz                 ,5,5);
  ALLOC2D(y_on_z             ,5,5);
  ALLOC2D(ortho_y            ,5,5);

  ALLOC(tmp ,4);
  ALLOC(ang ,4);

  for(i=0; i<=3; i++)        /* copy the input matrix */
    for(j=0; j<=3; j++)
      xmat[i+1][j+1] = (float)Transform_elem(*trans,i,j);

  /* -------------DETERMINE THE TRANSLATION FIRST! ---------  */

                                /* see where the center of rotation is displaced... */

  FILL_NR_COLVEC( center_of_rotation, center[0], center[1], center[2] );


  invertmatrix(4, xmat, TMP1);        /* get inverse of the matrix */

  matrix_multiply( 4, 4, 1, xmat, center_of_rotation, result); /* was TMP! in place of xmat */

  SUB_NR_COLVEC( result, result, center_of_rotation );

  for(i=0; i<=2; i++) 
    translations[i] = result[i+1][1];

  /* -------------NOW GET THE SCALING VALUES! ----------------- */

  for(i=0; i<=2; i++) 
    tmp[i+1] = -translations[i];
  translation_to_homogeneous(3, tmp, Tinv); 

  for(i=0; i<=2; i++) 
    tmp[i+1] = center[i];
  translation_to_homogeneous(3, tmp, C); 
  for(i=0; i<=2; i++) 
    tmp[i+1] = -center[i];
  translation_to_homogeneous(3, tmp, Cinv); 


  matrix_multiply(4,4,4, xmat, C, TMP1);    /* get scaling*shear*rotation matrix */


  matrix_multiply(4,4,4, Tinv, TMP1, TMP1);


  matrix_multiply(4,4,4, Cinv, TMP1,    SR);

  invertmatrix(4, SR, SRinv);        /* get inverse of scaling*shear*rotation */

                                /* find each scale by mapping a unit vector backwards,
                                   and finding the magnitude of the result. */
  FILL_NR_COLVEC( unit_vec, 1.0, 0.0, 0.0 );
  matrix_multiply( 4, 4, 1, SRinv, unit_vec, result);
  magnitude = MAG_NR_COLVEC( result );
  if (magnitude != 0.0) {
    scales[0] = 1/magnitude;
    Sinv[1][1] = magnitude;
  }
  else {
    scales[0] = 1.0;
    Sinv[1][1] = 1.0;
  }

  FILL_NR_COLVEC( unit_vec, 0.0, 1.0, 0.0 );
  matrix_multiply( 4, 4, 1, SRinv, unit_vec, result);
  magnitude = MAG_NR_COLVEC( result );
  if (magnitude != 0.0) {
    scales[1] = 1/magnitude;
    Sinv[2][2] = magnitude;
  }
  else {
    scales[1]  = 1.0;
    Sinv[2][2] = 1.0;
  }

  FILL_NR_COLVEC( unit_vec, 0.0, 0.0, 1.0 );
  matrix_multiply( 4, 4, 1, SRinv, unit_vec, result);
  magnitude = MAG_NR_COLVEC( result );
  if (magnitude != 0.0) {
    scales[2] = 1/magnitude;
    Sinv[3][3] = magnitude;
  }
  else {
    scales[2] = 1.0;
    Sinv[3][3] = 1.0;
  }

  /* ------------NOW GET THE SHEARS, using the info from above ----- */

  /* SR contains the [scale][shear][rot], must multiply [inv(scale)]*SR
     to get shear*rot. */

                                /* make [scale][rot] */
  matrix_multiply(4,4, 4, Sinv, SR,  TMP1);

                                /* get inverse of [scale][rot] */
  invertmatrix(4, TMP1, SRinv);        


  FILL_NR_COLVEC(x, SRinv[1][1], SRinv[2][1], SRinv[3][1]);
  FILL_NR_COLVEC(y, SRinv[1][2], SRinv[2][2], SRinv[3][2]);
  FILL_NR_COLVEC(z, SRinv[1][3], SRinv[2][3], SRinv[3][3]);



                                /* get normalized z direction  */
  magz = MAG_NR_COLVEC(z);
  SCALAR_MULT_NR_COLVEC( nz, z, 1/magz );

                                /* get a direction perpendicular 
                                   to z, in the yz plane.  */
  scalar = DOTSUM_NR_COLVEC(  y, nz );
  SCALAR_MULT_NR_COLVEC( y_on_z, nz, scalar );

  SUB_NR_COLVEC( result, y, y_on_z ); /* result = y - y_on_z */
  scalar = MAG_NR_COLVEC( result);     /* ortho_y = result ./ norm(result)  */
  SCALAR_MULT_NR_COLVEC( ortho_y, result, 1/scalar);


                                /* GET C for the skew matrix */

  scalar = DOTSUM_NR_COLVEC( y, nz ); /* project y onto z */
  magy   = MAG_NR_COLVEC(y);
  ci = scalar / sqrt((double)( magy*magy - scalar*scalar)) ;
                                /* GET B for the skew matrix */

                                /*    first need a1 */

  a1     = DOTSUM_NR_COLVEC( x, ortho_y ); /* project x onto ortho_y */
  magx   = MAG_NR_COLVEC(x);

                                /*    now get B  */

  scalar = DOTSUM_NR_COLVEC( x, nz );
  bi = scalar / sqrt((double)( magx*magx - scalar*scalar - a1*a1)) ;

                                /* GET A for skew matrix  */

  ai = a1 / sqrt((double)( magx*magx - scalar*scalar - a1*a1));

                                /* normalize the inverse shear parameters.
                                   so that there is no scaling in the matrix 
                                   (all scaling is already accounted for 
                                   in sx,sy and sz. */

  n1 = sqrt((double)(1 + ai*ai + bi*bi));
  n2 = sqrt((double)(1 + ci*ci));

  ai = ai / n1;
  bi = bi / n1;
  ci = ci / n2;

                                /* ai,bi,c1 now contain the parameters for 
                                   the inverse NORMALIZED shear matrix 
                                   (i.e., norm(col_i) = 1.0). */

  
  /* ------------NOW GET THE ROTATION ANGLES!----- */

                                  /*  since SR = [scale][shear][rot], then
                                    rot = [inv(shear)][inv(scale)][SR] */

  nr_identf(TMP1 ,1,4,1,4);        /* make inverse scale matrix */
  TMP1[1][1] = 1/scales[0];
  TMP1[2][2] = 1/scales[1];
  TMP1[3][3] = 1/scales[2];

  nr_identf(TMP2 ,1,4,1,4);        /* make_inverse normalized shear matrix */
  TMP2[1][1] = sqrt((double)(1 - ai*ai - bi*bi));
  TMP2[2][2] = sqrt((double)(1 - ci*ci));
  TMP2[2][1] = ai;
  TMP2[3][1] = bi;
  TMP2[3][2] = ci;


                                /* extract rotation matrix */
  matrix_multiply(4,4, 4, TMP2, TMP1, T);
  matrix_multiply(4,4, 4, T,    SR,   R);

                                /* get rotation angles */
  if (!rotmat_to_ang(R, ang)) {
    (void)fprintf(stderr,"Cannot convert R to radians!");
    printmatrix(3,3,R);
    return(FALSE);
  }

  for(i=0; i<=2; i++)
    rotations[i] = ang[i+1];

  /* ------------NOW ADJUST THE SCALE AND SKEW PARAMETERS ------------ */

  invertmatrix(4, T, Tinv);        /* get inverse of the matrix */
  

  scales[0] = Tinv[1][1];
  scales[1] = Tinv[2][2];
  scales[2] = Tinv[3][3];
  shears[0] = Tinv[2][1]/scales[1] ;
  shears[1] = Tinv[3][1]/scales[2] ;
  shears[2] = Tinv[3][2]/scales[2] ;
  

  FREE2D(xmat);
  FREE2D(TMP1);
  FREE2D(TMP2);
  FREE2D(Cinv);
  FREE2D(SR  );
  FREE2D(SRinv);
  FREE2D(Sinv);
  FREE2D(T   );
  FREE2D(Tinv);
  FREE2D(C   );
  FREE2D(R   );
  
  FREE2D(center_of_rotation);
  FREE2D(result            );
  FREE2D(unit_vec          );
  FREE2D(x                 );
  FREE2D(y                 );
  FREE2D(z                 );
  FREE2D(nz                );
  FREE2D(y_on_z            );
  FREE2D(ortho_y           );

  FREE(ang);
  FREE(tmp);

  return(TRUE);
}
示例#3
0
VIO_BOOL extract_parameters_from_matrix(VIO_Transform *trans,
                                              double *center,
                                              double *translations,
                                              double *scales,
                                              double *shears,
                                              double *rotations)
{
  int 
    i,j;

  float 
    magnitude,
    **center_of_rotation,
    **result,
    **unit_vec,
    *ang,*tmp,
    **xmat,**T,**Tinv,**C,**Sinv,**R,**SR,**SRinv,**Cinv,**TMP1,**TMP2;

  ALLOC2D(xmat  ,5,5); nr_identf(xmat ,1,4,1,4);
  ALLOC2D(TMP1  ,5,5); nr_identf(TMP1 ,1,4,1,4);
  ALLOC2D(TMP2  ,5,5); nr_identf(TMP2 ,1,4,1,4);
  ALLOC2D(Cinv  ,5,5); nr_identf(Cinv ,1,4,1,4);
  ALLOC2D(SR    ,5,5); nr_identf(SR   ,1,4,1,4);
  ALLOC2D(SRinv ,5,5); nr_identf(SRinv,1,4,1,4);
  ALLOC2D(Sinv  ,5,5); nr_identf(Sinv ,1,4,1,4); 
  ALLOC2D(T     ,5,5); nr_identf(T    ,1,4,1,4);
  ALLOC2D(Tinv  ,5,5); nr_identf(Tinv ,1,4,1,4);
  ALLOC2D(C     ,5,5); nr_identf(C    ,1,4,1,4);
  ALLOC2D(R     ,5,5); nr_identf(R    ,1,4,1,4);

  ALLOC2D(center_of_rotation ,5,5);        /* make column vectors */
  ALLOC2D(result             ,5,5);
  ALLOC2D(unit_vec           ,5,5);

  ALLOC(tmp ,4);
  ALLOC(ang ,4);


  for(i=0; i<=3; i++)        /* copy the input matrix */
    for(j=0; j<=3; j++)
      xmat[i+1][j+1] = (float)Transform_elem(*trans,i,j);

  

  /* -------------DETERMINE THE TRANSLATION FIRST! ---------  */

                                /* see where the center of rotation is displaced... */

  FILL_NR_COLVEC( center_of_rotation, center[0], center[1], center[2] );


  invertmatrix(4, xmat, TMP1);        /* get inverse of the matrix */

  matrix_multiply( 4, 4, 1, xmat, center_of_rotation, result); /* was TMP! in place of xmat */

  SUB_NR_COLVEC( result, result, center_of_rotation );

  for(i=0; i<=2; i++) 
    translations[i] = result[i+1][1];

  /* -------------NOW GET THE SCALING VALUES! ----------------- */

  for(i=0; i<=2; i++) 
    tmp[i+1] = -translations[i];
  translation_to_homogeneous(3, tmp, Tinv); 

  for(i=0; i<=2; i++) 
    tmp[i+1] = center[i];
  translation_to_homogeneous(3, tmp, C); 
  for(i=0; i<=2; i++) 
    tmp[i+1] = -center[i];
  translation_to_homogeneous(3, tmp, Cinv); 


  matrix_multiply(4,4,4, xmat, C, TMP1);    /* get scaling*rotation matrix */


  matrix_multiply(4,4,4, Tinv, TMP1, TMP1);


  matrix_multiply(4,4,4, Cinv, TMP1,    SR);

  invertmatrix(4, SR, SRinv);        /* get inverse of scaling*rotation */

                                /* find each scale by mapping a unit vector backwards,
                                   and finding the magnitude of the result. */
  FILL_NR_COLVEC( unit_vec, 1.0, 0.0, 0.0 );
  matrix_multiply( 4, 4, 1, SRinv, unit_vec, result);
  magnitude = MAG_NR_COLVEC( result );
  if (magnitude != 0.0) {
    scales[0] = 1/magnitude;
    Sinv[1][1] = magnitude;
  }
  else {
    scales[0] = 1.0;
    Sinv[1][1] = 1.0;
  }

  FILL_NR_COLVEC( unit_vec, 0.0, 1.0, 0.0 );
  matrix_multiply( 4, 4, 1, SRinv, unit_vec, result);
  magnitude = MAG_NR_COLVEC( result );
  if (magnitude != 0.0) {
    scales[1] = 1/magnitude;
    Sinv[2][2] = magnitude;
  }
  else {
    scales[1]  = 1.0;
    Sinv[2][2] = 1.0;
  }

  FILL_NR_COLVEC( unit_vec, 0.0, 0.0, 1.0 );
  matrix_multiply( 4, 4, 1, SRinv, unit_vec, result);
  magnitude = MAG_NR_COLVEC( result );
  if (magnitude != 0.0) {
    scales[2] = 1/magnitude;
    Sinv[3][3] = magnitude;
  }
  else {
    scales[2] = 1.0;
    Sinv[3][3] = 1.0;
  }

  /* ------------NOW GET THE ROTATION ANGLES!----- */

                                /* extract rotation matrix */
  matrix_multiply(4,4, 4, Sinv, SR,   R);

                                /* get rotation angles */
  if (!rotmat_to_ang(R, ang)) {
    (void)fprintf(stderr,"Cannot convert R to radians!");
    printmatrix(3,3,R);
    return(FALSE);
  }

  for(i=0; i<=2; i++)
    rotations[i] = ang[i+1];


  FREE2D(xmat);
  FREE2D(TMP1);
  FREE2D(TMP2);
  FREE2D(Cinv);
  FREE2D(SR  );
  FREE2D(SRinv);
  FREE2D(Sinv);
  FREE2D(T   );
  FREE2D(Tinv);
  FREE2D(C   );
  FREE2D(R   );
  
  FREE2D(center_of_rotation);
  FREE2D(result            );
  FREE2D(unit_vec          );

  FREE(ang);
  FREE(tmp);

  return(TRUE);
}
示例#4
0
/* ----------------------------- MNI Header -----------------------------------
@NAME       : build_inverse_transformation_matrix_quater
@INPUT      : center, translations, scales, quaternions
@OUTPUT     : the inverse linear transformation matrix of mat:
                since mat = (T)(C)(SH)(S)(R)(-C), then

                invmat = (C)(inv(r))(inv(S))(inv(SH))(-C)(-T)

@RETURNS    : nothing
@DESCRIPTION: 
               the matrix is to be  PREmultiplied with a vector (mat*vec)
               when used in the application
               same as build_inverse_transformation_matrix but with quaternions
@METHOD     : 
@GLOBALS    : 
@CALLS      : 
@CREATED    : Thr Apr 18 10:45:56 EST 2002 pln
@MODIFIED   : 
---------------------------------------------------------------------------- */
void build_inverse_transformation_matrix_quater(VIO_Transform *trans,
                                                       double *center,
                                                       double *translations,
                                                       double *scales,
                                                       double *shears,
                                                       double *quaternions)
{
  float
    **T,
    **SH,
    **S,
    **R,
    **C,
    **T1,
    **T2,
    **T3,
    **T4;

  int
    i,j;
  
  ALLOC2D(T   ,5,5);
  ALLOC2D(SH  ,5,5);
  ALLOC2D(S   ,5,5);
  ALLOC2D(R   ,5,5);
  ALLOC2D(C   ,5,5);
  ALLOC2D(T1  ,5,5);
  ALLOC2D(T2  ,5,5);
  ALLOC2D(T3  ,5,5);
  ALLOC2D(T4  ,5,5);
  
                                /* invmat = (C)(inv(r))(inv(S))(inv(SH))(-C)(-T)
                                   mat = (T)(C)(SH)(S)(R)(-C) */

  nr_identf(T,1,4,1,4);                     /* make (-T)(-C) */
  for(i=0; i<3; i++) {
    T[1+i][4] = -translations[i] - center[i];                
  }

  

  build_rotmatrix(T1,quaternions); /* make rotation matrix from quaternions */
  transpose(4,4,T1,R);
  

  make_shears(T1,shears);        /* make shear rotation matrix */
  invertmatrix(4, T1, SH);        /* get inverse of the matrix */

                                /* make scaling matrix */
  nr_identf(S,1,4,1,4);                   
  for(i=0; i<3; i++) {
    if (scales[i] != 0.0)
      S[1+i][1+i] = 1/scales[i];
    else
      S[1+i][1+i] = 1.0;
  }

  nr_identf(C,1,4,1,4);      /* make center          */
  for(i=0; i<3; i++) {
    C[1+i][4] = center[i];                
  }

  nr_multf(C,1,4,1,4,  R ,1,4,1,4, T1 );  
  nr_multf(T1,1,4,1,4, SH,1,4,1,4, T2 );  
  nr_multf(T2,1,4,1,4, S ,1,4,1,4, T3 );  
  nr_multf(T3,1,4,1,4, T ,1,4,1,4, T4 );  

  for(i=0; i<4; i++)
    for(j=0; j<4; j++)
      Transform_elem(*trans, i, j ) = T4[i+1][j+1];

  FREE2D(T    );
  FREE2D(SH   );
  FREE2D(S    );
  FREE2D(R    );
  FREE2D(C );
  FREE2D(T1   );
  FREE2D(T2   );
  FREE2D(T3   );
  FREE2D(T4   );
}
示例#5
0
void build_transformation_matrix_quater(VIO_Transform *trans,
                                               double *center,
                                               double *translations,
                                               double *scales,
                                               double *shears,
                                               double *quaternions)
{
  
  float
    **T,
    **SH,
    **S,
    **R,
    **C,
    **T1,
    **T2,
    **T3,
    **T4;

  double normal;


  int
    i,j;
  
  ALLOC2D(T  ,5,5);
  ALLOC2D(SH ,5,5);
  ALLOC2D(S  ,5,5);
  ALLOC2D(R  ,5,5);
  ALLOC2D(C  ,5,5);
  ALLOC2D(T1 ,5,5);
  ALLOC2D(T2 ,5,5);
  ALLOC2D(T3 ,5,5);
  ALLOC2D(T4 ,5,5);
  
 
  


  
  normal=(quaternions[0]*quaternions[0] + quaternions[1]*quaternions[1] + quaternions[2]*quaternions[2] + quaternions[3]*quaternions[3]);
  if (normal>1){
   for(i = 0; i < 4; i++){
      quaternions[i] /= normal;
   }} 
   
   

                        /* mat = (T)(C)(SH)(S)(R)(-C) */

  nr_identf(T,1,4,1,4);



                                             /* make (T)(C) */
  for(i=0; i<3; i++) {
    T[1+i][4] = translations[i] + center[i];                
  }
   
  

  build_rotmatrix(R,quaternions); /* make rotation matrix from quaternions */
  

                                /* make shear rotation matrix */
  make_shears(SH, shears);

                                /* make scaling matrix */
  nr_identf(S,1,4,1,4);                   
  for(i=0; i<3; i++) {
    S[1+i][1+i] = scales[i];
  }


  nr_identf(C,1,4,1,4);      /* make center          */
  for(i=0; i<3; i++) {
    C[1+i][4] = -center[i];                
  }

  nr_multf(T, 1,4,1,4, S  ,1,4,1,4, T1 );  
  nr_multf(T1,1,4,1,4, SH ,1,4,1,4, T2 );  
  nr_multf(T2,1,4,1,4, R  ,1,4,1,4, T3 );  
  nr_multf(T3,1,4,1,4, C  ,1,4,1,4, T4 );  

  for(i=0; i<4; i++)
    for(j=0; j<4; j++)
      Transform_elem(*trans, i, j ) = T4[i+1][j+1];

  FREE2D(T    );
  FREE2D(SH   );
  FREE2D(S    );
  FREE2D(R    );
  FREE2D(C );
  FREE2D(T1   );
  FREE2D(T2   );
  FREE2D(T3   );
  FREE2D(T4   );
}
示例#6
0
void build_transformation_matrix(VIO_Transform *trans,
                                        double *center,
                                        double *translations,
                                        double *scales,
                                        double *shears,
                                        double *rotations)
{
  
  float
    **T,
    **SH,
    **S,
    **R,
    **C,
    **T1,
    **T2,
    **T3,
    **T4;
  int
    i,j;
  
  ALLOC2D(T  ,5,5);
  ALLOC2D(SH ,5,5);
  ALLOC2D(S  ,5,5);
  ALLOC2D(R  ,5,5);
  ALLOC2D(C  ,5,5);
  ALLOC2D(T1 ,5,5);
  ALLOC2D(T2 ,5,5);
  ALLOC2D(T3 ,5,5);
  ALLOC2D(T4 ,5,5);
  
                                             /* mat = (T)(C)(SH)(S)(R)(-C) */

  nr_identf(T,1,4,1,4);                     /* make (T)(C) */
  for(i=0; i<3; i++) {
    T[1+i][4] = translations[i] + center[i];                
  }
                                /* make rotation matix */
  make_rots(R,
            (float)(rotations[0]),
            (float)(rotations[1]),
            (float)(rotations[2])); 

                                /* make shear rotation matrix */
  make_shears(SH, shears);

                                /* make scaling matrix */
  nr_identf(S,1,4,1,4);                   
  for(i=0; i<3; i++) {
    S[1+i][1+i] = scales[i];
  }

  nr_identf(C,1,4,1,4);      /* make center          */
  for(i=0; i<3; i++) {
    C[1+i][4] = -center[i];                
  }

  nr_multf(T, 1,4,1,4, S  ,1,4,1,4, T1 );  
  nr_multf(T1,1,4,1,4, SH ,1,4,1,4, T2 );  
  nr_multf(T2,1,4,1,4, R  ,1,4,1,4, T3 );  
  nr_multf(T3,1,4,1,4, C  ,1,4,1,4, T4 );  

  for(i=0; i<4; i++)
    for(j=0; j<4; j++)
      Transform_elem(*trans, i, j ) = T4[i+1][j+1];

  FREE2D(T    );
  FREE2D(SH   );
  FREE2D(S    );
  FREE2D(R    );
  FREE2D(C );
  FREE2D(T1   );
  FREE2D(T2   );
  FREE2D(T3   );
  FREE2D(T4   );
}
示例#7
0
/* parses options and stores the main game loop */
int main(int argc, char **argv)
{
    /* init ncurses environment */
    initscr();
    cbreak();
    noecho();
    curs_set(FALSE);

    /* init variables */
    file = ".hs2048g";
    hs = 0;
    s  = 0;
    sl = 0;
    SZ = 4;
    MAXVAL = 4;
    CALLOC2D(g, SZ);

    load_score();
    int n_blocks = 1;
    
    /* parse options */
    int c;
    while ((c = getopt(argc, argv, "rchs:b:")) != -1) {
        switch (c) {
            // color support - assumes your terminal can display colours
            // should still work regardless
            case 'c':
                start_color();
                init_pair(1, 1, 0);
                init_pair(2, 2, 0);
                init_pair(3, 3, 0);
                init_pair(4, 4, 0);
                init_pair(5, 5, 0);
                init_pair(6, 6, 0);
                init_pair(7, 7, 0);
                break;
            // different board sizes
            case 's':
                FREE2D(g, SZ);
                int optint = atoi(optarg);
                SZ = optint > 4 ? optint : 4;
                CALLOC2D(g, SZ);
                break;
            // different block spawn rate
            case 'b':
                n_blocks = atoi(optarg);
                break;
            // reset hiscores
            case 'r':
                endwin();
                printf("Are you sure you want to reset your highscores? (Y)es or (N)o\n");
                int response;
                if ((response = getchar()) == 'y' || response == 'Y') {
                    FILE *fd = fopen(file, "w+");
                    fclose(fd);
                }
                exit(EXIT_SUCCESS);
            // help menu
            case 'h':
                endwin();
                printf("Controls:\n"
                       "    hjkl, wasd      Movement\n"
                       "    q               Quit\n"
                       "\n"
                       "Usage:\n"
                       "    2048 [options]\n"
                       "\n"
                       "Options:\n"
                       "    -s <size>       Set the grid border length\n"
                       "    -b <rate>       Set the block spawn rate\n"
                       "    -c              Enables color support\n");
                exit(EXIT_SUCCESS);
        }
    }
    
    int width  = SZ * (MAXVAL + 2) + 1;
    int height = SZ * (MAXVAL + 2) + 3;

    // might center in middle of screen
    WINDOW *gamewin = newwin(height, width, 1, 1);
    keypad(gamewin, TRUE);

    /* random seed */
    srand((unsigned int)time(NULL));
    ITER(2, rand_block());
    draw_grid(gamewin);

    int key, moved;
    while (1) {
        /* will goto this if we didn't get a valid keypress */
        retry:;
        moved = 0;
        key = wgetch(gamewin);
        sl = 0;

        /* should check if anything changed during merge and if not retry */
        switch (key) {
            case 'h':
            case 'a':
            case KEY_LEFT:
                moved = TURN(DL);
                break;
            case 'l':
            case 'd':
            case KEY_RIGHT:
                moved = TURN(DR);
                break;
            case 'j':
            case 's':
            case KEY_DOWN:
                moved = TURN(DD);
                break;
            case 'k':
            case 'w':
            case KEY_UP:
                moved = TURN(DU);
                break;
            case 'q':
                FREE2D(g, SZ);
                erase();
                refresh();
                endwin();
                save_score();
                exit(EXIT_SUCCESS);
            default:
                goto retry;
        }
        
        if (!moves_available()) {
            endwin();
            printf("\n"
                   "YOU LOSE! - Your score was %d\n", s);
            save_score();
            exit(EXIT_SUCCESS);
        }

        if (moved) {
            ITER(n_blocks, rand_block());
            draw_grid(gamewin);
        }
    }
}
示例#8
0
BICAPI  BOOLEAN  singular_value_decomposition(
    int    m,
    int    n,
    Real   **a,
    Real   w[],
    Real   **v )
{
  
  int i,j;
  BOOLEAN val;
  char jobu = 'O';
  char jobvt = 'A';
  long int _m = (long int) m;
  long int _n = (long int) n;

  long int lda = _m;  
  long int ldu = _m;
  long int ldvt = _n;
  long int lwork = MAX(3*MIN(_m,_n)+MAX(_m,_n),5*MIN(_m,_n));
  Real** _a;
  Real* work;
  Real** _u;
  Real** _v;
  long int info;
  Real temp;

  ALLOC(work,(int) lwork);
  ALLOC2D(_a,n,m);
  ALLOC2D(_u,n,m);
  ALLOC2D(_v,n,n);

  for (j = 0; j < n; j++) {    
    for (i = 0; i < m; i++) {
      _a[j][i] = a[i][j];
    }
  }
  

  val = bicpl_dgesvd_(&jobu, &jobvt, &_m, &_n, (Real*) *_a, &lda, (Real*) w, 
		(Real*) *_u, &ldu, (Real*) *_v, &ldvt, 
		(Real*) work, &lwork, &info);
      
  for (j = 0; j < n; j++) {    
    for (i = 0; i < m; i++) {
      a[i][j] = _a[j][i];
    }
  }

  for (j = 0; j < n; j++) {    
    for (i = 0; i < n; i++) {
      v[i][j] = _v[i][j];
    }
  }

  FREE(work);
  FREE2D(_u);
  FREE2D(_v);
  FREE2D(_a);
  
  return val;  
}
示例#9
0
int main(int argc, char *argv[])
{
  union
    {
      long   l;
      char   c[4];
    } seedval;
  
  time_t t;
  char tmp;
  
  char 
    *in_tag, *out_tag, **labels;
  int 
    i,j,n_vols, n_points,
    *struc_ids, *pat_ids;
  VIO_Real
    std,**tags1, **tags2, 
    *weights;

  t = 2*time(NULL);
  seedval.l = t; 
  
  tmp = seedval.c[0]; seedval.c[0] = seedval.c[3]; seedval.c[3] = tmp; 
  tmp = seedval.c[1]; seedval.c[1] = seedval.c[2]; seedval.c[2] = tmp;
  
  srand48(seedval.l);
  
  if (argc!=4) {
    (void) fprintf(stderr, "Usage: randomize_tags in.tag out.tag std\n",
                   argv[0]);
      exit(EXIT_FAILURE);
  }

  prog_name = argv[0];
  in_tag    = argv[1];
  out_tag   = argv[2];
  std       = atof( argv[3] );

  input_tag_file(in_tag, 
                 &n_vols, &n_points, 
                 &tags1, &tags2, 
                 &weights, &struc_ids, &pat_ids, &labels);

  for(i=0; i<n_points; i++)
    for(j=0; j<3; j++)
      tags1[i][j] += gaussian_random_w_std(std);
  
  output_tag_file(out_tag, "Target (1st vol) points have been randomized",
                 n_vols, n_points, 
                 tags1, tags2, 
                 weights, struc_ids, pat_ids, labels);
                 
  FREE2D(tags1);
  FREE2D(tags2);
  FREE(weights);
  FREE(struc_ids);
  FREE(pat_ids);
  FREE2D(labels);

  exit(EXIT_SUCCESS);
}