Max 5 API Reference
00001 /* 00002 * Copyright 2001-2005 - Cycling '74 00003 * Derek Gerstmann - derek@cycling74.com 00004 * 00005 * Common utilities for fractal functor objects 00006 * 00007 */ 00008 00009 #include "jit.fractal.h" 00010 00011 /*************************************************************************/ 00012 00013 t_jit_err jit_functor_fractal_exponents_init( 00014 t_jit_functor_combined_dynarray *exp, 00015 double detail, double roughness, double lacunarity) 00016 { 00017 long i; 00018 t_jit_err err; 00019 double frequency = 1.0; 00020 double h = 1.0 - roughness; // fractal dimension 00021 long octaves = (long)detail + 1; 00022 00023 // dispose allocated mem 00024 err = jit_functor_combined_dynarray_init(exp, octaves); 00025 if(err) return err; 00026 00027 // compute weight for each frequency 00028 for ( i = 0; i < octaves; i++ ) 00029 { 00030 exp->float64[i] = jit_math_pow( frequency, -h ); 00031 exp->float32[i] = (float)exp->float64[i]; 00032 exp->fixed[i] = DoubleToFixed(exp->float64[i]); 00033 frequency *= lacunarity; 00034 } 00035 00036 return JIT_ERR_NONE; 00037 } 00038 00039 t_jit_err jit_functor_fractal_rotations_init( 00040 t_jit_functor_fractal_combined_matrix_dynarray *x, 00041 double octaves, long dimcount, long seed) 00042 { 00043 long i; 00044 t_jit_err err; 00045 long count = (long)octaves; 00046 00047 if(!x) 00048 return JIT_ERR_INVALID_PTR; 00049 00050 // destroy any allocated mem 00051 if(x->m) 00052 jit_functor_fractal_rotations_destroy(x); 00053 x->m = NULL; 00054 00055 // allocate 00056 x->count = count; 00057 x->m = (t_jit_functor_fractal_combined_matrix *)jit_newptr(x->count * sizeof(t_jit_functor_fractal_combined_matrix)); 00058 if(!x->m) 00059 return JIT_ERR_INVALID_PTR; 00060 00061 // init each matrix 00062 for(i = 0; i < x->count; i++) { 00063 x->m[i].cols = 0; 00064 x->m[i].rows = 0; 00065 x->m[i].fixed = NULL; 00066 x->m[i].float32 = NULL; 00067 x->m[i].float64 = NULL; 00068 err = jit_functor_fractal_rotation_matrix_init(&x->m[i], dimcount, seed); 00069 if(err) return err; 00070 } 00071 00072 return JIT_ERR_NONE; 00073 } 00074 00075 t_jit_err jit_functor_fractal_rotations_destroy( 00076 t_jit_functor_fractal_combined_matrix_dynarray *x) 00077 { 00078 long i; 00079 00080 if(!x) 00081 return JIT_ERR_INVALID_PTR; 00082 00083 for(i = 0; i < x->count; i++) 00084 jit_functor_fractal_rotation_matrix_destroy(&x->m[i]); 00085 00086 jit_disposeptr((char *)x->m); 00087 00088 x->m = NULL; 00089 x->count = 0; 00090 00091 return JIT_ERR_NONE; 00092 } 00093 00094 /* 00095 * Derek Gerstmann - derek@cycling74.com 00096 * 00097 * Construct an n-dimensional random rotation matrix. 00098 * 00099 * This implementation is based on Greg Ferrar's proposed algorithm used in his 00100 * public domain Hypercube n-dimensional Java applet. Comment snippet taken 00101 * from: 00102 * 00103 * http://www.flowerfire.com/ferrar/java/hypercuber/HyperCuber.java 00104 * 00105 * "Here is the algorithm used to build the matrix from scratch. This algorithm was 00106 * derived by examining correct rotation matrices up to size 7x7 (as derived by 00107 * Mathematica) and looking for patterns. The patterns were very obvious, but since 00108 * the analysis was not mathematical, this algorithm has not yet been formally PROVEN. 00109 * 00110 * M[i,j] is the (i,j)th element of the rotation matrix, and rows and columns both 00111 * start at 0. s[i] and c[i] are the ith element of the sines and cosines matrices, 00112 * respectively. s[0] is defined to be 1.0 (important for proper execution of step 5). 00113 * 00114 * 1. prod = 1; loop c from dim-1 to 1 step -1 { M[0,c] = -prod*s[c-1]; prod *= c[c-1]; } 00115 * 2. M[0, 0] = prod; 00116 * 3. loop r from 1 to dim-1 { M[r, r] = c[r-1] } 00117 * 4. loop r from 1 to dim-2 { loop c from r+1 to dim-1 { M[r, c] = 0 } } 00118 * 5. loop c from 0 to dim-2 { if (c==0) then prod = 1 else prod = -s[c-1]; 00119 * loop r from c+1 to dim-1 { M[r, c] = prod*s[r-1]; prod *= c[r-1] } } 00120 * 00121 * The matrix below is a sample 7x7 rotation matrix. The entries indicate which element 00122 * is generated by which step of the above algorithm. For instance, element (0,0) is 2, 00123 * indicating that the element in the 0th row and 0th column is generated by step 2 of 00124 * the algorithm." 00125 * 00126 * column = 0 column = dim-1 00127 * | | 00128 * 00129 * [ 2 1 1 1 1 1 1 ] row = 0 00130 * [ 5 3 4 4 4 4 4 ] 00131 * [ 5 5 3 4 4 4 4 ] 00132 * [ 5 5 5 3 4 4 4 ] 00133 * [ 5 5 5 5 3 4 4 ] 00134 * [ 5 5 5 5 5 3 4 ] 00135 * [ 5 5 5 5 5 0 3 ] row = dim-1 00136 * 00137 */ 00138 t_jit_err jit_functor_fractal_rotation_matrix_init( 00139 t_jit_functor_fractal_combined_matrix *x, 00140 long dimcount, long seed) 00141 { 00142 long i, j, k, r, c; 00143 t_jit_err err; 00144 double p; 00145 double offset = JIT_MATH_F64_PI/2000; 00146 double angles[JIT_MATRIX_MAX_DIMCOUNT]; 00147 00148 // safety 00149 if(!x) 00150 return JIT_ERR_INVALID_PTR; 00151 00152 // destroy any allocated memory 00153 err = jit_functor_fractal_rotation_matrix_destroy(x); 00154 if(err) return err; 00155 00156 // allocate NxN matrix stored as M[row][col] 00157 x->cols = x->rows = dimcount; 00158 00159 x->fixed = (long**)jit_newptr(x->rows * sizeof(long*)); 00160 if(!x->fixed) return JIT_ERR_INVALID_PTR; 00161 for(i = 0; i < x->rows; i++) { 00162 x->fixed[i] = (long *) jit_newptr(x->cols * sizeof(long)); 00163 if(!x->fixed[i]) return JIT_ERR_INVALID_PTR; 00164 } 00165 00166 x->float32 = (float**)jit_newptr(x->rows * sizeof(float*)); 00167 if(!x->float32) return JIT_ERR_INVALID_PTR; 00168 for(i = 0; i < x->rows; i++) { 00169 x->float32[i] = (float *) jit_newptr(x->cols * sizeof(float)); 00170 if(!x->float32[i]) return JIT_ERR_INVALID_PTR; 00171 } 00172 00173 x->float64 = (double**)jit_newptr(x->rows * sizeof(double*)); 00174 if(!x->float64) return JIT_ERR_INVALID_PTR; 00175 for(i = 0; i < x->rows; i++) { 00176 x->float64[i] = (double *) jit_newptr(x->cols * sizeof(double)); 00177 if(!x->float64[i]) return JIT_ERR_INVALID_PTR; 00178 } 00179 00180 // construct a random rotation matrix 00181 jit_rand_setseed(seed); 00182 for(j = 0; j < dimcount; j++) 00183 angles[j] = (jit_rand() % 65535) / (double) 65535; 00184 00185 // step 1 00186 p = 1.0; 00187 for (c = dimcount - 1; c >= 1; c--) 00188 { 00189 x->float64[0][c] = -p * jit_math_sin(angles[c-1] + offset); 00190 p *= jit_math_cos(angles[c-1] + offset); 00191 } 00192 00193 // step 2 00194 x->float64[0][0] = p; 00195 00196 // step 3 00197 for (r = 1; r <= dimcount-1; r++) 00198 x->float64[r][r] = jit_math_cos(angles[r-1] + offset); 00199 00200 // step 4 00201 for (r = 1; r <= dimcount-2; r++) 00202 for (c = r+1; c <= dimcount-1; c++) 00203 x->float64[r][c] = 0.0; 00204 00205 // step 5 00206 for (c = 0; c <= dimcount-2; c++) 00207 { 00208 if (c == 0) 00209 p = 1.0; 00210 else 00211 p = -jit_math_sin(angles[c-1]+ offset); 00212 for (r = c+1; r <= dimcount-1; r++) 00213 { 00214 x->float64[r][c] = p *jit_math_sin(angles[r-1] + offset); 00215 p *= jit_math_cos(angles[r-1] + offset); 00216 } 00217 } 00218 00219 // copy and convert 00220 for(j = 0; j < x->rows; j++) { 00221 for(k = 0; k < x->cols; k++){ 00222 x->float32[j][k] = (float)x->float64[j][k]; 00223 x->fixed[j][k] = DoubleToFixed(x->float64[j][k]); 00224 } 00225 } 00226 return JIT_ERR_NONE; 00227 } 00228 00229 t_jit_err jit_functor_fractal_rotation_matrix_destroy( 00230 t_jit_functor_fractal_combined_matrix *x) 00231 { 00232 long i; 00233 00234 if(!x) 00235 return JIT_ERR_INVALID_PTR; 00236 00237 // dispose allocated mem 00238 if(x->fixed) { 00239 for(i = 0; i < x->rows; i++) { 00240 jit_disposeptr((char *)x->fixed[i]); 00241 x->fixed[i] = NULL; 00242 } 00243 jit_disposeptr((char *)x->fixed); 00244 x->fixed = NULL; 00245 } 00246 00247 if(x->float32) { 00248 for(i = 0; i < x->rows; i++) { 00249 jit_disposeptr((char *)x->float32[i]); 00250 x->float32[i] = NULL; 00251 } 00252 jit_disposeptr((char *)x->float32); 00253 x->float32 = NULL; 00254 } 00255 00256 if(x->float64) { 00257 for(i = 0; i < x->rows; i++) { 00258 jit_disposeptr((char *)x->float64[i]); 00259 x->float64[i] = NULL; 00260 } 00261 jit_disposeptr((char *)x->float64); 00262 x->float64 = NULL; 00263 } 00264 00265 x->rows = x->cols = 0; 00266 return JIT_ERR_NONE; 00267 } 00268 00269 /*************************************************************************/
Copyright © 2008, Cycling '74