Poisson disc for periodic situation
This commit is contained in:
parent
ec23ab8b61
commit
e5b414419a
|
@ -31,10 +31,10 @@ def from_random(size,N_seeds,grid=None,seed=None):
|
|||
coords = grid_coords[rng.choice(_np.prod(grid),N_seeds, replace=False)] \
|
||||
+ _np.broadcast_to(size/grid,(N_seeds,3))*(rng.random((N_seeds,3))*.5-.25) # wobble without leaving grid
|
||||
|
||||
coords
|
||||
return coords
|
||||
|
||||
|
||||
def from_Poisson_disc(size,N_seeds,N_candidates,distance,seed=None):
|
||||
def from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=True,seed=None):
|
||||
"""
|
||||
Seeding in space according to a Poisson disc distribution.
|
||||
|
||||
|
@ -48,6 +48,8 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,seed=None):
|
|||
Number of candidates to consider for finding best candidate.
|
||||
distance : float
|
||||
Minimum acceptable distance to other seeds.
|
||||
periodic : boolean, optional
|
||||
Calculate minimum distance for periodically repeated grid.
|
||||
seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
|
||||
A seed to initialize the BitGenerator. Defaults to None.
|
||||
If None, then fresh, unpredictable entropy will be pulled from the OS.
|
||||
|
@ -61,7 +63,8 @@ def from_Poisson_disc(size,N_seeds,N_candidates,distance,seed=None):
|
|||
progress = util._ProgressBar(N_seeds+1,'',50)
|
||||
while i < N_seeds:
|
||||
candidates = rng.random((N_candidates,3))*_np.broadcast_to(size,(N_candidates,3))
|
||||
tree = _spatial.cKDTree(coords[:i])
|
||||
tree = _spatial.cKDTree(coords[:i],boxsize=size) if periodic else \
|
||||
_spatial.cKDTree(coords[:i])
|
||||
distances, dev_null = tree.query(candidates)
|
||||
best = distances.argmax()
|
||||
if distances[best] > distance: # require minimum separation
|
||||
|
|
|
@ -13,11 +13,13 @@ class TestSeeds:
|
|||
coords = seeds.from_random(size,N_seeds,grid)
|
||||
assert (0<=coords).all() and (coords<size).all()
|
||||
|
||||
def test_from_Poisson_disc(self):
|
||||
@pytest.mark.parametrize('periodic',[True,False])
|
||||
def test_from_Poisson_disc(self,periodic):
|
||||
N_seeds = np.random.randint(30,300)
|
||||
N_candidates = N_seeds//15
|
||||
distance = np.random.random()
|
||||
size = np.ones(3)*distance*N_seeds
|
||||
coords = seeds.from_Poisson_disc(size,N_seeds,N_candidates,distance)
|
||||
min_dists, _ = cKDTree(coords).query(coords, 2)
|
||||
coords = seeds.from_Poisson_disc(size,N_seeds,N_candidates,distance,periodic=periodic)
|
||||
min_dists, _ = cKDTree(coords,boxsize=size).query(coords, 2) if periodic else \
|
||||
cKDTree(coords).query(coords, 2)
|
||||
assert (0<= coords).all() and (coords<size).all() and np.min(min_dists[:,1])>=distance
|
||||
|
|
Loading…
Reference in New Issue