int random_partition(int a[], int start, int end) { int ran = random_2(start, end); std::swap(a[ran], a[end]); int pivot = a[end]; int i = start - 1; for (int j = start; j < end; j++) if (a[j] <= pivot) std::swap(a[j], a[++i]); std::swap(a[++i], a[end]); return i; }
void track_through_matter( double **part, long np, MATTER *matter, double Po ) { long ip; double L, Nrad, *coord, theta_rms, beta, P, gamma=0.0; double z1, z2, dx, dy, ds, t=0.0, dGammaFactor; double K1, K2=0.0, sigmaTotal, probScatter=0.0, dgamma; long nScatters=0; log_entry("track_through_matter"); if (particleIsElectron==0) bombElegant("MATTER element doesn't work for particles other than electrons", NULL); if ((L=matter->length)==0) return; beta = Po/sqrt(sqr(Po)+1); if (matter->Xo==0) Nrad = theta_rms = 0; else { Nrad = matter->length/matter->Xo; theta_rms = 13.6/particleMassMV/Po/sqr(beta)*sqrt(Nrad)*(1+0.038*log(Nrad)); } dGammaFactor = 1-exp(-Nrad); if (Nrad<1e-3) { if (matter->Z<1 || matter->A<1 || matter->rho<=0) bombElegant("MATTER element is too thin---provide Z, A, and rho for single-scattering calculation.", NULL); K1 = 4*sqr(matter->Z*particleRadius/(beta*Po)); K2 = sqr(pow(matter->Z, 1./3.)/137.036/Po); sigmaTotal = K1*pow(PI, 3)/(sqr(K2)+K2*SQR_PI); probScatter = matter->rho/(AMU*matter->A)*matter->length*sigmaTotal; /* fprintf(stdout, "K1=%le, K2=%le, mean expected number of scatters is %le\n", K1, K2, probScatter); */ } for (ip=0; ip<np; ip++) { coord = part[ip]; if (Nrad) { if (!matter->elastic) { P = (1+coord[5])*Po; gamma = sqrt(sqr(P)+1); beta = P/gamma; t = coord[4]/beta; } if (Nrad>=1e-3) { /* multiple scattering */ z1 = gauss_rn(0, random_2); z2 = gauss_rn(0, random_2); coord[0] += (dx=(z1/SQRT_3 + z2)*L*theta_rms/2 + L*coord[1]); coord[1] += z2*theta_rms; z1 = gauss_rn(0, random_2); z2 = gauss_rn(0, random_2); coord[2] += (dy=(z1/SQRT_3 + z2)*L*theta_rms/2 + L*coord[3]); coord[3] += z2*theta_rms; ds = sqrt(sqr(L)+sqr(dx)+sqr(dy)); } else { long sections; double F, theta, phi, zs, dxp, dyp, L1, prob; sections = probScatter/matter->pLimit+1; L1 = L/sections; prob = probScatter/sections; ds = 0; while (sections-- > 0) { if (random_2(1)<prob) { nScatters ++; /* single-scattering computation */ /* scatter occurs at location 0<=zs<=L */ zs = L1*random_2(1); /* pick a value for CDF and get corresponding angle */ F = random_2(1); theta = sqrt((1-F)*K2*SQR_PI/(K2+F*SQR_PI)); phi = random_2(1)*PIx2; dxp = theta*sin(phi); dyp = theta*cos(phi); /* advance to location of scattering event */ ds += zs*sqrt(1+sqr(coord[1])+sqr(coord[3])); /* scatter */ coord[1] += dxp; coord[3] += dyp; /* advance to end of slice */ coord[0] += dxp*(L1-zs); coord[2] += dyp*(L1-zs); ds += (L1-zs)*sqrt(1+sqr(coord[1])+sqr(coord[3])); } else { ds += L1*sqrt(1+sqr(coord[1])+sqr(coord[3])); coord[0] += coord[1]*L1; coord[2] += coord[3]*L1; } } } if (!matter->elastic) { dgamma = gamma*dGammaFactor; if (matter->energyStraggle) { double dgamma1; /* very simple-minded estimate: StDev(dE) = Mean(dE)/2 */ while ((dgamma1 = dgamma*(1+0.5*gauss_rn(0, random_2)))<0) ; dgamma = dgamma1; } gamma -= dgamma; P = sqrt(sqr(gamma)-1); coord[5] = (P-Po)/Po; beta = P/gamma; coord[4] = t*beta+ds; } else coord[4] += ds; } else { coord[0] += L*coord[1]; coord[2] += L*coord[3]; coord[4] += L*sqrt(1+sqr(coord[1])+sqr(coord[3])); } } /* if (Nrad<1e-3) fprintf(stdout, "%e scatters per particle\n", (1.0*nScatters)/np); */ log_exit("track_through_matter"); }
/* Launches one of those fancy effects. */ void launch_effect(int effect) { switch (effect) { case 0: /* Lights all the layers one by one. */ load_bar(1000); break; case 1: /* A pixel bouncing randomly around. */ boing_boing(150, 500, 0x03, 0x01); break; case 2: /* Randomly fill and empty the cube. */ fill(0x00); random_filler(100, 1, 500, 1); random_filler(100, 1, 500, 0); break; case 3: /* Send voxels randomly back and forth the z-axis. */ send_voxels_rand_z(150, 500, 2000); break; case 4: /* Spinning spiral */ spiral(1, 75, 1000); break; case 5: /* A coordinate bounces randomly around the cube. For every position * the status of that voxel is toggled. */ boing_boing(150, 500, 0x03, 0x02); break; case 6: /* Random raindrops */ rain(40, 1000, 500, 500); break; case 7: /* Snake: a snake randomly bounce around the cube. */ boing_boing(150, 500, 0x03, 0x03); break; case 8: /* Spinning plane */ spinning_plane(1, 50, 1000); break; case 9: /* Set x number of random voxels, delay, unset them. x increases * from 1 to 32 and back to 1. */ random_2(48); break; case 10: /* Set then unset all 64 voxels in a random order. */ random_filler2(200, 1); delay_ms(2000); random_filler2(200, 0); delay_ms(1000); break; case 11: /* Bounce a plane up and down all the directions. */ fly_plane('z', 1, 1000); delay_ms(2000); fly_plane('y', 1, 1000); delay_ms(2000); fly_plane('x', 1, 1000); delay_ms(2000); fly_plane('z', 0, 1000); delay_ms(2000); fly_plane('y', 0, 1000); delay_ms(2000); fly_plane('x', 0, 1000); delay_ms(2000); break; case 12: /* Fade in and out at low framerate. */ blinky2(); break; case 13: /* Random walk */ random_walk(4, 250, 1000); break; case 14: /* Spinning square */ spinning_square(1, 50, 1000); break; } }