I have been doing a fair amount of 3D printing with my Prusa i3 MK3s printer.  I have graduated from downloading and printing stl files from thingiverse to creating my own.  There are multiple different 3D design programs out there and I have tried several.  For complicated things, I use Fusion 360, which has a Free for Hobbyist page.  Hurray!  

For most things, however, I use TinkerCad.  It’s a great web-based tool that will cover most of your needs.  The one glaring flaw that I have found with TinkerCad is that there is no ‘Intersection’ tool.  If you have two objects, like the short box and cylinder below:

tinkercad box and cylinder

and you want to produce their intersection:

tinkercad intersection of box and cylinder

then you are out of luck with the built-in tools.

However, not all is lost!  What TinkerCad does provide are 2 things that we will use to produce and intersection:  Group and Holes.   A Group joins together two objects into a single object.    A Hole turns an object into a negative version of itself.  Here is how we use these to do an Intersection.

Step 1:  Select one of the objects and turn it into a Hole.  

Note, if you were to Group this with box, then you would end up with the following (You Group them by shift-clicking on the box, so the hole-cylinder and box would both be selected and then clicking on the Group button ):  

This is not what we want, so don’t do this yet!

Step 2:  Duplicate the other piece.  You do that by selecting it (left-clicking) and doing Cntl-D:

Step 3:  Group the Hole and the Duplicate.  Shift-click on the Hole and click on the Group button.  Here the Duplicate and Hole are selected: 

And this is what it looks like after the Grouping.  Note that there is a line showing where the duplicate is now missing a piece:  

Step 4:  Turn the Grouped-Duplicate-Hole into a Hole.  Without unselecting the Grouped object you just created, click on Hole, turning it into a hole:

 It’s a good idea to do this immediately, because the original box and the Grouped-Duplicate-Hole objects are on top of each other and it can be difficult to select the right one. 

Step 5:  Group the Grouped-Duplicate-Hole-Hole object with the original box.  So, shift-click the original box (the red part above) and Group:

and after you have Group-ed them:

And this is the Intersection, which is what we wanted.

Why does this work?   Because of set theory.  What we want is the Intersection, but that is not a function that is available to us.  We do have Union, since that is what Group does.  We don’t have Set Difference exactly, but we have a ‘Hole’ function.  So, what we are doing above is: 

A \cap B = A - ( A - B )

You may think to yourself that A – (A – B) = A, but this is not arithmetic.  This is set theory and set differences are not associative.  How do we get A – B?   We turn B into a hole and group it, so:

A - B = A \cup B^H

We want to do the difference again, so we have to turn the above into a hole and group again.  So, the final equation is:

A \cap B = A \cup ( A^D \cup B^H ) ^H

where A^D is a duplicate of A.  In terms of TinkerCad, do it starting in the middle and work your way out.  The steps are:

  1. Turn B into a Hole, call it Bh
  2. Duplicate A, call it Ad
  3. Group Ad and Bh, call this Ad-Bh
  4. Turn Ad-Bh into a hole, call it (Ad-Bh)h
  5. Group A and (Ad-Bh)h

And then you have your intersection.  

 

When working on algorithms dealing with real world objects, a common task is to view the object from a variety of points of view.  If we represent a point of view looking at the object as points on a sphere, we have the problem of distributing the points on the sphere evenly.  This prevents gaps (because points are too far apart in some places) and wasted computation (because points are too close in some places).

The naive approach would be to use something like latitude-latitude lines.  This is very simple:  rotate the point of view in longitude some number of degrees around the equator; increase latitude some number of degrees; repeat latitude.  There are a number of problems with this.  First, it assumes that the latitude and longitude degree increments add up to 360 degrees in longitude and +/- 90 degrees in latitude.  That means that the number of points on the sphere that can be used is very granular.  Second, and more importantly, the points are very unevenly distributed on the sphere. 

Points distributed like latitude – longitude points.

The points near the poles are very close to each other, and result in a great deal of uneven distribution and wasted computation.  

An alternative approach is to put the points on the sphere randomly and then adjust them to be more even.  A simple way to do this is treat them as connected to each other via springs and simulate their movement.  This is an interesting software engineering problem in itself, since you have to pick how many points each point connects to, what the mass of the points are, what the spring parameters are, friction or other non-linear forces, how to efficiently simulate, and then know when to stop.  In the most simple case, without friction, you can have waves of compression and expansion travel indefinitely over the sphere.  With too much friction or spring parameters too low, the simulation will take a very long time to settle down.  The biggest problem is that this whole approach is inefficient.

A clean, efficient solution, for any number of points, is to use a 3D version of a Golden Spiral.  In school, you may have learned about the distribution of seeds in a sunflower, how shells spiral out, and other natural growth phenomena form a series of Golden Spirals.  Here is a close up of the seeds in a sunflower:

Seeds in a sunflower. From Wikipedia

The mathematical model for this uses Vogel’s method, discussed on this Golden Angle Stack Exchange page.  Basically, it is a logarithmic spiral with a very special value for the growth parameter.  Here are the equations, as a function of ‘n’, the point number in polar coordinates: and , where phi is the Golden Ratio.  And here is what they look like:

Labeled points using Vogel’s method. From WikiCommons 

To get a better feel for how all this works, and the wonderful relationship to the Fibonacci series, watch these wonderful videos by Vihart:    Doodling in Math: Spirals, Fibonacci, and Being a Plant (Actually, it’s worthwhile seeing all the videos by Vihart.)  Conceptually, what is happening is that the angle between successive points is based on the Golden Angle, and the radius grows over time.  

If you watch the video, you will see that Vihart shows the spirals on a pine cone.  That’s actually pretty close to what we want for distributing points on a sphere.  The successive points on the sphere will still be based on the Golden Angle, so {\displaystyle \theta =n\times {\frac {2\pi }{\phi +1}}}, as above with Vogel’s method.  In cartesian coordinates, x and y will be:   x = radius * cos(theta) and y = radius * sin(theta).   The z will be evenly distributed between the top of the sphere and the bottom of the sphere.  In order for this to sit on the unit sphere, this means that the radius value will be sqrt(1-z*z).  The resulting plot of points looks like this:

Points even distributed on the sphere using 3D Vogel’s method.

In the diagram, I’ve hidden the points on the back of the sphere.  If you go through the bother of looking at how far points are from their nearest neighbors, which can be used as a measure of how well distributed points are, you will see that they are nicely distributed.   

The (surprisingly simple) code in python looks like this:  

import math
import numpy as np

golden_angle = math.pi * ( 3 - math.sqrt(5))
n = 1000

pts = numpy.zeros((n, 3))
for ii in range(0,n):
    z = (1 - (1/n)) - (2 * ii / n)
    r = math.sqrt(1 - z*z)

    d = gold_angle * ii
    x = r * math.cos(d)
    y = r * math.sin(d)
    pts[ii,0] = x
    pts[ii,1] = y
    pts[ii,2] = z

A reasonable question would be where the calculation for the golden_angle came from, since above it was defined as  2*pi / (phi+1).  If you plug in the formula for the golden ratio and simplify, you get pi * (3-sqrt(5)).  See Golden Angle .  By the way, I know the code is not very pythonic;  in practice, I’ve use linspace.