#include #include #include #include #include #include using namespace std; #include "ice.cxx" double xrnd(){ double rnd=0; while(rnd==0){ rnd=rand(); rnd/=RAND_MAX; } return rnd; } struct KEY{ int str, om; KEY(){ str=-1; om=-1; } bool operator< (const KEY& rhs) const{ return str < rhs.str || (str == rhs.str && om < rhs.om); } }; struct STR{ bool zf; int l, h; double zn, zx, sp; double rl[3], rh[3]; STR(){ zf=true; sp=-1; } }; map strs; struct DOM{ double r[3], R; DOM(){ R=0.178; } }; map doms; void load(){ ifstream inFile; inFile.open("geo-f2k", ifstream::in); if(!inFile.fail()){ KEY key; DOM dom; string id; unsigned long long domid; while(inFile>>id>>hex>>domid>>dec>>dom.r[0]>>dom.r[1]>>dom.r[2]>>key.str>>key.om) if(key.str>0 && key.om>=1 && key.om<=60){ doms[key]=dom; STR & s=strs[key.str]; if(s.sp<0){ s.l=key.om; s.h=key.om; for(int i=0; i<3; i++){ s.rl[i]=dom.r[i]; s.rh[i]=dom.r[i]; } s.sp=0; } else{ if(key.oms.h) s.h=key.om; for(int i=0; i<3; i++){ if(dom.r[i]s.rh[i]) s.rh[i]=dom.r[i]; } s.sp++; } } inFile.close(); } for(map::iterator s=doms.begin(); s!=doms.end(); s++){ STR & str=strs[s->first.str]; double dz=s->second.r[2]-(str.rl[2]+(s->first.om-str.h)*(str.rh[2]-str.rl[2])/(str.l-str.h)); if(str.zf){ str.zn=dz; str.zx=dz; str.zf=false; } else{ if(dzstr.zx) str.zx=dz; } } cerr<::iterator s=doms.begin(); s!=doms.end(); s++) if(s->first.str==str && s->first.om==om){ for(int i=0; i<3; i++) r[i]=s->second.r[i]; doms.erase(s); break; } } void circ(){ double xi=xrnd(); xi*=2*M_PI; n[0]=cos(xi); n[1]=sin(xi); n[2]=0; } } x; struct quat{ double val[4]; }; quat operator*(const quat &l, const quat &r){ quat z; z.val[0]=l.val[0]*r.val[0]-l.val[1]*r.val[1]-l.val[2]*r.val[2]-l.val[3]*r.val[3]; z.val[1]=l.val[0]*r.val[1]+l.val[1]*r.val[0]+l.val[2]*r.val[3]-l.val[3]*r.val[2]; z.val[2]=l.val[0]*r.val[2]-l.val[1]*r.val[3]+l.val[2]*r.val[0]+l.val[3]*r.val[1]; z.val[3]=l.val[0]*r.val[3]+l.val[1]*r.val[2]-l.val[2]*r.val[1]+l.val[3]*r.val[0]; return z; } struct photon{ double r[3], n[3], d, t; double c, g, la, ls; double xx; photon(){ d=0; t=0; for(int i=0; i<3; i++){ r[i]=x.r[i]; n[i]=x.n[i]; } xx=1.e-5; c=m.c; g=m.g; la=m.la; ls=m.ls; } void rotate(){ double u[3]; { double p1[3], p2[3]; { int i0=0; double n0=n[0]; for(int i=1; i<3; i++) if(abs(n[i])>abs(n0)){ i0=i; n0=n[i]; } int i1=(i0+1)%3, i2=(i0+2)%3; double n1=n[i1], n2=n[i2]; double z1=n1/n0, z2=n2/n0; double r1=sqrt(1+z1*z1), r2=sqrt(1+z2*z2); p1[i0]=-z1/r1; p1[i1]=1/r1; p1[i2]=0; p2[i0]=-z2/r2; p2[i1]=0; p2[i2]=1/r2; } { double q1[3], q2[3], r1=0, r2=0; for(int i=0; i<3; i++){ double a1=p1[i]-p2[i]; q1[i]=a1; r1+=a1*a1; double a2=p1[i]+p2[i]; q2[i]=a2; r2+=a2*a2; } r1=sqrt(r1); r2=sqrt(r2); for(int i=0; i<3; i++){ p1[i]=q1[i]/r1; p2[i]=q2[i]/r2; } } { double zi=xrnd(); zi*=2*M_PI; double px=cos(zi), py=sin(zi); for(int i=0; i<3; i++) u[i]=px*p1[i]+py*p2[i]; } } { double xi=xrnd(); xi=2*xi-1; if(g!=0){ double g2=g*g; double ga=(1-g2)/(1+g*xi); xi=(1+g2-ga*ga)/(2*g); } double c=sqrt((1+xi)/2), s=sqrt((1-xi)/2); quat q1, q2, v; { q1.val[0]=c; q2.val[0]=c; v.val[0]=0; } for(int i=0; i<3; i++){ double a=s*u[i]; q1.val[i+1]=a; q2.val[i+1]=-a; v.val[i+1]=n[i]; } quat f=q1*v*q2; double r=0; for(int i=0; i<3; i++){ double a=f.val[i+1]; n[i]=a; r+=a*a; } r=sqrt(r); for(int i=0; i<3; i++) n[i]/=r; } } void advance(double a){ d+=a; t+=a/c; for(int i=0; i<3; i++) r[i]+=n[i]*a; } void propagate(){ double TOT=-log(xrnd()); while(true){ double tot=m.aX(TOT, r[2], n[2]); double SCA=-log(xrnd()); double sca=m.sX(SCA, r[2], n[2]); if(sca>tot) sca=tot; KEY om=sphere(sca); TOT-=m.xA(sca, r[2], n[2]); advance(sca); if(om.str>=0){ cout<::const_iterator str=strs.begin(); str!=strs.end(); str++){ bool pass=false; const STR & s=str->second; for(int i=0; i<3; i++){ if(n[i]>0){ if(s.rh[i]r[i]+sca*n[i]){ pass=true; break; } } else{ if(s.rl[i]>r[i] || s.rh[i]0){ min=s.h-(r[2]+sca*n[2]-s.zn-s.rl[2])*st; max=s.h-(r[2]-s.zx-s.rl[2])*st; } else{ min=s.h-(r[2]-s.zn-s.rl[2])*st; max=s.h-(r[2]+sca*n[2]-s.zx-s.rl[2])*st; } int n1=(int)floor(min); int n2=(int)ceil(max); if(n1>s.h | n2first; key.om=om; DOM dom=doms[key]; double R=dom.R; double b=0, c=0; for(int i=0; i<3; i++){ double dr=dom.r[i]-r[i]; b+=n[i]*dr; c+=dr*dr; } c-=R*R; double D=b*b-c, h=-1; if(D>0){ D=sqrt(D); h=b-D; if(h<0) h=b+D; } if(h>0 && h=0) sca=hmin; return imin; } }; main(int arg_c, char *arg_a[]){ if(arg_c>1){ int str=0, dom=0; unsigned int seed=0; unsigned long long num=1000000ULL; if(arg_c>1) str=atoi(arg_a[1]); if(arg_c>2) dom=atoi(arg_a[2]); if(arg_c>3) num=(unsigned long long) atof(arg_a[3]); if(arg_c>4) seed=atoi(arg_a[4]); srand(1+seed); x.init(str, dom); for(unsigned long long i=0; i