I am using the following python script to generate an amount of random cylinders that do not overlap with each other:
import bpy
from random import random
from mathutils import Vector
cylinderRadius = 1
maxIterations = 500 # Max iterations to prevent while loop from running
forever
# min and max values for each axis for the random numbers
ranges = {
'x' : { 'min' : 7, 'max' : 10 },
'y' : { 'min' : 7, 'max' : 10 },
'z' : { 'min' : 0, 'max' : 0}
}
# Generates a random number within the axis minmax range
randLocInRange = lambda axis: ranges[axis]['min'] + random() * (
ranges[axis]['max'] - ranges[axis]['min'] )
size = 50 # Number of cylinders
cylinders = [] # Cylinders coordinates list
loopIterations = 0
while len( cylinders ) < size and loopIterations < maxIterations:
loopIterations += 1
# Generate a random 3D coordinate
loc = Vector([ randLocInRange( axis ) for axis in ranges.keys() ])
if len( cylinders ) > 0:
# Search for overlapping points (within the cylinder radius radius)
overlappingPoints = [ p for p in cylinders if ( p - loc ).length < cylinderRadius * 2 ]
# if any found, skip this location
if overlappingPoints: continue
# Add coordinate to cylinder list
cylinders.append( loc )
# Add the first cylinder (others will be duplicated from it)
bpy.ops.mesh.primitive_cylinder_add( radius = cylinderRadius, location =
cylinders[0] )
cylinder = bpy.context.scene.objects['Cylinder']
# Add all other cylinders
for c in cylinders[1:]:
dupliCylinder = cylinder.copy()
dupliCylinder.location = c
bpy.context.scene.objects.link( dupliCylinder )
However, I do not get the 50 cylinders I am asking for when compiling. Does anyone have an idea on how to actually avoid setting a number of cylinders to be generated, but to fill in a pre-defined area (e.g. a square) with randomly placed cylinders, that do not overlap with each other, on it ?
Thanks!