1 #ifndef VORONOTALT_SPHERES_SEARCHER_H_ 2 #define VORONOTALT_SPHERES_SEARCHER_H_ 7 #include "basic_types_and_functions.h" 19 explicit SpheresSearcher(
const std::vector<SimpleSphere>& spheres) noexcept
24 void init(
const std::vector<SimpleSphere>& spheres) noexcept
27 grid_parameters_=GridParameters(spheres_);
31 bool update(
const std::vector<SimpleSphere>& spheres,
const std::vector<UnsignedInt>& ids_to_update) noexcept
33 if(ids_to_update.empty())
38 if(ids_to_update.size()>size_threshold_for_full_rebuild())
44 for(UnsignedInt i=0;i<ids_to_update.size();i++)
46 if(ids_to_update[i]>=spheres.size() || !update_sphere(ids_to_update[i], spheres[ids_to_update[i]]))
58 grid_parameters_=obj.grid_parameters_;
60 spheres_.resize(obj.spheres_.size());
61 map_of_boxes_.resize(obj.map_of_boxes_.size());
62 boxes_.resize(obj.boxes_.size());
65 #ifdef VORONOTALT_OPENMP 66 #pragma omp parallel for 68 for(UnsignedInt i=0;i<obj.spheres_.size();i++)
70 spheres_[i]=obj.spheres_[i];
75 #ifdef VORONOTALT_OPENMP 76 #pragma omp parallel for 78 for(UnsignedInt i=0;i<obj.map_of_boxes_.size();i++)
80 map_of_boxes_[i]=obj.map_of_boxes_[i];
85 #ifdef VORONOTALT_OPENMP 86 #pragma omp parallel for 88 for(UnsignedInt i=0;i<obj.boxes_.size();i++)
90 boxes_[i]=obj.boxes_[i];
95 const std::vector<SimpleSphere>& searchable_spheres()
const noexcept
100 bool find_colliding_ids(
const UnsignedInt& central_id, std::vector<ValuedID>& colliding_ids,
const bool discard_hidden,
int& exclusion_status)
const noexcept
102 colliding_ids.clear();
104 if(central_id<spheres_.size())
106 const SimpleSphere& central_sphere=spheres_[central_id];
107 const GridPoint gp(central_sphere, grid_parameters_.box_size, grid_parameters_.grid_offset);
109 for(
int dx=-1;dx<=1;dx++)
112 for(
int dy=-1;dy<=1;dy++)
115 for(
int dz=-1;dz<=1;dz++)
118 const int index=dgp.index(grid_parameters_.grid_size);
121 const int box_id=map_of_boxes_[index];
124 const std::vector<UnsignedInt>& ids=boxes_[box_id];
125 for(UnsignedInt i=0;i<ids.size();i++)
127 const UnsignedInt
id=ids[i];
129 if(
id!=central_id && sphere_intersects_sphere(central_sphere, candidate_sphere))
132 && sphere_contains_sphere(candidate_sphere, central_sphere)
133 && (!sphere_equals_sphere(candidate_sphere, central_sphere) || central_id>id))
135 colliding_ids.clear();
139 else if(!discard_hidden
140 || !sphere_contains_sphere(central_sphere, candidate_sphere))
142 colliding_ids.push_back(
ValuedID(distance_to_center_of_intersection_circle_of_two_spheres(central_sphere, candidate_sphere),
id));
152 if(!colliding_ids.empty())
154 std::sort(colliding_ids.begin(), colliding_ids.end());
156 return (!colliding_ids.empty());
166 GridPoint() noexcept: x(0), y(0), z(0)
170 GridPoint(
const SimpleSphere& s,
const Float grid_step) noexcept
175 GridPoint(
const SimpleSphere& s,
const Float grid_step,
const GridPoint& grid_offset) noexcept
177 init(s, grid_step, grid_offset);
180 void init(
const SimpleSphere& s,
const Float grid_step) noexcept
182 x=
static_cast<int>(s.p.x/grid_step);
183 y=
static_cast<int>(s.p.y/grid_step);
184 z=
static_cast<int>(s.p.z/grid_step);
187 void init(
const SimpleSphere& s,
const Float grid_step,
const GridPoint& grid_offset) noexcept
189 x=
static_cast<int>(s.p.x/grid_step)-grid_offset.x;
190 y=static_cast<int>(s.p.y/grid_step)-grid_offset.y;
191 z=
static_cast<int>(s.p.z/grid_step)-grid_offset.z;
194 int index(
const GridPoint& grid_size)
const noexcept
196 return ((x>=0 && y>=0 && z>=0 && x<grid_size.x && y<grid_size.y && z<grid_size.z) ? (z*grid_size.x*grid_size.y+y*grid_size.x+x) : (-1));
199 bool operator<(
const GridPoint& gp)
const noexcept
201 return (x<gp.x || (x==gp.x && y<gp.y) || (x==gp.x && y==gp.y && z<gp.z));
204 bool operator==(
const GridPoint& gp)
const noexcept
206 return (x==gp.x && y==gp.y && z==gp.z);
210 struct GridParameters
212 GridPoint grid_offset;
217 GridParameters() noexcept : box_size(FLOATCONST(1.0)), padding_(1)
224 explicit GridParameters(
const std::vector<SimpleSphere>& spheres) noexcept : box_size(FLOATCONST(1.0)), padding_(1)
229 GridParameters(
const std::vector<SimpleSphere>& spheres,
const int padding) noexcept : box_size(FLOATCONST(1.0)), padding_(padding)
234 void init(
const std::vector<SimpleSphere>& spheres) noexcept
236 box_size=FLOATCONST(1.0);
237 padding_=std::max(0, padding_);
239 for(UnsignedInt i=0;i<spheres.size();i++)
242 box_size=std::max(box_size, s.r*FLOATCONST(2.0)+FLOATCONST(0.25));
245 for(UnsignedInt i=0;i<spheres.size();i++)
247 const GridPoint gp(spheres[i], box_size);
255 grid_offset.x=std::min(grid_offset.x, gp.x-padding_);
256 grid_offset.y=std::min(grid_offset.y, gp.y-padding_);
257 grid_offset.z=std::min(grid_offset.z, gp.z-padding_);
258 grid_size.x=std::max(grid_size.x, gp.x+padding_);
259 grid_size.y=std::max(grid_size.y, gp.y+padding_);
260 grid_size.z=std::max(grid_size.z, gp.z+padding_);
264 grid_size.x=grid_size.x-grid_offset.x+1;
265 grid_size.y=grid_size.y-grid_offset.y+1;
266 grid_size.z=grid_size.z-grid_offset.z+1;
269 bool operator==(
const GridParameters& gp)
const noexcept
271 return (box_size==gp.box_size && grid_offset==gp.grid_offset && grid_size==gp.grid_size);
275 UnsignedInt size_threshold_for_full_rebuild()
const noexcept
277 return static_cast<UnsignedInt
>(spheres_.size()/2);
280 void init_boxes() noexcept
282 map_of_boxes_.clear();
285 map_of_boxes_.resize(grid_parameters_.grid_size.x*grid_parameters_.grid_size.y*grid_parameters_.grid_size.z, -1);
287 for(UnsignedInt i=0;i<spheres_.size();i++)
289 const GridPoint gp(spheres_[i], grid_parameters_.box_size, grid_parameters_.grid_offset);
290 const int index=gp.index(grid_parameters_.grid_size);
291 const int box_id=map_of_boxes_[index];
294 map_of_boxes_[index]=
static_cast<int>(boxes_.size());
295 boxes_.push_back(std::vector<UnsignedInt>(1, i));
299 boxes_[box_id].push_back(i);
304 bool update_sphere(
const UnsignedInt& sphere_id,
const SimpleSphere& moved_sphere) noexcept
306 if(sphere_id<spheres_.size() && moved_sphere.r<=spheres_[sphere_id].r)
308 const GridPoint gp1(moved_sphere, grid_parameters_.box_size, grid_parameters_.grid_offset);
309 const int index1=gp1.index(grid_parameters_.grid_size);
312 const GridPoint gp0(spheres_[sphere_id], grid_parameters_.box_size, grid_parameters_.grid_offset);
313 const int index0=gp0.index(grid_parameters_.grid_size);
319 const int box_id0=map_of_boxes_[index0];
326 std::vector<UnsignedInt>& v0=boxes_[box_id0];
327 std::vector<UnsignedInt>::iterator it=std::lower_bound(v0.begin(), v0.end(), sphere_id);
328 if(it!=v0.end() && (*it)==sphere_id)
336 const int box_id1=map_of_boxes_[index1];
339 map_of_boxes_[index1]=
static_cast<int>(boxes_.size());
340 boxes_.push_back(std::vector<UnsignedInt>(1, sphere_id));
344 std::vector<UnsignedInt>& v1=boxes_[box_id1];
345 std::vector<UnsignedInt>::iterator it=std::lower_bound(v1.begin(), v1.end(), sphere_id);
346 if(it==v1.end() || (*it)!=sphere_id)
348 v1.insert(it, sphere_id);
353 spheres_[sphere_id]=moved_sphere;
361 std::vector<SimpleSphere> spheres_;
362 GridParameters grid_parameters_;
363 std::vector<int> map_of_boxes_;
364 std::vector< std::vector<UnsignedInt> > boxes_;
Definition: spheres_searcher.h:12
Definition: basic_types_and_functions.h:83
Definition: basic_types_and_functions.h:19
Definition: basic_types_and_functions.h:49