as everybody know, when you put two spheres close to each other they intersect other like this :

How do I flatten the spheres at the region where they intersect each, I tried to illustrate this with a quickdraw :enter image description here

I don't know if it's possible with physics like soft body or collision. does anyone know how to get this result, i need this for a still image not for animation.

I'm more looking for something like this:

enter image description here

  • $\begingroup$ This works but i want the effect even when i'm note playing the animation, i need this for a fix image not for animation, is there a way to get the physics result in one frame ? $\endgroup$
    – amby
    Commented Oct 14, 2017 at 19:58
  • $\begingroup$ This is for a personal project and i have absolutely no dead line, so do it only if you got the time, thank you very much $\endgroup$
    – amby
    Commented Oct 14, 2017 at 23:07

2 Answers 2


Bmesh script

Script to flatten spheres on their intersection plane. See intersection of two spheres on Paul Bourke's magnificent geometry site The code runs through each selected sphere, checks if they intersect, if they do clalculates the location of the circle of hit.

If there's a collision, for both spheres, selects all vertices that are within the conic angle of the collision and moves them to the point of intersection with the collision disc. NOTE: script relies on the origin of the spheres being the (default) centre of geometry.

Sphere example Test run on UV Spheres.

The script

Select all the spheres you want to modify and run script. Alter the scale to change the angle of effect of flattening vertices.

import bpy
import bmesh
from math import acos, degrees, radians
from mathutils import Vector
from mathutils.geometry import intersect_line_plane
context = bpy.context
scene = context.scene
spheres = [(o, max(axis for axis in o.dimensions) / 2) for o in context.selected_objects]
bmeshes = {}

scale = 1.0 # alter to widen bump angle.
def new_bmesh(me):
    bm = bmesh.new()
    return bm

def squish(sphere, angle, global_plane_co, global_plane_no):
    mw = sphere.matrix_world
    mwi = mw.inverted()

    bm = bmeshes.setdefault(sphere.name, new_bmesh(sphere.data))
    local_p = mwi * global_plane_co
    local_norm = mwi * (global_plane_co + global_plane_no) - local_p
    # select all verts via angle
    proj = angle > radians(90)
    if proj:
        angle = radians(180) - angle
        verts = [v for v in bm.verts if v.co.angle(local_p) > angle]
        verts = [v for v in bm.verts if v.co.angle(local_p) < angle]
    for v in verts:
        v.select = True
        d = local_norm if proj else v.co
        o = v.co if proj else Vector()
        hit = intersect_line_plane(o, d, local_p, local_norm)
        if hit and hit.length < v.co.length:
            v.co = hit

while spheres:
    sphere, R = spheres.pop()
    P = sphere.matrix_world.translation    
    for s, r in spheres:        
        p = s.matrix_world.translation
        v = (p - P)
        d = v.length
        if d >= r + R:
        elif abs(r - R) > d:
        elif d < 0.0001:

        x = (d * d - r * r + R * R) / (2 * d)
        # define plane
        pt = P + x * v
        norm = v  
        angle1 = acos(x / R)
        angle2 = acos((d - x) / r)
        #print(R, r, x, degrees(angle1), degrees(angle2))
        squish(sphere, scale * angle1, pt, norm)
        squish(s, scale * angle2, pt, norm)

for name, bm in bmeshes.items():
    me = scene.objects[name].data


Sample run icospheres Sample run on icosphere cluster on left, result on right

EDIT: fix for inside cases, now projects back onto plane if hit is inside (angle is greater than 90 degrees.

enter image description here

  • $\begingroup$ that's exactly what i was looking for, i try it as soon as possible, thank you for your answer batFINGER $\endgroup$
    – amby
    Commented Oct 15, 2017 at 18:17
  • $\begingroup$ @amby given this comment, I've edited your question. Re-edit it if it's not your intention. $\endgroup$
    – batFINGER
    Commented Oct 15, 2017 at 18:41
  • $\begingroup$ it was my intention, i just have some trouble to explain my idea in english (i'm french), so i make lots of mistakes in english.. $\endgroup$
    – amby
    Commented Oct 15, 2017 at 21:15
  • 1
    $\begingroup$ @amby edited script to handle inside cases better. $\endgroup$
    – batFINGER
    Commented Oct 17, 2017 at 16:44

If i understood the question maybe your looking for this

I have added 2 sphere and to 1 i have added the cast modifier

With the reference of pencil drawing sphere to deform when they touch each other.

In the cast modifier you can play with the settings and get the effect.

enter image description here


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