I need to write a script that randomly distributes spheres (around 300) in a specific space and after the placement of the spheres I need to randomly distribute cylinders(5 times the number of spheres) with random orientation. All the spheres and cylinders should not overlap. After the spheres and cylinders I need to fill a percentage of the remaining space with ellipsoids. I managed to distribute the spheres without overlapping by generating random locations, but I still have problems with the cylinders mostly because of the random orientation. My question is if there is any way for Blender to return the volume coordinates of an object when it is created, so that I can check for overlaps or if you possibly know any other methods to avoid overlapping.


1 Answer 1


I have this script,

# Function to calculate the distance between two points
def distance(a, b) :
    list , list --> float
    a = list with three element
    b = list with three element

    return the distance between two points in float
    return sqrt((a[0]-b[0])**2+(a[1]-b[1])**2+(a[2]-b[2])**2)

# How many Sphere you want to add
count = 50

# Cylinder properties
radius = 0.03
depth = 0.2

# The sphere will be created between -domain <--> domain
domain = 0.5

# Max time to try finding a new location before break the loop
maxTry = 50

# Variable to count how many try has been done
Try = 0

# list with three element to generate locations
location = [0, 0, 0]

# Variable to hold the distant between balls
dist = 0

# True == Won't collide , False == Will collide
State = True

# This tuple will hold centers of created spheres
locList = ()

while count > 0 :

    # Calculate x, y, z position
    location[0] = randint(-domain*10, domain*10)/10.0
    location[1] = randint(-domain*10, domain*10)/10.0
    location[2] = randint(-domain*10, domain*10)/10.0

    # Start check if it will collide with other spheres
    for x in locList :
        # Calculate the distant
        dist = distance(x, location)

        # If it's too close make State = False
        if dist < radius*2 + 0.1 :
            State = False
        # If it's in a good position State = True
        else :
            State = True

    # The distant is too close , recalculate the location
    if State == False :
        Try += 1

    # After Try reach maxTry break the loop
    if Try > maxTry :

    # Successfully found a New location
    # Add this point
    locList += (location[:],)

    # Smooth the faces

    #Create a new sphere at the same location, and resize it to an cylinder
    bpy.ops.mesh.primitive_cylinder_add(radius = 0.1, location = location)

    #Give the cylinder a random orientation
    bpy.ops.transform.rotate(value=(2*pi*random()-1), axis=((2*pi*random()-1), (2*pi*random()-1), (2*pi*random()-1)))

    #Smooth the faces

    # reset Try
    Try = 0

    # Decrease the counter
    count -= 1     

The problem of this script is in the condition of overlap between two cylinder, someone can solve this problem of overlap?

  • $\begingroup$ The issue with the test if dist < radius*2 + 0.1 is that the radius for a cylinder or cube is the distance from the center of the object to the center of the face not the edge or in the case of a cube the corner (furthest point from center). The test for a cube would be 2 * r * sqrt (3) or approximately 3.5x radius to avoid corners overlapping. This however essentially just tests against a larger sphere rejecting some possible solutions cubeA adjacent to cubeB along axis. $\endgroup$
    – Ratt
    Commented Dec 25, 2018 at 20:10
  • $\begingroup$ The condition: if dist <radius * 2 + 0.1, it is for the case of two spheres, but for the case of cylinders, there is a condition of non-overlapping between the bases between two cylinders and the condition between the distance between the two two centers of the two cylinders. about what you have written: cubeA adjacent to cubeB, I do not understand this, the problem is that we have a cube that contains objects (i.e: cylinders as an example). $\endgroup$
    – saded
    Commented Dec 30, 2018 at 17:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .