# How can we animate a ball rolling over a path?

So I have an complex smooth surface. I created a high resolution path curve and used a Shrink Wrap modifier to make it fit on my surface where I want it. I apply the shrink wrap.

I can easily make an object move along this path now with a Follow Path constraint. Great.

But...I would like to animate a ball rolling along this path. I can't find a constraint or other tool in Blender that allows for this. If I knew how Python interacts with Blender better (I'm just learning) I would write something using quaternions (I've done this in an iOS physics engine I did a few years back).

Or is there some trick with rigid body simulation to make my ball roll along the constrained path?

What's an animator to do?

• It might be possible to do something with a curve guide force field and the rigid body simulator. I'll give this a try later. – gandalf3 Dec 25 '14 at 21:07
• Seems curve guides don't affect rigid bodies? Odd, as there is an influence slider.. Perhaps a bug. – gandalf3 Dec 26 '14 at 6:21

You can make the ball roll with a Driver, first - this is what you should already have setuped, make sure the ball's Follow Path constraint option Follow Curve is set:

Add single driver to the X axis rotation field (RMB on field > Add Single Driver R)

Setup the driver like this (scripted type, no variables), also make sure Auto Run Python Scripts in User_Preferences > File is enabled:

Lets add a driver variable for the curve evaluation time, call the variable "eval_time", in the Prop field put the curve and Path is eval_time:

Now its time for the driver expression. You will need to know the ball's diameter and the curve's length.

• diameter you get from ball's dimensions in properties panel N:

• curve's length you get from running this script with curve selected:

 import bpy
import bmesh
orig = bpy.context.active_object.name
bpy.ops.object.duplicate_move()
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
bpy.ops.object.convert(target='MESH', keep_original=False)
bm = bmesh.new()
bm.from_mesh(bpy.context.active_object.data)
edge_length = 0
for edge in bm.edges:
edge_length += edge.calc_length()
bpy.context.window_manager.clipboard = str(round(edge_length,3))
bpy.ops.object.delete()
bpy.context.scene.objects.active = bpy.context.scene.objects[orig]
bpy.context.object.select = True


It will calculate the length and store it in the clipboard, you can then paste it with Ctrl+V.

The driver expression is: -2 * curve_length / diameter * ( eval_time / eval_max ):

Let's break the expression down:

• (eval_time/eval_max) is the only element that changes and it goes from 0 to 1 as the ball moves along the curve

• the rest equates to a number, that says how much has the ball turn to rotate along the whole path

If the ball turns 1 complete rotation (360°), it will travel pi*diameter units.

So to cover the path it needs curve_length / pi*diameter of full rotations.

The catch is that driver expects the input in radians, not degrees. So a full rotation of 360° is 2*pi radians.

(2pi) * curve_length / pidiameter, we can simplify and remove pi

The last thing is the minus in front of the expression (-), this is to influence which direction we want the ball to roll. You can use the right hand rule to see what rotation is positive, and what negative (thumb in axis direction, fingers point in positive rotation direction).

Now the ball will roll accordingly to your curve's Evaluation Time:

• This is awesome! Thanks. Now I have to read up on this stuff so I can do things like this myself. The more I learn, the less I know. :-) – Chuck Dec 26 '14 at 4:26
• This video is a good start to drivers. – sambler Dec 26 '14 at 8:50
• Pinging Jaroslav towards the question below... – aliasguru Jun 16 '20 at 7:59
• Hi @ThomasKordi, I included info how I got that expression – Jaroslav Jerryno Novotny Jun 17 '20 at 2:38