I'm attempting to print out a 300mm hollow sphere on my Printrbot by shaping the sphere's internal cavity as a regular, circumscribed polyhedron and splitting up the sphere based on the sides of the circumscribed polyhedron. I first attempted this with a cube, resulting in 6 sides with 3d-printable flat bottoms, however due to the limited build volume of the printer (150x150x150 mm), the ~175mm edges of the resulting side wouldn't fit.
The next reasonable stepped seemed to be changing the circumscribed polyhedron to a dodecahedron and printing out 12 sides rather than 6, however, I'm having some trouble figuring out how to properly project the pentagonal side onto the sphere and slice it up accordingly. Is there some way to get the intersection of the sphere and projected dodecahedron side? My current code is below.
$fn = 72;
diameter=300;
side();
module side()
{
difference()
{
hollow_sphere(diameter);
rotate([180,0,0])
fiveSideMask();
}
}
// A cubic mask to remove all sides but one from the circle
module fiveSideMask()
{
union()
{
rotate([45,0,0])
translate([0,-diameter/4, 0])
cube([diameter, diameter/2, diameter], center=true);
rotate([-45,0,0])
translate([0,-diameter/4, 0])
cube([diameter, diameter/2, diameter], center=true);
rotate([0,0,45])
translate([0,-diameter/4, 0])
cube([diameter, diameter/2, diameter], center=true);
rotate([0,0,-45])
translate([0,-diameter/4, 0])
cube([diameter, diameter/2, diameter], center=true);
}
}
module hollow_sphere(diameter=300, shell_thickness=5)
{
difference()
{
sphere(d=diameter, center=true);
//Sphere internal cavity
//sphere(d=(diameter-(shell_thickness*2)), center=true);
//Cube internal cavity
cube(CubeEdgeFromDiag(diameter - shell_thickness * 2), center=true);
//Dodecahedron internal cavity
//rotate([90,0,0])
//dodecahedron(225);
}
}
function CubeEdgeFromDiag(diagLength) = (sqrt(3) * diagLength) / 3;
module dodecahedron(size)
{
dihedral = 116.565;
intersection()
{
box(size);
intersection_for(i=[1:5])
{
rotate([dihedral, 0, 360 / 5 * i]) box(size);
}
}
}
module box(size)
{
cube([2*size, 2*size, size], center = true);
}
You can actually use a technique similar to your existing
fiveSideMask
module, but instead of cutting around a square pyramid, you'll be cutting around a pentagonal pyramid:
// A mask to remove everything from the sphere but the projection of the face.
module sideMask() {
union() {
radius = diameter / 2;
dihedral_angle = acos(-1/sqrt(5));
// Five slabs adjacent to the pentagonal-pyramind that projects out
// around the face.
for (theta = [0:360/5:359]) {
rotate([90 - dihedral_angle,0,theta])
translate([-diameter/2,0, 0])
cube([diameter, radius, diameter]);
}
// We also want to mask out the opposite side of the sphere.
translate([-radius, -radius, -radius])
cube([diameter, diameter, radius]);
}
}
You can also simplify hollow_sphere
(and make its name more accurate) by using hull
in side
. This is more computationally expensive, but simplifies the code considerably. The shell_thickness
passed to hollow_sphere
will end up being the minimum thickness, at the vertices of the dodecahedron:
module side() {
// hull() is pretty expensive, but it nicely flattens out the bottom of the
// shape, making for something easily printable.
hull() difference() {
hollow_sphere(diameter);
rotate([180,0,0])
sideMask();
}
}
module hollow_sphere(diameter=300, shell_thickness=15) {
difference() {
sphere(d=diameter);
sphere(d=diameter - shell_thickness);
}
}
The only other stuff you need to keep are the few lines at the top of the file...
$fn = 72;
diameter=300;
side();
...and you'll get something like this: