Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

utilities.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr                                                                       
00003  *cr            (C) Copyright 1995-2011 The Board of Trustees of the           
00004  *cr                        University of Illinois                       
00005  *cr                         All Rights Reserved                        
00006  *cr                                                                   
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: utilities.h,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.105 $      $Date: 2013/02/11 17:41:53 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *
00019  * General utility routines and definitions.
00020  *
00021  ***************************************************************************/
00022 #ifndef UTILITIES_H
00023 #define UTILITIES_H
00024 
00025 #include <stdlib.h> // need RAND_MAX
00026 
00027 #ifndef FALSE
00028 #define FALSE 0
00029 #define TRUE  1
00030 #endif
00031 
00032 #ifndef NULL
00033 #define NULL 0
00034 #endif
00035 
00036 #ifndef ABS
00037 #define ABS(A) ((A)>0?(A):-(A))
00038 #endif
00039 
00040 // various PI macros not available on all machines
00041 #define VMD_PI      3.14159265358979323846
00042 #define VMD_TWOPI   (2.0 * VMD_PI)
00043 #define VMD_1_PI    0.31830988618379067154
00044 
00045 // Convert Angstroms to Bohr
00046 #define VMD_ANGS_TO_BOHR 1.88972612478289694072
00047 
00048 // Degree-to-Radians and Radians-to-Degrees Conversion macros
00049 #define DEGTORAD(a)     (a*VMD_PI/180.0)
00050 #define RADTODEG(a)     (a*180.0/VMD_PI)
00051 
00055 extern char *combine_arguments(int, const char **, int);
00056 
00057 
00059 extern char *stringdup(const char *);
00060 
00061 
00063 extern char *stringtoupper(char *);
00064 
00066 void stripslashes(char *str);
00067 
00069 extern int strupcmp(const char *, const char *);
00071 extern int strupncmp(const char *, const char *, int);
00072 
00073 
00077 extern void breakup_filename(const char *, char **, char **);
00078 
00080 extern char *str_tokenize(const char *, int *, char **);
00081 
00084 extern double time_of_day(void);
00085 
00087 extern int vmd_check_stdin(void);
00088 
00090 extern char * vmd_username(void);
00092 extern int vmd_getuid(void);
00093 
00094 
00095 // Find the first selected atom, return 0 on success, return -1 if no selection
00096 extern int find_first_selection_aligned(int n, const int *on, int *firstsel);
00097 
00098 // Find the last selected atom, return 0 on success, return -1 if no selection
00099 extern int find_last_selection_aligned(int n, const int *on, int *lastsel);
00100 
00101 // Find the first selected atom, the last selected atom,
00102 // and the total number of selected atoms.
00103 // return 0 on success, return -1 if no selection
00104 extern int analyze_selection_aligned(int n, const int *on,
00105                                      int *firstsel, int *lastsel, int *selected);
00106 
00108 extern void minmax_1fv_aligned(const float *f, int n, float *min, float *max);
00109 
00110 // Compute min/max values for a 16-byte-aligned array of floats
00111 // input value n3 is the number of 3-element vectors to process
00112 extern void minmax_3fv_aligned(const float *f, const int n3, float *fmin, float *fmax);
00113 
00114 // Compute min/max values for a 16-byte-aligned array of floats
00115 // input value on is the array of atom selection flags, and firstsel
00116 // and lastsel indicate the first and last 3-element vectors to process
00117 // return 0 on success, -1 on no selected atoms or other problems
00118 extern int minmax_selected_3fv_aligned(const float *f, const int *on, 
00119                                        const int n3, const int firstsel, 
00120                                        const int lastsel, 
00121                                        float *fmin, float *fmax);
00122 
00124 inline int clamp_int(int val, int min, int max) {
00125   return   (val > min) ? ((val <= max) ? val : max) : 0;
00126 }
00127 
00130 extern float * cross_prod(float *x1, const float *x2, const float *x3);
00131 
00133 inline float dot_prod(const float *v1, const float *v2) {
00134   return v1[0]* v2[0] + v1[1]* v2[1] + v1[2] * v2[2];
00135 }
00136 
00137 inline double dot_prod(const double *v1, const double *v2) {
00138   return v1[0]* v2[0] + v1[1]* v2[1] + v1[2] * v2[2];
00139 }
00140 
00142 inline void vec_copy(float *v1, const float *v2) {
00143   v1[0] = v2[0];
00144   v1[1] = v2[1];
00145   v1[2] = v2[2];
00146 }
00147 
00150 extern float * vec_normalize(float *);
00151 
00154 inline void vec_sub(float *a, const float *b, const float *c) {
00155   a[0]=b[0]-c[0];
00156   a[1]=b[1]-c[1];
00157   a[2]=b[2]-c[2];
00158 }
00159 
00161 inline void vec_add(float *a, const float *b, const float *c) {
00162   a[0]=b[0]+c[0];
00163   a[1]=b[1]+c[1];
00164   a[2]=b[2]+c[2];
00165 }
00166 
00168 inline void vec_incr(float *a, const float *b) {
00169   a[0] += b[0];
00170   a[1] += b[1];
00171   a[2] += b[2];
00172 }
00173 
00175 inline void vec_scale(float *a, float b, const float *c) {
00176   a[0] = b*c[0];
00177   a[1] = b*c[1];
00178   a[2] = b*c[2];
00179 }
00180 
00182 inline void vec_scale(float *a, float b, const double *c) {
00183   a[0] = b * (float) c[0];
00184   a[1] = b * (float) c[1];
00185   a[2] = b * (float) c[2];
00186 }
00187 
00189 inline void vec_negate(float *a, const float *b) {
00190   a[0] = -b[0];
00191   a[1] = -b[1];
00192   a[2] = -b[2];
00193 }
00194 
00196 inline void vec_scaled_add(float *a, float b, const float *c) {
00197   a[0] += b*c[0];
00198   a[1] += b*c[1];
00199   a[2] += b*c[2];
00200 }
00201 
00203 inline void vec_triad(float *a, const float *b, float c, const float *d) {
00204   a[0] = b[0] + c*d[0];
00205   a[1] = b[1] + c*d[1];
00206   a[2] = b[2] + c*d[2];
00207 }
00208 
00210 inline void vec_lerp(float *a, const float *b, const float *c, float frac) {
00211   float diff[3], tmp[3];
00212   vec_sub(diff, c, b);
00213   vec_scale(tmp, frac, diff);
00214   vec_add(a, b, tmp);
00215 }
00216 
00217 inline void vec_zero(float *a) {
00218   a[0] = 0.0f;
00219   a[1] = 0.0f;
00220   a[2] = 0.0f;
00221 }
00222 
00223 inline void clamp_color(float *rgb) {
00224   // clamp color values to legal range
00225   if (rgb[0] < 0.0f)
00226     rgb[0] = 0.0f;
00227   if (rgb[0] > 1.0f)
00228     rgb[0] = 1.0f;
00229 
00230   if (rgb[1] < 0.0f)
00231     rgb[1] = 0.0f;
00232   if (rgb[1] > 1.0f)
00233     rgb[1] = 1.0f;
00234 
00235   if (rgb[2] < 0.0f)
00236     rgb[2] = 0.0f;
00237   if (rgb[2] > 1.0f)
00238     rgb[2] = 1.0f;
00239 }
00240 
00241 
00243 inline void midpoint(float *a, const float *b, const float *c) {
00244   a[0] = 0.5f * (b[0]+c[0]);
00245   a[1] = 0.5f * (b[1]+c[1]);
00246   a[2] = 0.5f * (b[2]+c[2]);
00247 }
00248 
00249 
00250 // These define a cubic spline with various bases
00251 // see Foley and Van Dam, et. al., Computer Graphics, p505 or so
00252 //
00253 // this one was too sharply curved for my tastes
00254 //
00255 // float CatmullRom_basis[4][4]={{-1.0/2.0,  3.0/2.0, -3.0/2.0,  1.0/2.0},
00256 //                               { 2.0/2.0, -5.0/2.0,  4.0/2.0, -1.0/2.0},
00257 //                               {-1.0/2.0,  0.0/2.0,  1.0/2.0,  0.0/2.0},
00258 //                               { 0.0/2.0,  2.0/2.0,  0.0/2.0,  0.0/2.0}};
00259 //
00260 // this define makes the next basis identical to CatmullRom
00261 // #define SLOPE 2.0f
00262 //
00263 // This deemphasizes the slope and makes things look nicer (IMHO)
00264 // #define SLOPE 1.25f
00265 //
00266 // float modified_CR_basis[4][4] = {
00267 //    {-1.0f/SLOPE,  -1.0f/SLOPE + 2.0f,  1.0f/SLOPE - 2.0f,  1.0f/SLOPE},
00268 //    { 2.0f/SLOPE,   1.0f/SLOPE - 3.0f,   -2.0f/SLOPE+3.0f, -1.0f/SLOPE},
00269 //    {-1.0f/SLOPE,                0.0f,         1.0f/SLOPE,        0.0f},
00270 //    {       0.0f,                1.0f,               0.0f,        0.0f}
00271 // };
00272 //
00273 // This doesn't describe the system very nicely as the lines don't
00274 // go through the control points (which are the C-alphas)
00275 // float Bspline_basis[4][4]={{-1.0/6.0,  3.0/6.0, -3.0/6.0,  1.0/6.0},
00276 //                            { 3.0/6.0, -6.0/6.0,  3.0/6.0,  0.0/6.0},
00277 //                            {-3.0/6.0,  0.0/6.0,  3.0/6.0,  0.0/6.0},
00278 //                            { 1.0/6.0,  4.0/6.0,  1.0/6.0,  0.0/6.0}};
00279 
00281 inline void create_Bspline_basis(float array[4][4]) {
00282   array[0][0] = -1.0f/6.0f;
00283   array[0][1] =  3.0f/6.0f;
00284   array[0][2] = -3.0f/6.0f;
00285   array[0][3] =  1.0f/6.0f;
00286   array[1][0] =  3.0f/6.0f;
00287   array[1][1] = -6.0f/6.0f;
00288   array[1][2] =  3.0f/6.0f;
00289   array[1][3] =  0.0f/6.0f;
00290   array[2][0] = -3.0f/6.0f;
00291   array[2][1] =  0.0f/6.0f;
00292   array[2][2] =  3.0f/6.0f;
00293   array[2][3] =  0.0f/6.0f;
00294   array[3][0] =  1.0f/6.0f;
00295   array[3][1] =  4.0f/6.0f;
00296   array[3][2] =  1.0f/6.0f;
00297   array[3][3] =  0.0f/6.0f;
00298 }
00299 
00301 inline void create_modified_CR_spline_basis(float array[4][4], float slope) {
00302   array[0][0] = -1.0f / slope;
00303   array[0][1] = -1.0f / slope + 2.0f;
00304   array[0][2] =  1.0f / slope - 2.0f;
00305   array[0][3] =  1.0f / slope;
00306   array[1][0] =  2.0f / slope;
00307   array[1][1] =  1.0f / slope - 3.0f;
00308   array[1][2] = -2.0f / slope + 3.0f;
00309   array[1][3] = -1.0f / slope;
00310   array[2][0] = -1.0f / slope;
00311   array[2][1] =  0.0f;
00312   array[2][2] =  1.0f / slope;
00313   array[2][3] =  0.0f;
00314   array[3][0] =  0.0f;
00315   array[3][1] =  1.0f;
00316   array[3][2] =  0.0f;
00317   array[3][3] =  0.0f;
00318 }
00319 
00326 inline void make_spline_Q_matrix(float q[4][3], float basis[4][4], const float *pts) {
00327   int i, j;
00328   for (i = 0; i<4; i++) {
00329     float a, b, c;
00330     a = b = c = 0.0;
00331 
00332     for (j = 0; j<4; j++) {
00333       a += basis[i][j] * pts[j*3    ];
00334       b += basis[i][j] * pts[j*3 + 1];
00335       c += basis[i][j] * pts[j*3 + 2];
00336     }
00337 
00338     q[i][0] = a; 
00339     q[i][1] = b; 
00340     q[i][2] = c; 
00341   }
00342 }
00343 
00350 inline void make_spline_Q_matrix_noncontig(float q[4][3], float basis[4][4], 
00351                                         const float *pts1, const float *pts2,
00352                                         const float *pts3, const float *pts4) {
00353   int i;
00354 
00355   for (i = 0; i<4; i++) {
00356     float a, b, c;
00357     a = b = c = 0.0;
00358 
00359     a += basis[i][0] * pts1[0];
00360     b += basis[i][0] * pts1[1];
00361     c += basis[i][0] * pts1[2];
00362 
00363     a += basis[i][1] * pts2[0];
00364     b += basis[i][1] * pts2[1];
00365     c += basis[i][1] * pts2[2];
00366 
00367     a += basis[i][2] * pts3[0];
00368     b += basis[i][2] * pts3[1];
00369     c += basis[i][2] * pts3[2];
00370 
00371     a += basis[i][3] * pts4[0];
00372     b += basis[i][3] * pts4[1];
00373     c += basis[i][3] * pts4[2];
00374 
00375     q[i][0] = a; 
00376     q[i][1] = b; 
00377     q[i][2] = c; 
00378   }
00379 }
00380 
00381 
00393 inline void make_spline_interpolation(float out[3], float w, float q[4][3]) {
00394   out[0] = w * (w * (w * q[0][0] + q[1][0]) + q[2][0]) + q[3][0];
00395   out[1] = w * (w * (w * q[0][1] + q[1][1]) + q[2][1]) + q[3][1];
00396   out[2] = w * (w * (w * q[0][2] + q[1][2]) + q[2][2]) + q[3][2];
00397 }
00398 
00400 extern int tri_degenerate(const float *, const float *, const float *);
00401 
00403 extern float angle(const float *, const float *);
00404 
00407 extern float dihedral(const float *, const float *, const float *, 
00408                       const float *);
00409 
00411 extern float distance(const float *, const float *);
00412 
00414 inline float distance2(const float *a, const float *b) {
00415   float delta = a[0] - b[0];
00416   float r2 = delta*delta;
00417   delta = a[1] - b[1];
00418   r2 += delta*delta;
00419   delta = a[2] - b[2];
00420   return r2 + delta*delta;
00421 }
00422 
00424 extern float norm(const float *);
00425 
00429 char *vmd_tempfile(const char *);
00430 
00432 int vmd_delete_file(const char *);
00433 
00435 void vmd_sleep(int);   // sleeps for N seconds
00436 void vmd_msleep(int);  // sleeps for N milliseconds
00437 
00440 extern int vmd_system(const char* cmd);
00441 
00442 
00444 extern void vmd_srandom(unsigned int);
00445 extern long vmd_random();
00446 extern float vmd_random_gaussian();
00447 
00448 // select the right VMD_RAND_MAX value depending on implementation and platform
00449 #if defined(__linux) || defined(_MSC_VER)
00450 // Linux uses RAND_MAX for both rand() and random()
00451 // Windows is currently implemented with rand()
00452 #define VMD_RAND_MAX RAND_MAX
00453 #else
00454 // All other platforms I've seen use 2^31-1 for their max random() return val
00455 #if defined(LONG_MAX)
00456 #define VMD_RAND_MAX LONG_MAX
00457 #else
00458 // just in case no LONG_MAX, 
00459 // or in cases where they choose to update it for 64-bits or something
00460 #define VMD_RAND_MAX 2147483647L
00461 #endif
00462 #endif
00463 
00465 long vmd_get_total_physmem_mb(void);
00466 
00468 long vmd_get_avail_physmem_mb(void);
00469 
00471 long vmd_get_avail_physmem_percent(void);
00472 
00473 #endif

Generated on Tue Jun 18 01:48:13 2013 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002