How to rotate an object to continually touch the uneven surface of another rotating object?

  • Object A (black) rotates using a variable speed driver to another object's rotation. Object A has an uneven circumference against which Object B needs to lean.

  • Object B (gold) needs to pivot back and forth as it's little roller
    rolls along object A's uneven circumference as A continually rotates.

  • It needs to be a simulation, not keyframed animation so object B will always follow A regardless of A's rotational speed forward or backward.

Once this contraption is built, It will be mounted on a robot arm moving everywhere in world space and orientation.

I've tried adding a complicated driver to Object B based on the radian rotation sections of Object B.enter image description here

I've tried hard body simulation, but it just gets hung up and i cannot figure out how to get Object B to continually lean against the circumference of Object A. I've even tried adding an invisible spring and I couldn't get it to work.


  • 1
    $\begingroup$ Have you tried a Rigid Body motor and hinge combination? youtu.be/gVrvzBjZwgk $\endgroup$
    – Blunder
    Commented Sep 27, 2023 at 16:24
  • $\begingroup$ Would you describe this a s a cam? (That might be more searchable) $\endgroup$
    – Robin Betts
    Commented Sep 27, 2023 at 16:53
  • $\begingroup$ This is really something better done with a rigid body sim than with constraints and drivers; you can still animate the wheel as desired. Here's my basic test setup: pasteboard.co/rVwk2skYInr5.png which shows you object origins and RB constraint settings. Note that you need to use mesh collision for any concave objects. $\endgroup$
    – Nathan
    Commented Sep 27, 2023 at 17:03

2 Answers 2


Here's a simple Geometry Nodes setup:


Collision Detection by Rotating with Python

I just wanted to post a scripting option for those who are more comfortable with Python than the physics engine. This may not be the solution with the best performance.

enter image description here

The Script

"""This script adds a frame-change handler to rotate ObjectA
until it contacts ObjectB.

import bpy
import math
from mathutils import Vector
import bmesh
from mathutils.bvhtree import BVHTree

def create_bvh(obj):
    """Create a bvh tree for the given object."""
    bm = bmesh.new()
    depsgraph = bpy.context.evaluated_depsgraph_get()
    evaluated_obj = obj.evaluated_get(depsgraph)
    mesh = evaluated_obj.to_mesh()
    bvh = BVHTree.FromBMesh(bm)
    return bvh

def collision(obj1, obj2):
    """Return True if there is a collision between obj1 and obj2."""
    # Create BVH trees for each object
    bvh1 = create_bvh(obj1)
    bvh2 = create_bvh(obj2)

    # Check for overlaps between the two BVH trees
    overlapping_pairs = bvh1.overlap(bvh2)
    if overlapping_pairs:
        return True
        return False

def rotate_to_contact(scene):
    """Rotate ObjectA until it contacts ObjectB"""
    object_a = bpy.data.objects["ObjectA"]
    object_b = bpy.data.objects["ObjectB"]

    # Reset the rotation just beyond the widest part of the
    # rotating object in order to minimize the number of steps required.
    object_a.rotation_euler.z = -1.14
    # Set the tiny step by which to rotate
    # Decrease this for higher accuracy but slower playback
    angle_increment = math.radians(-.5)

    for _ in range(2000):
        # Make a tiny rotation and check for a collision.
        object_a.rotation_euler.rotate_axis("Z", angle_increment)
        if collision(object_a, object_b):
    # Update the scene for good measure

if __name__ == "__main__":

You must log in to answer this question.

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