123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- #include "defs.h"
- extern char errstr[200];
- int raytrace(FLOAT_GRID *electron_density_grid,FLOAT_GRID *radiological_depth_grid,
- POINT point1,POINT point2)
- {
- float x1,y1,z1,
- x2,y2,z2,
- xp1,yp1,zp1,
- dx,dy,dz;
- int Nx,Ny,Nz;
- float xpN, ypN, zpN;
- float alpha_x_min,alpha_y_min,alpha_z_min,alpha_x_max,alpha_y_max,alpha_z_max;
-
- float alpha_min, alpha_max;
- int i_min,i_max,j_min,j_max,k_min,k_max;
- float *alpha_x,*alpha_y,*alpha_z;
- float *alpha;
- int i_index,j_index,k_index;
- int a;
- int max_index;
- float d12;
- float alpha_mid;
- float length;
- int i,j,k;
- float rpl = 0.0;
- float voxel_density;
- float lmax;
- float pnorm;
- x1 = point1.x;
- y1 = point1.y;
- z1 = point1.z;
- x2 = point2.x;
- y2 = point2.y;
- z2 = point2.z;
- Nx = electron_density_grid->x_count + 1;
- Ny = electron_density_grid->y_count + 1;
- Nz = electron_density_grid->z_count + 1;
- dx = electron_density_grid->inc.x;
- dy = electron_density_grid->inc.y;
- dz = electron_density_grid->inc.z;
- xp1 = electron_density_grid->start.x - 0.5*dx;
- yp1 = electron_density_grid->start.y - 0.5*dy;
- zp1 = electron_density_grid->start.z - 0.5*dz;
- pnorm = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) + (z2-z1)*(z2-z1));
- lmax = sqrt(pow((x2-x1)*dx,2.0f)+pow((y2-y1)*dy,2.0f)+pow((z2-z1)*dz,2.0f))/pnorm;
- xpN = xp1 + (Nx-1)*dx;
- ypN = yp1 + (Ny-1)*dy;
- zpN = zp1 + (Nz-1)*dz;
- if (x1==x2)
- x2 += 0.00001;
- if (y1==y2)
- y2 += 0.00001;
- if (z1==z2)
- z2 += 0.00001;
- if ((fabs(x1-x2)<dx) && (fabs(y1-y2)<dy) && (fabs(z1-z2)<dz))
- {
- sprintf(errstr,"Error - ray trace region too small.");
- return(FAILURE);
- }
- alpha_x_min = (((xp1-x1)/(x2-x1))<((xpN-x1)/(x2-x1))) ? ((xp1-x1)/(x2-x1))
- : ((xpN-x1)/(x2-x1));
- alpha_y_min = (((yp1-y1)/(y2-y1))<((ypN-y1)/(y2-y1))) ? ((yp1-y1)/(y2-y1))
- : ((ypN-y1)/(y2-y1));
- alpha_z_min = (((zp1-z1)/(z2-z1))<((zpN-z1)/(z2-z1))) ? ((zp1-z1)/(z2-z1))
- : ((zpN-z1)/(z2-z1));
- alpha_x_max = (((xp1-x1)/(x2-x1))>((xpN-x1)/(x2-x1))) ? ((xp1-x1)/(x2-x1))
- : ((xpN-x1)/(x2-x1));
- alpha_y_max = (((yp1-y1)/(y2-y1))>((ypN-y1)/(y2-y1))) ? ((yp1-y1)/(y2-y1))
- : ((ypN-y1)/(y2-y1));
- alpha_z_max = (((zp1-z1)/(z2-z1))>((zpN-z1)/(z2-z1))) ? ((zp1-z1)/(z2-z1))
- : ((zpN-z1)/(z2-z1));
- alpha_min = (alpha_x_min>alpha_y_min) ? alpha_x_min : alpha_y_min;
- if (alpha_z_min>alpha_min)
- alpha_min = alpha_z_min;
- if (alpha_min<0)
- alpha_min = 0;
- alpha_max = (alpha_x_max<alpha_y_max) ? alpha_x_max : alpha_y_max;
- if (alpha_z_max<alpha_max)
- alpha_max = alpha_z_max;
- if (alpha_max>1)
- alpha_max = 1;
-
- i_min = (x2>x1) ? (int) ceil((float) Nx - (xpN-alpha_min*(x2-x1)-x1)/dx-0.001)
- : (int) ceil((float) Nx - (xpN-alpha_max*(x2-x1)-x1)/dx-0.001);
- i_max = (x2>x1) ? (int) floor(1.0000 + (x1+alpha_max*(x2-x1)-xp1)/dx+0.001)
- : (int) floor(1.0000 + (x1+alpha_min*(x2-x1)-xp1)/dx+0.001);
- j_min = (y2>y1) ? (int) ceil((float) Ny - (ypN-alpha_min*(y2-y1)-y1)/dy-0.001)
- : (int) ceil((float) Ny - (ypN-alpha_max*(y2-y1)-y1)/dy-0.001);
- j_max = (y2>y1) ? (int) floor(1.0000 + (y1+alpha_max*(y2-y1)-yp1)/dy+0.001)
- : (int) floor(1.0000 + (y1+alpha_min*(y2-y1)-yp1)/dy+0.001);
- k_min = (z2>z1) ? (int) ceil((float) Nz - (zpN-alpha_min*(z2-z1)-z1)/dz-0.001)
- : (int) ceil((float) Nz - (zpN-alpha_max*(z2-z1)-z1)/dz-0.001);
- k_max = (z2>z1) ? (int) floor(1.0000 + (z1+alpha_max*(z2-z1)-zp1)/dz+0.001)
- : (int) floor(1.0000 + (z1+alpha_min*(z2-z1)-zp1)/dz+0.001);
- if ((alpha_x = (float*) calloc(Nx+1,sizeof(float))) == NULL)
- {
- sprintf(errstr,"Error - insufficient heap for alpha_x allocation.");
- return(FAILURE);
- }
- if ((alpha_y = (float*) calloc(Ny+1,sizeof(float))) == NULL)
- {
- sprintf(errstr,"Error - insufficient heap for alpha_y allocation.");
- return(FAILURE);
- }
- if ((alpha_z = (float*) calloc(Nz+1,sizeof(float))) == NULL)
- {
- sprintf(errstr,"Error - insufficient heap for alpha_z allocation.");
- return(FAILURE);
- }
-
- if (i_min <= i_max)
- if (x2>x1)
- {
- alpha_x[0] = ((xp1+(i_min-1)*dx)-x1)/(x2-x1);
- for (a=1;a<=i_max-i_min;a++)
- alpha_x[a] = alpha_x[a-1]+dx/(x2-x1);
- }
- else
- {
- alpha_x[i_max-i_min] = ((xp1+(i_min-1)*dx)-x1)/(x2-x1);
- for (a=i_max-i_min-1;a>=0;a--)
- alpha_x[a] = alpha_x[a+1]+(dx/(x2-x1));
- }
- alpha_x[i_max-i_min+1] = 10000.0;
- if (j_min <= j_max)
- if (y2>y1)
- {
- alpha_y[0] = ((yp1+(j_min-1)*dy)-y1)/(y2-y1);
- for (a=1;a<=j_max-j_min;a++)
- alpha_y[a] = alpha_y[a-1]+dy/(y2-y1);
- }
- else
- {
- alpha_y[j_max-j_min] = ((yp1+(j_min-1)*dy)-y1)/(y2-y1);
- for (a=j_max-j_min-1;a>=0;a--)
- alpha_y[a] = alpha_y[a+1]+(dy/(y2-y1));
- }
- alpha_y[j_max-j_min+1] = 10001.0;
- if (k_min <= k_max)
- if (z2>z1)
- {
- alpha_z[0] = ((zp1+(k_min-1)*dz)-z1)/(z2-z1);
- for (a=1;a<=k_max-k_min;a++)
- alpha_z[a] = alpha_z[a-1]+(dz/(z2-z1));
- }
- else
- {
- alpha_z[k_max-k_min] = ((zp1+(k_min-1)*dz)-z1)/(z2-z1);
- for (a=k_max-k_min-1;a>=0;a--)
- alpha_z[a] = alpha_z[a+1]+(dz/(z2-z1));
- }
- alpha_z[k_max-k_min+1] = 10002.0;
- if ((alpha = (float*) calloc(Nx+Ny+Nz+3,sizeof(float))) == NULL)
- {
- sprintf(errstr,"Error - insufficient heap for alpha allocation.");
- return(FAILURE);
- }
- max_index = (i_max-i_min+1)+(j_max-j_min+1)+(k_max-k_min+1)+1;
- alpha[0] = alpha_min;
- i_index = 0;
- j_index = 0;
- k_index = 0;
- for (a=1;a<=max_index-1;a++)
- if (alpha_x[i_index]<alpha_y[j_index])
- if (alpha_x[i_index]<alpha_z[k_index])
- {
- alpha[a] = alpha_x[i_index];
- i_index += 1;
- }
- else
- {
- alpha[a] = alpha_z[k_index];
- k_index += 1;
- }
- else
- if (alpha_y[j_index]<alpha_z[k_index])
- {
- alpha[a] = alpha_y[j_index];
- j_index += 1;
- }
- else
- {
- alpha[a] = alpha_z[k_index];
- k_index += 1;
- }
- alpha[max_index] = alpha_max;
- free(alpha_x);
- free(alpha_y);
- free(alpha_z);
- d12 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1));
-
- for (a=1;a<=max_index;a++)
- {
- length = d12*(alpha[a]-alpha[a-1]);
- if (fabs(length)>0.01)
- {
- alpha_mid = (alpha[a]+alpha[a-1])/2.0;
-
- i = (int) floor((x1 + alpha_mid*(x2-x1) - xp1)/dx);
- j = (int) floor((y1 + alpha_mid*(y2-y1) - yp1)/dy);
- k = (int) floor((z1 + alpha_mid*(z2-z1) - zp1)/dz);
-
-
-
- voxel_density = GRID_VALUE(electron_density_grid,i,j,k);
- rpl += length * voxel_density/2.0;
-
-
- if (length>=0.75/2*lmax && GRID_VALUE(radiological_depth_grid,i,j,k)<0.0)
- GRID_VALUE(radiological_depth_grid, i, j, k) = rpl;
-
- rpl += length * voxel_density/2.0;
- }
- }
- free(alpha);
- return(SUCCESS);
- }
|