\Fractals
3MFRACT.C
/**************************************************************************** INTERNATIONAL AVS CENTER (This disclaimer must remain at the top of all files) WARRANTY DISCLAIMER This module and the files associated with it are distributed free of charge. It is placed in the public domain and permission is granted for anyone to use, duplicate, modify, and redistribute it unless otherwise noted. Some modules may be copyrighted. You agree to abide by the conditions also included in the AVS Licensing Agreement, version 1.0, located in the main module directory located at the International AVS Center ftp site and to include the AVS Licensing Agreement when you distribute any files downloaded from that site. The International AVS Center, MCNC, the AVS Consortium and the individual submitting the module and files associated with said module provide absolutely NO WARRANTY OF ANY KIND with respect to this software. The entire risk as to the quality and performance of this software is with the user. IN NO EVENT WILL The International AVS Center, MCNC, the AVS Consortium and the individual submitting the module and files associated with said module BE LIABLE TO ANYONE FOR ANY DAMAGES ARISING FROM THE USE OF THIS SOFTWARE, INCLUDING, WITHOUT LIMITATION, DAMAGES RESULTING FROM LOST DATA OR LOST PROFITS, OR ANY SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES. This AVS module and associated files are public domain software unless otherwise noted. Permission is hereby granted to do whatever you like with it, subject to the conditions that may exist in copyrighted materials. Should you wish to make a contribution toward the improvement, modification, or general performance of this module, please send us your comments: why you liked or disliked it, how you use it, and most important, how it helps your work. We will receive your comments at avs@ncsc.org. Please send AVS module bug reports to avs@ncsc.org. AUTHOR : Stardent Computer, Inc. ******************************************************************************/ /* AUTHOR: Anonymous DATE: 1-31-89 COMPANY: Stardent Computers PHONE NUMBER: 617-964-1000 EMAIL: larryg@stardent.com This file contains a module for generating mid-point displacement [3mfractal[23ms in two- and three-dimensions */ #include#include #include #include #define INDEX(p,w,x,y) (*((p)+((x)*(w))+(y))) #define INDEX3D(p,w,x,y,z) (*((p)+ (((x)*(w))+(y))*(w) + (z) )) float random(); void seed_random(); [3mfractal[23m_body(output,max_width,pow_ptr) AVSfield_char **output; int max_width; float *pow_ptr; { int i, j, step, depth, done; float *curr_ptr, *new_ptr, tmp; int curr_width, new_width; int dims[2]; static int been_here = 0; float scale[32]; float power; float curr_scale; static unsigned int seed; if(pow_ptr) power = *pow_ptr; else power = 2.0; if(!been_here || AVSparameter_changed("Reseed")) { been_here = 1; seed = time(0); } for(i=1;i<32;i++) scale[i] = 1.0/pow((float)i,power); seed_random(seed); curr_width = 3; curr_ptr = (float *)malloc(curr_width*curr_width*sizeof(float)); INDEX(curr_ptr,curr_width,0,0) = 0.0; INDEX(curr_ptr,curr_width,0,2) = 0.0; INDEX(curr_ptr,curr_width,2,0) = 0.0; INDEX(curr_ptr,curr_width,2,2) = 0.0; depth = 1; curr_scale = scale[depth]; INDEX(curr_ptr,curr_width,0,1) = 0.5*(INDEX(curr_ptr,curr_width,0,0)+INDEX(curr_ptr,curr_width,0,2)) + random(curr_scale); INDEX(curr_ptr,curr_width,1,0) = 0.5*(INDEX(curr_ptr,curr_width,0,0)+INDEX(curr_ptr,curr_width,2,0)) + random(curr_scale); INDEX(curr_ptr,curr_width,2,1) = 0.5*(INDEX(curr_ptr,curr_width,2,0)+INDEX(curr_ptr,curr_width,2,2)) + random(curr_scale); INDEX(curr_ptr,curr_width,1,2) = 0.5*(INDEX(curr_ptr,curr_width,0,2)+INDEX(curr_ptr,curr_width,2,2)) + random(curr_scale); INDEX(curr_ptr,curr_width,1,1) = 0.25*( INDEX(curr_ptr,curr_width,0,1) + INDEX(curr_ptr,curr_width,1,0) + INDEX(curr_ptr,curr_width,2,1) + INDEX(curr_ptr,curr_width,1,2) ) + random(curr_scale); /* * I am not sure what this interpolation function is. The bilinear one would obviously be: * * 4/9 2/9 * * 2/9 1/9 * */ depth++; curr_scale = scale[depth]; while(curr_width data,curr_ptr,curr_width*curr_width); free(curr_ptr); } [3mfractal[23m3d_body(output,max_width,pow_ptr) AVSfield_char **output; int max_width; float *pow_ptr; { int i, j, k, step, depth, done; float *curr_ptr, *new_ptr, tmp; int curr_width, new_width; int dims[2]; static int been_here = 0; float scale[32]; float power; float curr_scale; static unsigned int seed; if(pow_ptr) power = *pow_ptr; else power = 2.0; if(!been_here || AVSparameter_changed("Reseed")) { been_here = 1; seed = time(0); } for(i=1;i<32;i++) scale[i] = 1.0/pow((float)i,power); seed_random(seed); curr_width = 3; curr_ptr = (float *)malloc(curr_width*curr_width*curr_width*sizeof(float)); INDEX3D(curr_ptr,curr_width,0,0,0) = 0.0; INDEX3D(curr_ptr,curr_width,0,2,0) = 0.0; INDEX3D(curr_ptr,curr_width,2,0,0) = 0.0; INDEX3D(curr_ptr,curr_width,2,2,0) = 0.0; INDEX3D(curr_ptr,curr_width,0,0,2) = 0.0; INDEX3D(curr_ptr,curr_width,0,2,2) = 0.0; INDEX3D(curr_ptr,curr_width,2,0,2) = 0.0; INDEX3D(curr_ptr,curr_width,2,2,2) = 0.0; depth = 1; curr_scale = scale[depth]; /* Edges */ INDEX3D(curr_ptr,curr_width,1,0,0) = random(curr_scale); INDEX3D(curr_ptr,curr_width,0,1,0) = random(curr_scale); INDEX3D(curr_ptr,curr_width,1,2,0) = random(curr_scale); INDEX3D(curr_ptr,curr_width,2,1,0) = random(curr_scale); INDEX3D(curr_ptr,curr_width,0,0,1) = random(curr_scale); INDEX3D(curr_ptr,curr_width,2,0,1) = random(curr_scale); INDEX3D(curr_ptr,curr_width,0,2,1) = random(curr_scale); INDEX3D(curr_ptr,curr_width,2,2,1) = random(curr_scale); INDEX3D(curr_ptr,curr_width,1,0,2) = random(curr_scale); INDEX3D(curr_ptr,curr_width,0,1,2) = random(curr_scale); INDEX3D(curr_ptr,curr_width,2,1,2) = random(curr_scale); INDEX3D(curr_ptr,curr_width,1,2,2) = random(curr_scale); /* Faces */ INDEX3D(curr_ptr,curr_width,1,1,0) = random(curr_scale) + 0.25*( INDEX3D(curr_ptr,curr_width,0,0,0) + INDEX3D(curr_ptr,curr_width,2,0,0) + INDEX3D(curr_ptr,curr_width,0,2,0) + INDEX3D(curr_ptr,curr_width,2,2,0) ); INDEX3D(curr_ptr,curr_width,1,0,1)= random(curr_scale) + 0.25*( INDEX3D(curr_ptr,curr_width,0,0,0) + INDEX3D(curr_ptr,curr_width,2,0,0) + INDEX3D(curr_ptr,curr_width,0,0,2) + INDEX3D(curr_ptr,curr_width,2,0,2) ); INDEX3D(curr_ptr,curr_width,0,1,1)= random(curr_scale) + 0.25*( INDEX3D(curr_ptr,curr_width,0,0,0) + INDEX3D(curr_ptr,curr_width,0,0,2) + INDEX3D(curr_ptr,curr_width,0,2,0) + INDEX3D(curr_ptr,curr_width,0,2,2) ); INDEX3D(curr_ptr,curr_width,2,1,1)= random(curr_scale) + 0.25*( INDEX3D(curr_ptr,curr_width,2,0,0) + INDEX3D(curr_ptr,curr_width,2,0,2) + INDEX3D(curr_ptr,curr_width,2,2,0) + INDEX3D(curr_ptr,curr_width,2,2,2) ); INDEX3D(curr_ptr,curr_width,1,2,1)= random(curr_scale) + 0.25*( INDEX3D(curr_ptr,curr_width,0,2,0) + INDEX3D(curr_ptr,curr_width,2,2,0) + INDEX3D(curr_ptr,curr_width,0,2,2) + INDEX3D(curr_ptr,curr_width,2,2,2) ); INDEX3D(curr_ptr,curr_width,1,1,2)= random(curr_scale) + 0.25*( INDEX3D(curr_ptr,curr_width,0,0,2) + INDEX3D(curr_ptr,curr_width,2,0,2) + INDEX3D(curr_ptr,curr_width,0,2,2) + INDEX3D(curr_ptr,curr_width,2,2,2) ); /* Center */ INDEX3D(curr_ptr,curr_width,1,1,1)= random(curr_scale) + 0.166666667 * ( INDEX3D(curr_ptr,curr_width,0,1,1) + INDEX3D(curr_ptr,curr_width,2,1,1) + INDEX3D(curr_ptr,curr_width,1,0,1) + INDEX3D(curr_ptr,curr_width,1,2,1) + INDEX3D(curr_ptr,curr_width,1,1,0) + INDEX3D(curr_ptr,curr_width,1,1,2) ); /* * In 3D, the trilinear interpolation function would be: * * 8/27 4/27 4/27 2/27 * * 4/27 2/27 2/27 1/27 * */ depth++; curr_scale = scale[depth]; while(curr_width data,curr_ptr,curr_width*curr_width*curr_width); free(curr_ptr); } /**** Specifications ****/ [3mfractal[23m_spec() { AVSset_module_name("[3mfractal[23m", MODULE_DATA); AVScreate_output_port("Output Field", "field 2D scalar byte"); AVSadd_parameter("max width","integer",64,0,512); AVSadd_float_parameter("power",2.0,0.0,5.0); AVSadd_parameter("Reseed","oneshot",0,0,1); AVSset_compute_proc([3mfractal[23m_body); } [3mfractal[23m3d_spec() { AVSset_module_name("3d [3mfractal[23m", MODULE_DATA); AVScreate_output_port("Output Field", "field 3D scalar byte"); AVSadd_parameter("max width","integer",64,0,512); AVSadd_float_parameter("power",2.0,0.0,5.0); AVSadd_parameter("Reseed","oneshot",0,0,1); AVSset_compute_proc([3mfractal[23m3d_body); } int ((*module_list[])()) = { [3mfractal[23m_spec, [3mfractal[23m3d_spec, }; AVSinit_modules() { AVSinit_from_module_list(module_list, sizeof(module_list)/sizeof(module_list[0])); } pack(dst,src,n) unsigned char dst[]; float src[]; int n; { int i; float max, min; float scale; max = min = src[0]; for(i=1;i max) max = src[i]; else if(src[i] < min) min = src[i]; } scale = 255.0/(max-min); for(i=0;i 0 ) *idum *= -1; ix1=(IC1-(*idum))%M1; ix1=(IA1*ix1+IC1)%M1; ix2=ix1%M2; ix1=(IA1*ix1+IC1)%M1; ix3=ix1%M3; for(j=1;j<97;j++) { ix1=(IA1*ix1+IC1)%M1; ix2=(IA2*ix2+IC2)%M2; r[j]=(ix1+ix2*RM2)*RM1; } *idum=1; } ix1=(IA1*ix1+IC1)%M1; ix2=(IA2*ix2+IC2)%M2; ix3=(IA3*ix3+IC3)%M3; j=1+((97*ix3)/M3); if(j>97 || j<1) { fprintf(stderr,"Bad j in random: %d\n"); exit(1); } temp=r[j]; r[j]=(ix1+ix2*RM2)*RM1; if(debug_random) printf("%f\n",temp); return temp; } static int rand_seed; void seed_random(seed) int seed; { if(seed > 0) seed *= -1; rand_seed = seed; i_rand(&rand_seed); } float random(scale) float scale; { float ftmp; ftmp = i_rand(&rand_seed); return scale*(2.0*ftmp-1.0); }