GLYLIB  0.3.0b
rotations.c
Go to the documentation of this file.
00001 /* 
00002  * Functions for rotation about an axis
00003  *
00004  * author: Robert Davis
00005  *      integrated with glylib by BLFoley 20110405
00006  */
00007 
00008 #include <mylib.h>
00009 #include <molecules.h>
00010 #include <geometries.h>
00011 
00012 /** Create a rotation matrix for a rotation of theta degrees
00013  * about an axis through the given point in the given direction
00014  */
00015 double *
00016 create_rotation_matrix(coord_3D point, vectormag_3D direction, double theta)
00017 {
00018     direction=normalize_vec(direction);
00019     if(direction.d==0){fprintf(stderr,"Attempting to rotate about a vector of zero length in create_rotation_matrix.  Ignoring.\n");}
00020     double u = direction.i;
00021     double v = direction.j;
00022     double w = direction.k;
00023 
00024     double a = point.i;
00025     double b = point.j;
00026     double c = point.k;
00027 
00028     double *matrix = (double *)malloc(12 * sizeof(double));
00029     double u2 = u*u;
00030     double v2 = v*v;
00031     double w2 = w*w;
00032     double cosT = cos(theta);
00033     double sinT = sin(theta);
00034  
00035     matrix[3] = a*(v2 + w2) - u*(b*v + c*w)
00036                  + (u*(b*v + c*w) - a*(v2 + w2))*cosT + (b*w - c*v)*sinT;
00037 
00038     matrix[7] = b*(u2 + w2) - v*(a*u + c*w)
00039                 + (v*(a*u + c*w) - b*(u2 + w2))*cosT + (c*u - a*w)*sinT;
00040 
00041     matrix[11] = c*(u2 + v2) - w*(a*u + b*v)
00042                  + (w*(a*u + b*v) - c*(u2 + v2))*cosT + (a*v - b*u)*sinT;
00043 
00044     matrix[0] = (u2 + (v2 + w2) * cosT);
00045     matrix[1] = (u*v * (1 - cosT) - w*sinT);
00046     matrix[2] = (u*w * (1 - cosT) + v*sinT);
00047 
00048     matrix[4] = (u*v * (1 - cosT) + w*sinT);
00049     matrix[5] = (v2 + (u2 + w2) * cosT);
00050     matrix[6] = (v*w * (1 - cosT) - u*sinT);
00051 
00052     matrix[8] = (u*w * (1 - cosT) - v*sinT);
00053     matrix[9] = (v*w * (1 - cosT) + u*sinT);
00054     matrix[10] = (w2 + (u2 + v2) * cosT);
00055 
00056     return matrix;
00057 }
00058 
00059 void
00060 destroy_rotation_matrix(double *matrix)
00061 {
00062     free(matrix);
00063 }
00064 
00065 void
00066 apply_rotation_matrix_to_coord_p(coord_3D *c, double *matrix)
00067 {
00068     coord_3D temp = *c;
00069 
00070     c->i = matrix[0]*temp.i + matrix[1]*temp.j + matrix[2]*temp.k + matrix[3];
00071     c->j = matrix[4]*temp.i + matrix[5]*temp.j + matrix[6]*temp.k + matrix[7];
00072     c->k = matrix[8]*temp.i + matrix[9]*temp.j + matrix[10]*temp.k + matrix[11];
00073 }
00074 
00075 void 
00076 rotate_coords_about_axis_dp_list(coord_3D **coords, int num_coords, coord_3D point, 
00077               vectormag_3D direction, double theta)
00078 {
00079     int i;
00080     double *matrix;
00081 
00082     matrix = create_rotation_matrix(point, direction, theta);
00083     for(i = 0; i < num_coords; i++)
00084         apply_rotation_matrix_to_coord_p(coords[i], matrix);
00085 
00086     destroy_rotation_matrix(matrix);
00087 }
00088 
00089 coord_3D
00090 get_cartesian_point_from_internal_coords(coord_3D a, coord_3D b, coord_3D c,
00091                       double theta, double phi, double distance)
00092 {
00093     vectormag_3D lmn_x, lmn_y, lmn_z;
00094     double x_p, y_p, z_p;
00095 
00096     vectormag_3D cb = get_vector_from_coords(c, b);
00097     vectormag_3D ba = get_vector_from_coords(b, a);
00098 
00099     lmn_y = normalize_vec(get_crossprod(ba, cb));
00100     lmn_z = normalize_vec(cb);
00101     lmn_x = get_crossprod(lmn_y, lmn_z);
00102 
00103     x_p = distance * sin(theta) * cos(phi);
00104     y_p = distance * sin(theta) * sin(phi);
00105     z_p = distance * cos(theta);
00106 
00107     return (coord_3D) {lmn_x.i*x_p + lmn_y.i*y_p + lmn_z.i*z_p + c.i,
00108                     lmn_x.j*x_p + lmn_y.j*y_p + lmn_z.j*z_p + c.j,
00109                     lmn_x.k*x_p + lmn_y.k*y_p + lmn_z.k*z_p + c.k};
00110 }
00111 
 All Classes Files Functions Variables Typedefs Defines