GLYLIB  0.3.0b
rotate_vector_to_Z.c
Go to the documentation of this file.
00001 // Function written by B. Lachele Foley, 2007
00002 #include <mylib.h>
00003 #include <molecules.h>
00004 //#include "../inc/mylib.h"
00005 //#include "../inc/molecules.h"
00006 /* This function rotates the coordinate system so that the
00007 z-axis is aligned with the specified vector.  The x and y axes
00008 are in the proper plane, but their exact position within that
00009 plane is determined somewhat arbitrarily.   
00010 
00011 There are two versions of the function.  Note that the meaning 
00012 of the input integer is different in the two functions.  In each
00013 function, the program will check for memory available and exit 
00014 with complaint if it doesn't find enough.
00015 
00016 The first works on a list of coord_3D coordinate sets. 
00017 
00018         void rotate_vector_to_Z_list(coord_3D* XS,int n,vectormag_3D v)
00019 
00020         *XS = pointer to list of coordinates to rotate
00021           n = number of coordinates in list XS to rotate
00022           v = the vector into which the z axis should be rotated.
00023 
00024 Note that it will overwrite the coordinates you send to it.  So, if
00025 you want to keep a copy of the originals, do that first.  The
00026 int, here, is the number of coordinates pointed to by the 
00027 coord_3D pointer.  
00028 
00029 The second works on all the coordinate sets for a given molecule. 
00030 
00031         void rotate_vector_to_Z_M(molecule *m,int xs, int xl,int vs,int vl,vectormag_3D v)
00032 
00033           m = a molecule structure (see molecules.h)
00034          xs = the position of the initial coordinates in the molecule structure 
00035                 if xs==-1 then the coords are in m.x.  If xs>=0, then
00036                 the coords are in m.xa[xs].
00037          xl = the position in the structure where you want the new
00038                 coords to go; same rules as for xs
00039          vs = the initial set of vectors to rotate.  If you don't need
00040                 vectors rotated, set this to -1.
00041          vl = the position in the array (m.v[vl]) where the rotated
00042                 vectors should go.  Set to -1 for no vector rotation.
00043           v = the vector into which the z axis should be rotated.
00044 
00045 */
00046 /******************* rotate_vector_to_Z_list() *****************/
00047 void rotate_vector_to_Z_list(coord_3D* XS,int n,vectormag_3D v){
00048 int ra=0;
00049 vectormag_3D cX,cY,cZ; // direction cosines for X Y and Z
00050 coord_3D RC; // temporary coords
00051 
00052 // If the requested direction already points along z
00053 if((v.i==0)&&(v.j==0)){ return; }
00054 
00055 // get direction cosines for unit vector along new Z axis (the rotation axis)
00056 cZ=normalize_vec(v);
00057 if(cZ.d==0){mywhine("zero-length vector passed to rotate_vector_to_Z (can't rotate to that)");}
00058 
00059 if(cZ.j!=0){ // if the j component of the target direction isn't zero
00060         // set abitrary point in new XY plane for positive Y position
00061         cY.i=cZ.i; // set xY=iZ
00062         cY.k=cZ.k; // set zY=kZ
00063         cY.j=-(cZ.k*cZ.k+cZ.i*cZ.i)/cZ.j;  ; // solve for yY in X-Y plane
00064         // turn that into a unit vector (make into direction cosines)
00065         cY=normalize_vec(cY); 
00066         // get direction cosines for unit vector along new X axis
00067         // (this is the X-prod of the new Y and Z axes)
00068         cX=get_crossprod(cY,cZ); // note ordering looks backwards...
00069         }
00070 else{ // the i component isn't zero (or we would have exited)
00071         // set abitrary point in new XY plane for positive X position
00072         cX.j=cZ.j; // set yX=jZ, which is zero or we wouldn't be here...
00073         cX.k=cZ.k; // set zX=kZ
00074         cX.i=-(cZ.k*cZ.k)/cZ.i;  ; // solve for yY in X-Y plane
00075         // turn that into a unit vector (make into direction cosines)
00076         cX=normalize_vec(cX); 
00077         // get direction cosines for unit vector along new X axis
00078         // (this is the X-prod of the new Y and Z axes)
00079         cY=get_crossprod(cZ,cX);
00080         }
00081 
00082 // rotate molecule 
00083 for(ra=0;ra<n;ra++){ // for each residue
00084         RC.i=cX.i*XS[ra].i + cX.j*XS[ra].j + cX.k*XS[ra].k;
00085         RC.j=cY.i*XS[ra].i + cY.j*XS[ra].j + cY.k*XS[ra].k;
00086         RC.k=cZ.i*XS[ra].i + cZ.j*XS[ra].j + cZ.k*XS[ra].k;
00087         XS[ra]=RC;
00088         }
00089 
00090 return;
00091 }
00092 
00093 /******************* rotate_vector_to_Z_M() *****************/
00094 void rotate_vector_to_Z_M(molecule *m,int xs, int xl,int vs,int vl,vectormag_3D v){
00095 int ra=0,rb=0,localdebug=0;;
00096 vectormag_3D cX,cY,cZ,RV; // direction cosines for X Y and Z
00097 residue *R; // residue pointer for convenience
00098 coord_3D RC;
00099 
00100 // get direction cosines for unit vector along new Z axis (the rotation axis)
00101 if(localdebug>=2){
00102 printf("in rotate_vector_to_Z_M xs is %d ; xl is %d ; vs is %d ; vl is %d \n",xs,xl,vs,vl);
00103 printf("normalizing rotation vector.  Before (v) \n");
00104 dprint_vectormag_3D(&v);
00105 }
00106 
00107 
00108 // If the requested direction already points along z
00109 if((v.i==0)&&(v.j==0)){ return; }
00110 
00111 // get direction cosines for unit vector along new Z axis (the rotation axis)
00112 cZ=normalize_vec(v);
00113 if(localdebug>=2){
00114 printf("normalizing rotation vector.  After (cZ)\n");
00115 dprint_vectormag_3D(&cZ);
00116 }
00117 if(cZ.d==0){mywhine("zero-length vector passed to rotate_vector_to_Z (can't rotate to that)");}
00118 
00119 if(cZ.j!=0){ // if the j component of the target direction isn't zero
00120         // set abitrary point in new XY plane for positive Y position
00121         cY.i=cZ.i; // set xY=iZ
00122         cY.k=cZ.k; // set zY=kZ
00123         cY.j=-(cZ.k*cZ.k+cZ.i*cZ.i)/cZ.j;  ; // solve for yY in X-Y plane
00124         // turn that into a unit vector (make into direction cosines)
00125 if(localdebug>=2){
00126 printf("normalizing Y axis vector. Before:\n");
00127 dprint_vectormag_3D(&cY);
00128 }
00129         cY=normalize_vec(cY); 
00130 if(localdebug>=2){
00131 printf("normalized Y axis vector:\n");
00132 dprint_vectormag_3D(&cY);
00133 }
00134         // get direction cosines for unit vector along new X axis
00135         // (this is the X-prod of the new Y and Z axes)
00136         cX=get_crossprod(cY,cZ); // note ordering looks backwards...
00137 if(localdebug>=2){
00138 printf("Just got X axis vector:\n");
00139 dprint_vectormag_3D(&cX);
00140 }
00141         }
00142 else{ // the i component isn't zero (or we would have exited)
00143         // set abitrary point in new XY plane for positive X position
00144         cX.j=cZ.j; // set yX=jZ, which is zero or we wouldn't be here...
00145         cX.k=cZ.k; // set zX=kZ
00146         cX.i=-(cZ.k*cZ.k)/cZ.i;  ; // solve for yY in X-Y plane
00147         // turn that into a unit vector (make into direction cosines)
00148 if(localdebug>=2){
00149 printf("normalizing X axis vector (cZ.j=0).  Before:\n");
00150 dprint_vectormag_3D(&cX);
00151 }
00152         cX=normalize_vec(cX); 
00153 if(localdebug>=2){
00154 printf("normalized X axis vector:\n");
00155 dprint_vectormag_3D(&cX);
00156 }
00157         // get direction cosines for unit vector along new X axis
00158         // (this is the X-prod of the new Y and Z axes)
00159         cY=get_crossprod(cZ,cX);
00160 if(localdebug>=2){
00161 printf("Just got Y axis vector:\n");
00162 dprint_vectormag_3D(&cY);
00163 }
00164         }
00165 
00166 
00167 //dprint_molecule(&m[0],24);
00168 //dprint_residue(&m[0].r[0],24);
00169 //printf("m[0].nr is %d\n",m[0].nr);
00170 
00171 // rotate molecule 
00172 if((xs==-1)&&(xl==-1)){ //this makes code harder to read, but execution faster
00173 if(localdebug>=2){
00174 printf("(xs==-1)&&(xl==-1)\n");
00175 printf("m[0].nr is %d\n",m[0].nr);
00176 }
00177 for(ra=0;ra<m[0].nr;ra++){ // for each residue
00178         R=&m[0].r[ra]; // this isn't necessary, and certainly slows the execution 
00179                 //by a few nanoseconds, bit it makes reading the code a bit easier
00180         for(rb=0;rb<R[0].na;rb++){ // for each atom
00181                 RC.i=cX.i*R[0].a[rb].x.i + cX.j*R[0].a[rb].x.j + cX.k*R[0].a[rb].x.k;
00182                 RC.j=cY.i*R[0].a[rb].x.i + cY.j*R[0].a[rb].x.j + cY.k*R[0].a[rb].x.k;
00183                 RC.k=cZ.i*R[0].a[rb].x.i + cZ.j*R[0].a[rb].x.j + cZ.k*R[0].a[rb].x.k;
00184                 R[0].a[rb].x=RC;
00185 if(localdebug>=2){dprint_coord_3D(&R[0].a[rb].x); }
00186                 } // for each atom
00187         } // for each residue
00188         }
00189 if((xs!=-1)&&(xl==-1)){ //this makes code harder to read, but execution faster
00190 for(ra=0;ra<m[0].nr;ra++){ // for each residue
00191         R=&m[0].r[ra]; // this isn't necessary, and certainly slows the execution 
00192                 //by a few nanoseconds, bit it makes reading the code a bit easier
00193         for(rb=0;rb<R[0].na;rb++){ // for each atom
00194                 RC.i=cX.i*R[0].a[rb].xa[xs].i + cX.j*R[0].a[rb].xa[xs].j + cX.k*R[0].a[rb].xa[xs].k;
00195                 RC.j=cY.i*R[0].a[rb].xa[xs].i + cY.j*R[0].a[rb].xa[xs].j + cY.k*R[0].a[rb].xa[xs].k;
00196                 RC.k=cZ.i*R[0].a[rb].xa[xs].i + cZ.j*R[0].a[rb].xa[xs].j + cZ.k*R[0].a[rb].xa[xs].k; 
00197                 R[0].a[rb].x=RC;
00198 if(localdebug>=2){dprint_coord_3D(&R[0].a[rb].x); }
00199                 } // for each atom
00200         } // for each residue
00201         }
00202 if((xs==-1)&&(xl!=-1)){ //this makes code harder to read, but execution faster
00203 for(ra=0;ra<m[0].nr;ra++){ // for each residue
00204         R=&m[0].r[ra]; // this isn't necessary, and certainly slows the execution 
00205                 //by a few nanoseconds, bit it makes reading the code a bit easier
00206         for(rb=0;rb<R[0].na;rb++){ // for each atom
00207                 RC.i=cX.i*R[0].a[rb].x.i + cX.j*R[0].a[rb].x.j + cX.k*R[0].a[rb].x.k;
00208                 RC.j=cY.i*R[0].a[rb].x.i + cY.j*R[0].a[rb].x.j + cY.k*R[0].a[rb].x.k;
00209                 RC.k=cZ.i*R[0].a[rb].x.i + cZ.j*R[0].a[rb].x.j + cZ.k*R[0].a[rb].x.k; 
00210                 R[0].a[rb].xa[xl]=RC;
00211 if(localdebug>=2){dprint_coord_3D(&R[0].a[rb].x); }
00212                 } // for each atom
00213         } // for each residue
00214         }
00215 if((xs!=-1)&&(xl!=-1)){ //this makes code harder to read, but execution faster
00216 for(ra=0;ra<m[0].nr;ra++){ // for each residue
00217         R=&m[0].r[ra]; // this isn't necessary, and certainly slows the execution 
00218                 //by a few nanoseconds, bit it makes reading the code a bit easier
00219         for(rb=0;rb<R[0].na;rb++){ // for each atom
00220 
00221                 RC.i=cX.i*R[0].a[rb].xa[xs].i + cX.j*R[0].a[rb].xa[xs].j + cX.k*R[0].a[rb].xa[xs].k;
00222                 RC.j=cY.i*R[0].a[rb].xa[xs].i + cY.j*R[0].a[rb].xa[xs].j + cY.k*R[0].a[rb].xa[xs].k;
00223                 RC.k=cZ.i*R[0].a[rb].xa[xs].i + cZ.j*R[0].a[rb].xa[xs].j + cZ.k*R[0].a[rb].xa[xs].k; 
00224                 R[0].a[rb].xa[xl]=RC; 
00225 if(localdebug>=2){dprint_coord_3D(&R[0].a[rb].x); }
00226                 } // for each atom
00227         } // for each residue
00228         }
00229 
00230 
00231 // if vector rotation is specified
00232 if((vs>=0)&&(vl>=0)){
00233 for(ra=0;ra<m[0].nr;ra++){ // for each residue
00234         R=&m[0].r[ra]; // this isn't necessary, and certainly slows the execution 
00235                 //by a few nanoseconds, bit it makes reading the code a bit easier
00236         for(rb=0;rb<R[0].na;rb++){ // for each atom
00237                 RV.i=cX.i*R[0].a[rb].v[vs].i + cX.j*R[0].a[rb].v[vs].j + cX.k*R[0].a[rb].v[vs].k;
00238                 RV.j=cY.i*R[0].a[rb].v[vs].i + cY.j*R[0].a[rb].v[vs].j + cY.k*R[0].a[rb].v[vs].k;
00239                 RV.k=cZ.i*R[0].a[rb].v[vs].i + cZ.j*R[0].a[rb].v[vs].j + cZ.k*R[0].a[rb].v[vs].k; 
00240                 RV.d=get_magnitude(RV); // not that it should change...
00241                 R[0].a[rb].v[vl]=RV; 
00242 if(localdebug>=2){
00243         printf("Source (%d), intermediate and rotated (%d) vectors for set %d:\n",vs,vl,rb);
00244         dprint_vectormag_3D(&R[0].a[rb].v[vs]); 
00245         dprint_vectormag_3D(&RV); 
00246         dprint_vectormag_3D(&R[0].a[rb].v[vl]); 
00247         }
00248                 } // for each atom
00249         } // for each residue
00250         }
00251 
00252 return;
00253 } 
 All Classes Files Functions Variables Typedefs Defines