|
Open PaperOpt
|
00001 #pragma once 00002 #ifndef UTILITIES_H 00003 #define UTILITIES_H 00004 00005 00006 00007 00008 #include <stdio.h> 00009 #include <string> 00010 #include <vector> 00011 #include <complex> 00012 #include <stdarg.h> 00013 #include <functional> 00014 #include <algorithm> 00015 #include <math.h> 00016 #include "V3.h" 00017 #include <time.h> 00018 00019 00024 #define MIN(a,b) (((a)<=(b))?(a):(b)) 00025 00028 #define MAX(a,b) (((a)>=(b))?(a):(b)) 00029 00032 #define ABS(a) (((a) < 0) ? -(a) : (a)) 00033 00034 00038 #define FLT_QNAN 0xffc00000 00039 00040 #define DATA_MOVE(data,dist) (data)=(double*)(((char*)(data))+(dist)) 00041 #define DATA_ADD(data,dist) ((double*)(((char*)(data))+(dist))) 00042 00043 #pragma warning(disable:4996) 00044 00045 using namespace std; 00065 //============================================================================ 00075 template <class C> class AutoDelete { 00076 public: 00077 00081 AutoDelete() {ptr=0;} 00087 AutoDelete(C* p) {ptr=p;} 00088 ~AutoDelete() {delete ptr;ptr=0;} 00089 00094 C* operator->() const {return ptr;} 00098 C& operator*() const {return *ptr;} 00102 C* Ptr() const {return ptr;} 00106 operator C*() const {return Ptr();} 00110 void clear() {delete ptr;ptr=0;} 00115 void set(C* p) {delete ptr;ptr=p;} 00120 void operator=(C* p) {set(p);} 00121 00126 C* detatch() {C* p=ptr;ptr=0;return p;} 00127 00128 private: 00129 AutoDelete(const AutoDelete& p) {} //Deny copy 00130 00131 C* ptr; 00132 }; 00133 00134 //=============================================================================== 00142 template <class C> class AutoDeleteV { 00143 public: 00144 AutoDeleteV() {ptr=0;} 00145 AutoDeleteV(C* p) {ptr=p;} 00146 ~AutoDeleteV() {delete [] ptr;ptr=0;} 00147 00148 C* operator->() const {return ptr;} 00149 C& operator*() const {return *ptr;} 00150 C* Ptr() const {return ptr;} 00151 operator C*() const {return Ptr();} 00152 00153 void clear() {delete [] ptr;ptr=0;} 00154 void set(C* p) {delete [] ptr;ptr=p;} 00155 void operator=(C* p) {set(p);} 00156 00160 C* detatch() {C* p=ptr;ptr=0;return p;} 00161 00162 private: 00163 AutoDeleteV(const AutoDeleteV& p) {} //Deny copy 00164 00165 C* ptr; 00166 }; 00167 //============================================================================= 00168 00175 class StdExcept { 00176 public: 00180 StdExcept() {} 00186 StdExcept(const char* format,...){ 00187 char buf[2048]; 00188 va_list(arglist); 00189 va_start(arglist,format); 00190 vsnprintf(buf,2048,format,arglist); 00191 mMsg=buf; 00192 printf("/n%s/n",buf); 00193 } 00197 string GetMessage() const {return mMsg;} 00198 private: 00199 string mMsg; 00200 }; 00201 00202 00203 00204 00205 //============================================================================== 00206 00214 template <int numbins> 00215 class SimpleDist { 00216 public: 00217 SimpleDist() {mMin=mBinWidth=0;memset(mF,0,sizeof(mF));} 00218 ~SimpleDist() {} 00219 00220 int GetDataSize() {return sizeof(*this);} 00221 00222 void InitFromSamples(double minVal,double maxVal,double* data,int numData,int dataDist); 00223 00224 double InvF(double y); //Calc F^-1(y), y=[0..1) 00225 00226 private: 00227 double mMin,mBinWidth;//Start of distributaion and width of bins 00228 double mF[numbins-1]; //The f-function assume 1 in last 00229 }; 00230 00231 template <int numbins> 00232 void SimpleDist<numbins>::InitFromSamples(double minVal,double maxVal,double* data,int numData,int dataDist) 00233 { 00234 //Sanitycheck parameters 00235 if (numData<2) throw StdExcept("SimpleDist::InitFromSamples: numData<2"); 00236 if (minVal>=maxVal) throw StdExcept("SimpleDist::InitFromSamples: minVal(%f)>=maxVal(%f) error",minVal,maxVal); 00237 if (numbins<2) throw StdExcept("SimpleDist::InitFromSamples: numbins<2"); //Well, will compile away... 00238 if (dataDist<4) throw StdExcept("SimpleDist::InitFromSamples: invalid dataDist (%d)",dataDist); 00239 00240 //Uppdate locals 00241 mMin = minVal; 00242 mBinWidth = (maxVal-minVal)/(double)(numbins); 00243 00244 //Accumulate points 00245 int numPnts=0; 00246 int bins[numbins+1]; //+1 to capture case when data==maxVal 00247 00248 memset(bins,0,sizeof(bins)); 00249 for (int i=numData;i;i--) { 00250 double val=*data; 00251 data=(double*)(((char*)data)+dataDist); 00252 if (val>=minVal && val<=maxVal) { 00253 numPnts++; 00254 int binNo=(int)((val-minVal)/mBinWidth); 00255 if (binNo<0 || binNo>=numbins+1) throw StdExcept("SimpleDist<numbins>::InitFromSamples: Dodamn :)"); //TODO: Remove 00256 bins[binNo]++; 00257 } 00258 } 00259 //Check that we caught atleast two points 00260 if (numPnts<2) throw StdExcept("SimpleDist::InitFromSamples: Less than 2 points in intervall"); 00261 00262 //Calc f-function 00263 double nPntInv=1.0/numPnts; 00264 int pntAcc=0; 00265 00266 for (int i=0;i<(numbins-1);i++) { 00267 pntAcc+=bins[i]; 00268 mF[i]=pntAcc*nPntInv; 00269 } 00270 } 00271 00272 //---------------------------------------------------------------------------------------- 00273 00274 template <int numbins> 00275 double SimpleDist<numbins>::InvF(double y) { 00276 00277 //Binsearch for the bin we'r in 00278 double* f=upper_bound(mF,mF+(numbins-1),y); 00279 00280 double l=(f==mF)?0.0:*(f-1); //Left value 00281 double r=(f==mF+(numbins-1))?1.0:*f; //Right value 00282 00283 //If no samples in bin, return midpos 00284 if (fabs(r-l)<1e-15) 00285 return ((f-mF)+0.5)*mBinWidth+mMin; 00286 00287 double pos=mBinWidth*(y-l)/(r-l); //Ofs in this bin 00288 pos+=(f-mF)*mBinWidth+mMin; //Add bin offset 00289 return pos; 00290 } 00291 00292 00293 //================================================================================= 00294 00295 typedef SimpleDist<13> ZDist; 00296 00297 //================================================================================= 00305 class SubdivPatch { 00306 public: 00307 SubdivPatch() {min=0;max=0;p=0;numPnt=0;} 00308 SubdivPatch(double mi,double ma,double* pp,int np) {min=mi;max=ma;p=pp,numPnt=np;} 00309 00310 bool operator<(const SubdivPatch& p) const {return min<p.min;} 00311 bool operator==(const SubdivPatch& p) const {return min==p.min;} 00312 00313 double min,max; 00314 double* p; 00315 int numPnt; 00316 }; 00317 00318 //================================================================================= 00325 class SubdivEnv { 00326 public: 00327 double minVal,maxVal; 00328 double minDelta; 00329 int minPoints; 00330 double maxPatch; 00331 int dataDist; 00332 00333 vector <SubdivPatch> patches; 00334 }; 00335 //================================================================================= 00336 class fiberData { 00337 public: 00338 fiberData() {x=0;y=0;z=0;} 00339 fiberData(double xx,double yy,double zz) {x=xx;y=yy;z=zz;} 00340 bool operator<(const fiberData& f) const {return 1;} 00341 bool operator==(const fiberData& f) const {return 1;} 00342 00343 double* getZPointer() {return &z;} 00344 00345 bool compare_x(double xx) const {return x<=xx;} 00346 bool compare_y(double yy) const {return y<=yy;} 00347 00348 00349 double x,y,z; 00350 }; 00351 //================================================================================ 00352 typedef vector<fiberData> fsamples; 00353 typedef fsamples::iterator fsamplesiter; 00354 00355 //Predicate-templates 00356 template<class _Tx,class _Ty> 00357 struct compare_x : binary_function<_Tx, _Ty, bool> { 00358 bool operator()(const _Tx& _X, const _Ty& _Y) const 00359 {return _X.compare_x(_Y);} 00360 }; 00361 template<class _Tx,class _Ty> 00362 struct compare_y : binary_function<_Tx, _Ty, bool> { 00363 bool operator()(const _Tx& _X, const _Ty& _Y) const 00364 {return _X.compare_y(_Y);} 00365 }; 00366 //================================================================================= 00367 00368 //== Creaton of local_weight(y) 00373 class TreeNode { 00374 public: 00378 TreeNode() {value=0;}; 00382 ~TreeNode() {}; 00383 00387 TreeNode* Left() const {return left;} 00391 TreeNode* Right() const {return right;} 00395 double Value() const {return value;} 00396 00400 void Left(TreeNode* n) {left=n;} 00404 void Right(TreeNode* n) {right=n;} 00408 void Value(double d) {value=d;} 00409 00413 void operator+=(double d) {value+=d;} 00414 00415 private: 00416 AutoDelete<TreeNode> left; 00417 AutoDelete<TreeNode> right; 00418 double value; 00419 }; 00420 00421 //====================================================================================== 00422 00431 class FiberSample { 00432 public: 00436 int operator<(const FiberSample& f) const {return d[0]<f.d[0];} 00440 int operator==(const FiberSample& f) const {return d[0]==f.d[0] && d[1]==f.d[1] && d[2]==f.d[2];} 00444 double operator[](int idx) const {return d[idx];} 00445 00449 double* PtrToFirst() {return &(d[0]);} 00450 00451 double d[3]; //Len,Wid,Curl 00452 }; 00453 00454 //========================================================================================= 00464 namespace p3d{ 00465 00466 static const double gMinBaseLen = 1000.0/8.0; //um, stop subdividing base here 00467 static const double gTolerance = 0.03f; //%, itterate untill within this tollerance 00468 static const double gLowTolerance = 0.09f; //%, itterate untill within this tollerance if <65% cf 00469 static const double gEnergyMultipler = 1.0f/500.0f;//Angular scaler //TODO: Fit this parameter to samples 00470 extern int GenerateCurlVector(double len,double rad,double formfac,int numSegs,double* angles,int packetsLow=25,int packetsHig=35); 00471 } 00472 //=========================================================================================== 00482 namespace p3d{ 00483 #define SIMVOL_FLAG_ANGLE 0x0001 00484 #define SIMVOL_FLAG_CURL 0x0002 00485 #define SIMVOL_FLAG_POS 0x0004 00486 #define SIMVOL_FLAG_POS3D 0x0008 00487 #define SEGT_ROTZ 0x0001 00488 } 00489 00490 00491 00492 #if _MSC_VER >= 1000 00493 #pragma once 00494 #endif // _MSC_VER >= 1000 00495 00496 //#define NEW_PROP_IN_LAYER 0 00497 00498 00499 00500 00501 #define EPS 2.220446049250313e-016 00502 #define INF 1e48 00503 #define PI 3.1415926535897932384626433832795 00504 const double THICKNESS_LIMIT = 1e-4;//100*EPS; 00505 00506 00507 #include <stdlib.h> 00508 #include <iostream> 00509 #include <complex> 00510 using namespace std; 00511 //Complex number representation 00512 typedef std::complex<double> complex_LC; 00513 00514 00515 00516 #define R2_IM1 2147483563 00517 #define R2_IM2 2147483399 00518 #define R2_AM (1.0/R2_IM1) 00519 #define R2_IMM1 (R2_IM1-1) 00520 #define R2_IA1 40014 00521 #define R2_IA2 40692 00522 #define R2_IQ1 53668 00523 #define R2_IQ2 52774 00524 #define R2_IR1 12211 00525 #define R2_IR2 3791 00526 #define R2_NTAB 32 00527 #define R2_NDIV (1+R2_IMM1/R2_NTAB) 00528 #define R2_EPS 1.2e-7 00529 #define R2_RNMX (1.0-R2_EPS) 00530 //long rand_idnum; 00531 //=-347; 00532 00536 inline int InitialiseGenerateRandom(void){ 00537 extern long rand_idnum; 00538 srand ( time(NULL) ); 00539 rand_idnum = (long)(-rand()/double(RAND_MAX)*1000); 00540 cout << "Random generator initialised: " << rand_idnum << endl; 00541 return(1); 00542 } 00543 00547 inline double GenerateRandom(void){ 00548 extern long rand_idnum; 00549 // FROM JON JENSEN 00550 //---------------------------------------------------------------------------------------- 00551 // From Numerical Recipies, slightly modified code, same generator. 00552 int j; 00553 long k; 00554 static long idum2=123456789; 00555 static long iy=0; 00556 static long iv[R2_NTAB]; 00557 float temp; 00558 00559 if (rand_idnum <= 0) { //Initialize. 00560 if (-(rand_idnum) < 1) //Be sure to prevent rand_idnum = 0. 00561 rand_idnum=1; 00562 else 00563 rand_idnum = -(rand_idnum); 00564 idum2=(rand_idnum); 00565 for (j=R2_NTAB+7;j>=0;j--) { //Load the shuffle table (after 8 warm-ups). 00566 k=(rand_idnum)/R2_IQ1; 00567 rand_idnum=R2_IA1*(rand_idnum-k*R2_IQ1)-k*R2_IR1; 00568 if (rand_idnum < 0) 00569 rand_idnum += R2_IM1; 00570 if (j < R2_NTAB) 00571 iv[j] = rand_idnum; 00572 } 00573 iy=iv[0]; 00574 } 00575 00576 k=(rand_idnum)/R2_IQ1; //Start here when not initializing. 00577 rand_idnum=R2_IA1*(rand_idnum-k*R2_IQ1)-k*R2_IR1; //Compute rand_idnum=(IA1*rand_idnum) % IM1 without 00578 if (rand_idnum < 0) //overflows by Schrage's method. 00579 rand_idnum += R2_IM1; 00580 k=idum2/R2_IQ2; 00581 idum2=R2_IA2*(idum2-k*R2_IQ2)-k*R2_IR2; //Compute idum2=(IA2*rand_idnum) % IM2 likewise. 00582 if (idum2 < 0) 00583 idum2 += R2_IM2; 00584 j=iy/R2_NDIV; //Will be in the range 0..NTAB-1. 00585 iy=iv[j]-idum2; //Here rand_idnum is shufled, rand_idnum and idum2 are 00586 //combined to generate output. 00587 iv[j] = rand_idnum; 00588 if (iy < 1) 00589 iy += R2_IMM1; 00590 if ((temp=(float)R2_AM*iy) > R2_RNMX) //Because users don't expect endpoint values. 00591 return (float)R2_RNMX; 00592 else 00593 return temp; 00594 }; 00595 00596 00597 00598 00599 inline double square(complex_LC a) 00600 { 00601 double temp = a.real()*a.real() + a.imag()*a.imag(); 00602 return (temp*temp); 00603 } 00604 00605 // MIN and MAX functions 00606 inline double grMax(double n1,double n2){if (n1 > n2){return n1;} else return n2;} 00607 inline double grMin(double n1, double n2){if (n1 < n2){return n1;} else return n2;} 00608 00609 00610 00611 int CalcQ(const std::complex<double> n1, const std::complex<double> n2,const V3<double> wp_lmn_local, const V3<double> wp_lmn_new, 00612 double *Qss, double *Qsp, double *Qps, double *Qpp); 00613 00614 int MicroScattering2(V3<double>& wp_lmn_local, V3<double>& wp_pol_local, double wp_s_local, 00615 double wp_p_local, complex_LC refr_i,complex_LC refr_t,V2<float> rms, 00616 double lambda, double &reflfactor); 00617 00618 // Implement complex arcsin 00619 complex<double> cmplxasin(complex<double> z); 00620 00621 00622 00623 #endif