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.96 $       $Date: 2010/12/16 04:08:58 $
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 
00095 inline int clamp_int(int val, int min, int max) {
00096   return   (val > min) ? ((val <= max) ? val : max) : 0;
00097 }
00098 
00101 extern float * cross_prod(float *x1, const float *x2, const float *x3);
00102 
00104 inline float dot_prod(const float *v1, const float *v2) {
00105   return v1[0]* v2[0] + v1[1]* v2[1] + v1[2] * v2[2];
00106 }
00107 
00108 inline double dot_prod(const double *v1, const double *v2) {
00109   return v1[0]* v2[0] + v1[1]* v2[1] + v1[2] * v2[2];
00110 }
00111 
00113 inline void vec_copy(float *v1, const float *v2) {
00114   v1[0] = v2[0];
00115   v1[1] = v2[1];
00116   v1[2] = v2[2];
00117 }
00118 
00121 extern float * vec_normalize(float *);
00122 
00125 inline void vec_sub(float *a, const float *b, const float *c) {
00126   a[0]=b[0]-c[0];
00127   a[1]=b[1]-c[1];
00128   a[2]=b[2]-c[2];
00129 }
00130 
00132 inline void vec_add(float *a, const float *b, const float *c) {
00133   a[0]=b[0]+c[0];
00134   a[1]=b[1]+c[1];
00135   a[2]=b[2]+c[2];
00136 }
00137 
00139 inline void vec_incr(float *a, const float *b) {
00140   a[0] += b[0];
00141   a[1] += b[1];
00142   a[2] += b[2];
00143 }
00144 
00146 inline void vec_scale(float *a, float b, const float *c) {
00147   a[0] = b*c[0];
00148   a[1] = b*c[1];
00149   a[2] = b*c[2];
00150 }
00151 
00153 inline void vec_scale(float *a, float b, const double *c) {
00154   a[0] = b * (float) c[0];
00155   a[1] = b * (float) c[1];
00156   a[2] = b * (float) c[2];
00157 }
00158 
00160 inline void vec_negate(float *a, const float *b) {
00161   a[0] = -b[0];
00162   a[1] = -b[1];
00163   a[2] = -b[2];
00164 }
00165 
00167 inline void vec_scaled_add(float *a, float b, const float *c) {
00168   a[0] += b*c[0];
00169   a[1] += b*c[1];
00170   a[2] += b*c[2];
00171 }
00172 
00174 inline void vec_triad(float *a, const float *b, float c, const float *d) {
00175   a[0] = b[0] + c*d[0];
00176   a[1] = b[1] + c*d[1];
00177   a[2] = b[2] + c*d[2];
00178 }
00179 
00181 inline void vec_lerp(float *a, const float *b, const float *c, float frac) {
00182   float diff[3], tmp[3];
00183   vec_sub(diff, c, b);
00184   vec_scale(tmp, frac, diff);
00185   vec_add(a, b, tmp);
00186 }
00187 
00188 inline void vec_zero(float *a) {
00189   a[0] = 0.0f;
00190   a[1] = 0.0f;
00191   a[2] = 0.0f;
00192 }
00193 
00194 inline void clamp_color(float *rgb) {
00195   // clamp color values to legal range
00196   if (rgb[0] < 0.0f)
00197     rgb[0] = 0.0f;
00198   if (rgb[0] > 1.0f)
00199     rgb[0] = 1.0f;
00200 
00201   if (rgb[1] < 0.0f)
00202     rgb[1] = 0.0f;
00203   if (rgb[1] > 1.0f)
00204     rgb[1] = 1.0f;
00205 
00206   if (rgb[2] < 0.0f)
00207     rgb[2] = 0.0f;
00208   if (rgb[2] > 1.0f)
00209     rgb[2] = 1.0f;
00210 }
00211 
00212 
00214 inline void midpoint(float *a, const float *b, const float *c) {
00215   a[0] = 0.5f * (b[0]+c[0]);
00216   a[1] = 0.5f * (b[1]+c[1]);
00217   a[2] = 0.5f * (b[2]+c[2]);
00218 }
00219 
00220 
00221 // These define a cubic spline with various bases
00222 // see Foley and Van Dam, et. al., Computer Graphics, p505 or so
00223 //
00224 // this one was too sharply curved for my tastes
00225 //
00226 // float CatmullRom_basis[4][4]={{-1.0/2.0,  3.0/2.0, -3.0/2.0,  1.0/2.0},
00227 //                               { 2.0/2.0, -5.0/2.0,  4.0/2.0, -1.0/2.0},
00228 //                               {-1.0/2.0,  0.0/2.0,  1.0/2.0,  0.0/2.0},
00229 //                               { 0.0/2.0,  2.0/2.0,  0.0/2.0,  0.0/2.0}};
00230 //
00231 // this define makes the next basis identical to CatmullRom
00232 // #define SLOPE 2.0f
00233 //
00234 // This deemphasizes the slope and makes things look nicer (IMHO)
00235 // #define SLOPE 1.25f
00236 //
00237 // float modified_CR_basis[4][4] = {
00238 //    {-1.0f/SLOPE,  -1.0f/SLOPE + 2.0f,  1.0f/SLOPE - 2.0f,  1.0f/SLOPE},
00239 //    { 2.0f/SLOPE,   1.0f/SLOPE - 3.0f,   -2.0f/SLOPE+3.0f, -1.0f/SLOPE},
00240 //    {-1.0f/SLOPE,                0.0f,         1.0f/SLOPE,        0.0f},
00241 //    {       0.0f,                1.0f,               0.0f,        0.0f}
00242 // };
00243 //
00244 // This doesn't describe the system very nicely as the lines don't
00245 // go through the control points (which are the C-alphas)
00246 // float Bspline_basis[4][4]={{-1.0/6.0,  3.0/6.0, -3.0/6.0,  1.0/6.0},
00247 //                            { 3.0/6.0, -6.0/6.0,  3.0/6.0,  0.0/6.0},
00248 //                            {-3.0/6.0,  0.0/6.0,  3.0/6.0,  0.0/6.0},
00249 //                            { 1.0/6.0,  4.0/6.0,  1.0/6.0,  0.0/6.0}};
00250 
00252 inline void create_Bspline_basis(float array[4][4]) {
00253   array[0][0] = -1.0f/6.0f;
00254   array[0][1] =  3.0f/6.0f;
00255   array[0][2] = -3.0f/6.0f;
00256   array[0][3] =  1.0f/6.0f;
00257   array[1][0] =  3.0f/6.0f;
00258   array[1][1] = -6.0f/6.0f;
00259   array[1][2] =  3.0f/6.0f;
00260   array[1][3] =  0.0f/6.0f;
00261   array[2][0] = -3.0f/6.0f;
00262   array[2][1] =  0.0f/6.0f;
00263   array[2][2] =  3.0f/6.0f;
00264   array[2][3] =  0.0f/6.0f;
00265   array[3][0] =  1.0f/6.0f;
00266   array[3][1] =  4.0f/6.0f;
00267   array[3][2] =  1.0f/6.0f;
00268   array[3][3] =  0.0f/6.0f;
00269 }
00270 
00272 inline void create_modified_CR_spline_basis(float array[4][4], float slope) {
00273   array[0][0] = -1.0f / slope;
00274   array[0][1] = -1.0f / slope + 2.0f;
00275   array[0][2] =  1.0f / slope - 2.0f;
00276   array[0][3] =  1.0f / slope;
00277   array[1][0] =  2.0f / slope;
00278   array[1][1] =  1.0f / slope - 3.0f;
00279   array[1][2] = -2.0f / slope + 3.0f;
00280   array[1][3] = -1.0f / slope;
00281   array[2][0] = -1.0f / slope;
00282   array[2][1] =  0.0f;
00283   array[2][2] =  1.0f / slope;
00284   array[2][3] =  0.0f;
00285   array[3][0] =  0.0f;
00286   array[3][1] =  1.0f;
00287   array[3][2] =  0.0f;
00288   array[3][3] =  0.0f;
00289 }
00290 
00297 inline void make_spline_Q_matrix(float q[4][3], float basis[4][4], const float *pts) {
00298   int i, j;
00299   for (i = 0; i<4; i++) {
00300     float a, b, c;
00301     a = b = c = 0.0;
00302 
00303     for (j = 0; j<4; j++) {
00304       a += basis[i][j] * pts[j*3    ];
00305       b += basis[i][j] * pts[j*3 + 1];
00306       c += basis[i][j] * pts[j*3 + 2];
00307     }
00308 
00309     q[i][0] = a; 
00310     q[i][1] = b; 
00311     q[i][2] = c; 
00312   }
00313 }
00314 
00321 inline void make_spline_Q_matrix_noncontig(float q[4][3], float basis[4][4], 
00322                                         const float *pts1, const float *pts2,
00323                                         const float *pts3, const float *pts4) {
00324   int i;
00325 
00326   for (i = 0; i<4; i++) {
00327     float a, b, c;
00328     a = b = c = 0.0;
00329 
00330     a += basis[i][0] * pts1[0];
00331     b += basis[i][0] * pts1[1];
00332     c += basis[i][0] * pts1[2];
00333 
00334     a += basis[i][1] * pts2[0];
00335     b += basis[i][1] * pts2[1];
00336     c += basis[i][1] * pts2[2];
00337 
00338     a += basis[i][2] * pts3[0];
00339     b += basis[i][2] * pts3[1];
00340     c += basis[i][2] * pts3[2];
00341 
00342     a += basis[i][3] * pts4[0];
00343     b += basis[i][3] * pts4[1];
00344     c += basis[i][3] * pts4[2];
00345 
00346     q[i][0] = a; 
00347     q[i][1] = b; 
00348     q[i][2] = c; 
00349   }
00350 }
00351 
00352 
00364 inline void make_spline_interpolation(float out[3], float w, float q[4][3]) {
00365   out[0] = w * (w * (w * q[0][0] + q[1][0]) + q[2][0]) + q[3][0];
00366   out[1] = w * (w * (w * q[0][1] + q[1][1]) + q[2][1]) + q[3][1];
00367   out[2] = w * (w * (w * q[0][2] + q[1][2]) + q[2][2]) + q[3][2];
00368 }
00369 
00371 extern int tri_degenerate(const float *, const float *, const float *);
00372 
00374 extern float angle(const float *, const float *);
00375 
00378 extern float dihedral(const float *, const float *, const float *, 
00379                       const float *);
00380 
00382 extern float distance(const float *, const float *);
00383 
00385 inline float distance2(const float *a, const float *b) {
00386   float delta = a[0] - b[0];
00387   float r2 = delta*delta;
00388   delta = a[1] - b[1];
00389   r2 += delta*delta;
00390   delta = a[2] - b[2];
00391   return r2 + delta*delta;
00392 }
00393 
00395 extern float norm(const float *);
00396 
00400 char *vmd_tempfile(const char *);
00401 
00403 int vmd_delete_file(const char *);
00404 
00406 void vmd_sleep(int);   // sleeps for N seconds
00407 void vmd_msleep(int);  // sleeps for N milliseconds
00408 
00411 extern int vmd_system(const char* cmd);
00412 
00413 
00415 extern void vmd_srandom(unsigned int);
00416 extern long vmd_random();
00417 extern float vmd_random_gaussian();
00418 
00419 // select the right VMD_RAND_MAX value depending on implementation and platform
00420 #if defined(__linux) || defined(_MSC_VER)
00421 // Linux uses RAND_MAX for both rand() and random()
00422 // Windows is currently implemented with rand()
00423 #define VMD_RAND_MAX RAND_MAX
00424 #else
00425 // All other platforms I've seen use 2^31-1 for their max random() return val
00426 #if defined(LONG_MAX)
00427 #define VMD_RAND_MAX LONG_MAX
00428 #else
00429 // just in case no LONG_MAX, 
00430 // or in cases where they choose to update it for 64-bits or something
00431 #define VMD_RAND_MAX 2147483647L
00432 #endif
00433 #endif
00434 
00436 long vmd_get_total_physmem_mb(void);
00437 
00439 long vmd_get_avail_physmem_mb(void);
00440 
00442 long vmd_get_avail_physmem_percent(void);
00443 
00444 #endif

Generated on Thu May 24 01:51:36 2012 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002