point random_sample(point p, bool (*inside)(const point), int niter) { point cur_point(p.n), next_point(p.n), delta(p.n); cur_point = p; real eps = 0.1; for(int iter = 0; iter < niter; iter++) { next_point = cur_point; random_unit_ball(&delta); delta *= eps; next_point += delta; if(inside(next_point)) { cur_point = next_point; } } return cur_point; }
void TractCluster::add_tract(const float* points,unsigned int count) { unsigned int tract_index = tract_labels.size(); tract_labels.push_back(0); tract_length.push_back(count); // get the passed region and the regoin with error std::vector<unsigned short> passed_points; std::vector<unsigned short> ranged_points; const float* points_end = points + count; for (;points_end != points;points += 3) { image::vector<3,float> cur_point(points); cur_point /= error_distance; cur_point += 0.5; cur_point.floor(); if(!dim.is_valid(cur_point)) continue; image::pixel_index<3> center(cur_point[0],cur_point[1],cur_point[2],dim); passed_points.push_back(center.index() & 0xFFFF); std::vector<image::pixel_index<3> > iterations; image::get_neighbors(center,dim,iterations); for(unsigned int index = 0;index < iterations.size();++index) if (dim.is_valid(iterations[index])) ranged_points.push_back(iterations[index].index() & 0xFFFF); } // delete repeated points { std::set<unsigned short> unique_passed_points(passed_points.begin(),passed_points.end()); passed_points = std::vector<unsigned short>(unique_passed_points.begin(),unique_passed_points.end()); std::set<unsigned short> unique_ranged_points(ranged_points.begin(),ranged_points.end()); ranged_points = std::vector<unsigned short>(unique_ranged_points.begin(),unique_ranged_points.end()); } // get the eligible fibers for merging, and also register the ending points std::vector<unsigned int> passing_tracts; if(passed_points.empty() || ranged_points.empty()) goto end; { const std::vector<unsigned int>* connection_set = add_connection(passed_points.front(),tract_index); passing_tracts.insert(passing_tracts.end(),connection_set->begin(),connection_set->end()); connection_set = add_connection(passed_points.back(),tract_index); passing_tracts.insert(passing_tracts.end(),connection_set->begin(),connection_set->end()); passing_tracts.erase(std::remove(passing_tracts.begin(),passing_tracts.end(),tract_index),passing_tracts.end()); std::set<unsigned int> unique_tracts(passing_tracts.begin(),passing_tracts.end()); passing_tracts = std::vector<unsigned int>(unique_tracts.begin(),unique_tracts.end()); } // check each tract to see if anyone is included in the error range { std::vector<unsigned int>::const_iterator iter = passing_tracts.begin(); std::vector<unsigned int>::const_iterator end = passing_tracts.end(); for (;iter !=end;++iter) { unsigned int cur_index = *iter; Cluster* label1 = tract_labels.back(); Cluster* label2 = tract_labels[cur_index]; if (label1 != 0 && label1 == label2) continue; unsigned int cur_count = tract_length[cur_index]; float dif = cur_count; dif -= (float) count; dif /= (float)std::max(cur_count,count); if (std::abs(dif) > 0.2) continue; if (std::includes(ranged_points.begin(),ranged_points.end(), tract_passed_voxels[cur_index].begin(),tract_passed_voxels[cur_index].end()) && std::includes(tract_ranged_voxels[cur_index].begin(),tract_ranged_voxels[cur_index].end(), passed_points.begin(),passed_points.end())) merge_tract(tract_index,cur_index); } } end: tract_passed_voxels.push_back(std::vector<unsigned short>()); tract_passed_voxels.back().swap(passed_points); tract_ranged_voxels.push_back(std::vector<unsigned short>()); tract_ranged_voxels.back().swap(ranged_points); }