void prepare_image(t_fdf *e) { int i; int j; int size; t_3d *v; t_3d **vertexes; if (!init_scales(e)) return ; i = -1; size = e->npw; vertexes = e->p; while ((v = vertexes[++i])) { j = -1; while (++j < size) { v[j].x = (FDF_SQRT2_2 * (j * e->off - i * e->off) + e->dx) * e->f; v[j].y = (FDF_SQRT_23_ * -v[j].z + FDF_1_SQRT6 * (j * e->off + i * e->off) + e->dy) * e->f; if (j) trace_line(e, &v[j - 1], &v[j]); if (i) trace_line(e, &vertexes[i - 1][j], &v[j]); } } }
void draw(t_img *img, t_2d *map) { int i; i = 0; while (i < map[i].xlen * map[i].ylen) { if (i % map->xlen < map->xlen - 1) trace_line(img, &map[i], &map[i + 1]); if (i / map->xlen < map->ylen - 1) trace_line(img, &map[i], &map[i + map->xlen]); i++; } }
static void * thread(void *arg) { ThreadArg* thread_arg = arg; for (;;) { pthread_mutex_lock(&thread_arg->mutex); if (thread_arg->next_line == thread_arg->height) break; long line = thread_arg->next_line++; pthread_mutex_unlock(&thread_arg->mutex); trace_line(line, thread_arg->width, thread_arg->buffer + line * 4 * thread_arg->width); } pthread_mutex_unlock(&thread_arg->mutex); return NULL; }
void trace_scene(float time, int width, int height, unsigned char *buf, int threaded) { if (trace_vectors && (trace_vectors_width != width || trace_vectors_height != height)) { free(trace_vectors); trace_vectors = 0; } if (!trace_vectors) initialize_trace_vectors(width, height); objects[0].position[0] = (1.5 + 0.35 * sin(1.0 * time + 0.0)) * cos(0.5 * time); objects[0].position[1] = (1.5 + 0.35 * sin(1.0 * time + 2.5)) * sin(0.5 * time); objects[1].position[0] = (1.5 + 0.35 * sin(1.0 * time + 2.0)) * cos(0.5 * time + 1/3. * TAU); objects[1].position[1] = (1.5 + 0.35 * sin(1.0 * time + 1.5)) * sin(0.5 * time + 1/3. * TAU); objects[3].position[0] = (1.5 + 0.35 * sin(1.0 * time + 1.0)) * cos(0.5 * time + 2/3. * TAU); objects[3].position[1] = (1.5 + 0.35 * sin(1.0 * time + 0.5)) * sin(0.5 * time + 2/3. * TAU); objects[2].position[2] = -3 + 0.2 * sin(time * 1.0); memcpy(objects[4].position, objects[2].position, sizeof(objects[4].position)); if(threaded) { ThreadArg arg; memset(&arg, 0, sizeof(arg)); arg.width = width; arg.height = height; pthread_mutex_init(&arg.mutex, NULL); arg.buffer = buf; int num_threads = sysconf(_SC_NPROCESSORS_CONF) - 1; pthread_t* threads = NULL; if (num_threads > 0) { threads = calloc(sizeof(*threads), num_threads); for (int i = 0; i < num_threads; ++i) pthread_create(&threads[i], NULL, thread, &arg); } thread(&arg); for(int i = 0; i < num_threads; ++i) pthread_join(threads[i], NULL); free(threads); } else { for(int i = 0; i < height; ++i) trace_line(i, width, buf + i * 4 * width); } }
// add photon background to the dose distribution bool e_beam_triple_poly::add_photons(real &cpu_time, int n_batch) { // measure CPU time real cpu_start = etime(); // determine dose maximum float dose,dose_max = ZERO; for (register int k=0; k<dim.z; ++k) { for (register int j=0; j<dim.y; ++j) { for (register int i=0; i<dim.x; ++i) { dose = beam_dose->matrix[i][j][k]; if (dose > dose_max) dose_max = dose; } } } xvmc_message("Maximum dose before photon correction:", dose_max,"10^-10 Gy cm^2",1); // calculate scaled photon background depth parameters real p_a = photo_a*dose_max/100.0; real p_b = photo_b*dose_max/100.0; real p_c = 6.0*log(20.0)/energy_max; // calculate minimum and maximum beam angles for photon background real tan_x_min=(app_x1 - 10.0)/app_distance; real tan_x_max=(app_x2 + 10.0)/app_distance; real tan_y_min=(app_y1 - 10.0)/app_distance; real tan_y_max=(app_y2 + 10.0)/app_distance; // calculate photon background profile parameters real rx2 = 1.0 - (app_width_x-4.0)/42.0; rx2 = 0.66*(rx2*app_width_x)*(rx2*app_width_x); real ry2 = 1.0 - (app_width_y-4.0)/42.0; ry2 = 0.66*(ry2*app_width_y)*(ry2*app_width_y); // calculate photon background for all voxels // (fan lines from origin point to each voxel center) real_3 pos; // position of voxel center real_3 dop; // difference vector from origin to voxel center real temp; pos.z = -voxel_size.z*ONE_HALF; for (register int k=0; k<dim.z; ++k) { pos.z += voxel_size.z; dop.z = pos.z - origin.z; pos.y = -voxel_size.y*ONE_HALF; for (register int j=0; j<dim.y; ++j) { pos.y += voxel_size.y; dop.y = pos.y - origin.y; pos.x = -voxel_size.x*ONE_HALF; for (register int i=0; i<dim.x; ++i) { pos.x += voxel_size.x; dop.x = pos.x - origin.x; // origin to voxel center distance real dist = sqrt(dop.x*dop.x + dop.y*dop.y + dop.z*dop.z); // fan line direction vector real_3 dir; dir.x = dop.x/dist; dir.y = dop.y/dist; dir.z = dop.z/dist; // rotate back by the table angle temp = dir.x*sin_beta; dir.x = dir.x*cos_beta - dir.y*sin_beta; dir.y = temp + dir.y*cos_beta; // rotate back by the gantry angle temp = dir.x*sin_alpha; dir.x = dir.x*cos_alpha + dir.z*sin_alpha; dir.z = -temp + dir.z*cos_alpha; // rotate back by the collimator angle temp = dir.x*sin_gamma; dir.x = dir.x*cos_gamma - dir.y*sin_gamma; dir.y = temp + dir.y*cos_gamma; // investigate fan lines if (fabs(dir.z) > ZERO) { real tan_x = dir.x/fabs(dir.z); real tan_y = dir.y/fabs(dir.z); // the fan line must be within the beam cone if ((tan_x > tan_x_min) && (tan_x < tan_x_max)) { if ((tan_y > tan_y_min) && (tan_y < tan_y_max)) { // geometrical length within the cube (dummy variable) real length = ZERO; // effective length in water real eff_length = trace_line(origin, pos, length); // profile parameters temp = app_distance*tan_x; real bpx = exp(-temp*temp/rx2); temp = app_distance*tan_y; real bpy = exp(-temp*temp/ry2); // depth parameters real dose = p_b*(ONE-exp(-eff_length*p_c)) + p_a*eff_length; // total photon dose (must be larger than 0) dose *= bpx*bpy; if (dose < ZERO) dose = ZERO; // dose in vacuum or air is 0 real rho = density->matrix[i][j][k]; const real rho_min = 0.01; dose = rho > rho_min ? dose : ZERO; // the photon background should not contribute to the // statistical uncertainty, the following update to the // "beam_error->matrix" provides this functionality real error = (TWO*dose*beam_dose->matrix[i][j][k]+dose*dose)/n_batch; // add photon background to beam dose and error matrices beam_dose->matrix[i][j][k] += dose; beam_error->matrix[i][j][k] += error; } } } } } } // measure CPU time cpu_time = etime() - cpu_start; return(true); }