GLYLIB
0.3.0b
|
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 }