# Generate x cubes at random locations but not inside each other?

Im generating cubes with this code:

for a in range(10): x = random.randint(-5, 4) y = random.randint(-2, 7) z = random.randint(3, 10) bpy.ops.mesh.primitive_cube_add(location=(x,y,z), radius = 1)

What do I add to make sure no one of these 10 cubes are created with some part of it inside of one of the earlier created cubes?

• I would look into Poisson sampling – Sebastián Mestre Dec 1 '17 at 15:03
• @SebastiánMestre would be interested in seeing an answer using Poisson Sampling – batFINGER Dec 3 '17 at 14:36
• my mistake, i meant poisson disk sampling. and i am sorry, i won't be leaving a reply – Sebastián Mestre Dec 5 '17 at 19:13

A similar answer that utilizes Blender's Mathutils' Vector length property (prevents you from needing to calculate distances in all 3 axes individually):

import bpy
from random import random
from mathutils import Vector

maxIterations = 1000 # Max iterations to prevent while loop from running forever

# min and max values for each axis for the random numbers
ranges = {
'x' : { 'min' : -10, 'max' : 10 },
'y' : { 'min' : -10, 'max' : 10 },
'z' : { 'min' : -10, 'max' : 10 }
}

# Generates a random number within the axis minmax range
randLocInRange = lambda axis: ranges[axis]['min'] + random() * ( ranges[axis]['max'] - ranges[axis]['min'] )

size  = 250 # Number of cubes
cubes = []  # Cube coordinates list

loopIterations = 0
while len( cubes ) < size and loopIterations < maxIterations:
loopIterations += 1

# Generate a random 3D coordinate
loc = Vector([ randLocInRange( axis ) for axis in ranges.keys() ])

if len( cubes ) > 0:
overlappingPoints = [ p for p in cubes if ( p - loc ).length < cubeRadius * 2 ]

# if any found, skip this location
if overlappingPoints: continue

# Add coordinate to cube list
cubes.append( loc )

# Add the first cube (others will be duplicated from it)
cube = bpy.context.scene.objects['Cube']

for c in cubes[1:]:
dupliCube = cube.copy()
dupliCube.location = c

• Much more efficient. The only thought i would have for a change is instead of a max iteration check for consecutive fails vs a max fails in the event someone wanted to push the limit of size > iterations. (easily incremented & reset at the "overlappingPoints" check. And i guess regarding the specific question adjust for using randint(). but thank you for the improved version. – Ratt Dec 3 '17 at 13:33
• Good candidate for using any if any((p - loc).length < D for p in cubes): continue – batFINGER Dec 4 '17 at 13:26

For small sample sets testing collision can be done like this:

import random
import bpy

obj_ctr = []
# one object must be created outside the loop for data structure to be available for testing
x = random.randint(-5, 4)
y = random.randint(-2, 7)
z = random.randint(3, 10)
obj_ctr.append((x,y,z))

#while len(obj_ctr) < 10:
for a in range(10):
test_x = False
test_y = False
test_z = False
x = random.randint(-5, 4)
y = random.randint(-2, 7)
z = random.randint(3, 10)
for test in obj_ctr: #verify the new randoms will not allow collision
if abs(test[0] - x) < obj_radius * 2:
test_x = False
else:
test_x = True
if abs(test[1] - y) < obj_radius * 2:
test_y = False
else:
test_y = True
if abs(test[2] - y) < obj_radius * 2:
test_z = False
else:
test_z = True
if (test_x and test_y and test_z):
obj_ctr.append((x,y,z))

for obj in obj_ctr: