I have been working to create 3d-printed structures that would include marbles rolling down specific tracks (maybe a Rube Goldberg machine). To do this, a generic mechanism for creating tracks for arbitrarily complex paths is needed. OpenScad is a great tool for parametric 3D modeling, and seemed like a natural choice for solving the problem. A sample track looks like:

## The Basic Shape

As always, we start with some spheres .These are copies of the same object, representing the location of the marble at different points in time. This can be done with the OpenScad ‘sphere’ command (note the approach is generic and should work with any object type – not just spheres):

## Connecting the Spheres

We can use the convex hull function in OpenScad to create a convex hull around the spheres. The choice of the number of spheres included in each convex hull is important – the more sphere we include, the more area under the track will be included in the convex hull. In order to keep the structure free-standing we will need to use a union of multiple convex hulls, with each hull encompassing three spheres:

## Generating a Full Path of Spheres

We can run this for a full set of spheres, and define the x,y,z coordinates for each sphere arbitrarily. This is where I plan to use a defined set of twists, turns and drop to generate the complex tracks for the marbles to follow. In the interim, for proving out this method, I am using a parametric path for a simple concave parabola on the x-z access with a right intercept at x=rightx and peak at z=topz. Note ‘n’ in this example represents the total number of spheres we are using (the path resolution):

```
function xi(i) = rightx*i/n;
function yi(i) = 0;
function zi(i) = topz*(-i*i+n*i)/(n*n/4);
```

The convex hull around 3-sphere segments of the parabola defined above looks like:

Generated via:

```
module convexTrail(){
// start from 0 for a closed shape; 1 for an open shape
for(i=[0:parts-1:n-2]){
hull()
{
for(j=[i:1:i+2]) // connect each three items
basic_shape(xi(j),yi(j),zi(j));
}
}
}
```

## Creating a Groove for the Track

Finally, for a track to be useful it needs to have a groove for the object to pass through. We recreate the same shape, offset on the z access by the sphere radius, and subtract it from the original shape:

Generated via:

```
difference(){
convexTrail();
translate([0,0,r])
convexTrail();
}
```

The full code is available on GitHub:

## Follow-Ups

There are a few different directions I can see taking this. If anyone reading this has thoughts or ideas, please share in the comments below.

- Create a generic module to load path locations from a data file
- Improvements to render time:
- Look at generating the convex hull for all spheres at once and then substracting the bottom portion (should make rendering more efficient)
- Use the OpenScad 2d sub-system for some of the initial work

- Research equivalent Blender Python script
- 3D-printing a track and run some marbles through it!