Connecting Parts
Introduction:
In order to build larger 3D models you need to be able to connect interlocking parts together.Objective:
Design your own system of interlocking parts.Considerations
- How much material are you using?
- How long does printing take?
- How flexible is your design?
- Does you part fit snugly?
- Does your part need to slide?
Helpful Information
- For a part that needs to fit tightly within another part, design them so that they have 0.25mm clearance on all sides.(You may have to test this, as shrinkage occurs and your printing may be different).
- For a part that must easily slide within another part, design them so that they have 0.5mm clearance on all sides.
- 1 millimeter = 0.0393700787 inches
A brief/simple openSCAD tutorial:
- Open OpenSCAD
- Paste the following code into the editor:
module pin(){ union(){ linear_extrude(height = 4, center = true, convexity = 10) polygon( [ [0,0],[2,-2],[4,-2],[6,0],[6,2],[4,4],[2,4],[0,2] ] , [ [0,1,2,3,4, 5, 6, 7, 8] ]); translate([3,1,0]) cylinder(h = 15, r=1.5); translate([0,0,15]) linear_extrude(height = 4, center = true, convexity = 10) polygon( [ [0,0],[2,-2],[4,-2],[6,0],[6,2],[4,4],[2,4],[0,2] ] , [ [0,1,2,3,4, 5, 6, 7, 8] ]); } } scale(2){ difference(){ difference(){ cube([12,15,3]); color([1,0,0]) translate([2.75,1.25,-.5]) cube([6.5,4.50,4]); translate([2.75,9.25,-.5]) cube([6.5,4.50,4]); } translate([4.5,-1.25,-.5]) cube([3,6,4]); translate([4.5,10.25,-.5]) cube([3,6,4]); } color([1,0,0]) rotate( 90, [1, 0, 0]) translate([2.95,1,-3.50]) pin(); } - Test the file.
- Separate the pin and the cube into separate files or arrange them so that they both rest on same plane.
- Press F6 to build model
- Select Design>Export as STL
- Open .stl file in netFabb, repair and export part
- Open fixed file in ReplicatorG
- Print
module pinHolder(){
union(){
cylinder(h = 10, r=20);
difference(){
translate([0,0,10])
cylinder(h = 35, r=10);
translate([0,0,10])
cylinder(h = 36, r=8);
}
}
}
module pin(){
translate([0,0,10])
color([1,0,0])
cylinder(h = 55, r=9.5);
}
Inspiration from Outside
Here are real products that you might find as a source of inspiration:
Inspiration from within
From Thingiverse
Ball Vertex by WilliamAAdams
openSCAD file:
// A default set of sizes
goldenratio = 1.618;
IR = 4.2; // Inner radius of connector
OR = IR * goldenratio; // 7; // Outer radius of connector
Length = 22; // Length of connector
Radius = 10; // Radius of ball
Depth = Radius *0.6;
//equilateralvertex(Radius, Length, IR, OR, Depth);
//cubevertex(Radius, Length, IR, OR, Depth);
tetravertex(Radius, Length, IR, OR, Depth);
//teevertex(Radius, Length, IR, OR, Depth);
module barholder(Length, IR, OR, Offset)
{
difference()
{
cylinder(r=OR, h=Length, $fn =12);
translate([0,0,Offset]) cylinder(r=IR, h=Length+0.5, $fn =8);
}
}
module equilateralvertex(BallRadius, Length, IR, OR, Depth)
{
Offset = Length * 0.3;
union()
{
sphere(r=BallRadius);
rotate([-90,0,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset );
rotate([0,90,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset);
rotate([0,30,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset);
}
}
module tetravertex(BallRadius, Length, IR, OR, Depth)
{
Offset = Length * 0.3;
union()
{
sphere(r=BallRadius);
rotate([0,45,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset );
rotate([-45,0,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset );
rotate([-45,90,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset );
}
}
module cubevertex(BallRadius, Length, IR, OR, Depth)
{
Offset = Length * 0.3;
union()
{
sphere(r=BallRadius);
rotate([-90,0,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset);
rotate([0,90,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset);
rotate([0,0,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset);
}
}
module teevertex(BallRadius, Length, IR, OR, Depth)
{
Offset = Length * 0.3;
union()
{
difference()
{
sphere(r=BallRadius);
rotate([90,0,0]) cylinder(r = IR, h = (BallRadius*2)+Depth*2, center=true, $fn=8);
}
rotate([-90,0,0]) translate([0,0,Depth]) barholder(Length, IR, OR, -0.20);
rotate([0,90,0]) translate([0,0,Depth]) barholder(Length, IR, OR, Offset);
rotate([90,0,0]) translate([0,0,Depth]) barholder(Length, IR, OR, -0.20);
}
}
Space Frame Vertex v0.1 by WilliamAAdams

History
This is a derivative work of PolyBot Socket Ball Holder by WilliamAAdams.
Description
I am always in search of the perfect space frame vertex. Some of the qualities I am after are; ease of use, reduction in amount of plastic, strength, small size, easy of printing, flexibility in construction.
This thing, although not strictly a derivative, meets some of the criteria.
The benefits of this other vertex: thingiverse.com/thing:9560 is that you can fairly easily construct any vertex to suit any specified criteria. The limitation is that you must create a specific vertex for each situation. So, if you're trying to construct a 2v or 3v geodesic dome, you must create the correct vertex to match that topology, thus increasing your parts count.
This thing uses a flexible joint, like this other thing:
thingiverse.com/thing:8985
and this original thing:
thingiverse.com/thing:5126
The difference is that instead of using a ball and socket, it uses a slightly different kind of joint. There are a couple of challenges with the ball and socket. Although it provides great degrees of freedom, it actually provides too much freedom. With space frames, you typically only want the rods to move within a single plane. The other challenge has to do with the nature of a ball/socket joint. You have to snap the ball into the socket. This can be a bit hard with higher counts. And lastly, to get a really good connection, you need the hub to be quite thick, so that it provides more contact for the friction fit of the ball.
This thing uses a curved cylinder (torus) as the 'socket'. By doing so, it allows for a limited freedom (planar), while still providing a nice tight friction fit. So, when you're building a space frame, you can use a single 'hub' type, and the angles of the rods can be adjusted in realtime. That alleviates the need to construct vertices with fixed geometries. You just have to be concerned with the number of connections, but not their angle defects(saves on the math).
Also, the hub is fairly easy to construct. It's a single piece, with gentle curves. It can be printed without any support structure. I am imagining it would be fairly easy to create a mold for this thing as well, if you wanted to mass produce through injection molding.
The swing arm is a different story. The model of the piece is fairly simple, but the actual printing requires some support structure. I would like to simplify that part.
The models that I have here 'work' together, but the arm is weak, and will easily break depending on the plastic you are using to print. I would like to improve that arm, but I think I've proved the concept to myself enough that I will continue the design.
1) Print as many 'hubs' as you like. There are .stl files for 3, 5, and 6 connection hubs. The OpenScad will allow you to construct a hub with any number of connections.
2) Print as many arms as you need to match your hubs.
3) Press fit rods into the sleeves of your connecting arms
4) Slip the end of the rounded arm into a hole on the hub
5) Rejoice!
The default rod that can be accomodated is 5/16", but you can alter the OpenScad to be anything you want.
Although the OpenScad will allow you to use as many holes on the hub as you want, you will want to be mindful of the hub's overall cylinder size. I'm using a fixed size, which nicely accomodates 6 holes, down to 1. I wanted to have a single size so various vertices could work together without changing distance from center. If you're going to use more than 6 holes, you'll probably want to choose a larger hub cylinder radius.
WARNING: Right now, the arm is very fragile (at the neck). I've only printed two of them, and they both snapped (very soft plastic). This part of the design needs to improve.
joinfactor = 0.125;
goldenratio = 1.618;
gAttachRadius = 1/8*25.4;
gArcRadius = 5/16*25.4;
//curvedarm(arcradius = gArcRadius, attachradius = gAttachRadius, $fn=24);
receiver(arcradius = gArcRadius,
attachradius = gAttachRadius,
sections = 5);
//torcircle(gArcRadius, gAttachRadius, $fn=12);
//swingarm(arcradius = gArcRadius, attachradius = gAttachRadius, $fn=24);
//========================================
// Modules
//========================================
module torus(majorradius, minorradius)
{
rotate_extrude(convexity=4)
translate([majorradius, 0,0])
circle(r=minorradius);
}
module torcircle(arcradius, attachradius)
{
union()
{
torus(majorradius = arcradius, minorradius = attachradius);
//linear_extrude(height = attachradius*goldenratio, center=true)
linear_extrude(height = attachradius, center=true)
circle(r=arcradius);
}
}
module curvedarm(arcradius, attachradius)
{
union()
{
difference()
{
torcircle(arcradius, attachradius);
// Take some chunks out of it
translate([-(arcradius+attachradius+joinfactor)/2, 0,0])
rotate([0,0,0])
cube(size = [arcradius+attachradius+joinfactor,
arcradius*4+attachradius*2+joinfactor*2,
attachradius*2+joinfactor*2], center=true);
translate([-(arcradius+attachradius+joinfactor)/2, 0,0])
rotate([0,0,0])
cube(size = [arcradius+attachradius+joinfactor,
arcradius*4+attachradius*2+joinfactor*2,
attachradius*2+joinfactor*2], center=true);
}
cube(size=[arcradius*goldenratio,
arcradius/goldenratio,
attachradius],
center=true);
// Add spheres to the tips for easier insertion in the receiver
translate([0, arcradius, 0])
sphere(r=attachradius);
translate([0, -arcradius, 0])
sphere(r=attachradius);
}
}
//==============================================================
// Modules
//==============================================================
module rodsleeve(primarybore, borelength, borecaplength)
{
primaryIR = primarybore/2;
primaryOR = primaryIR*goldenratio;
length = borelength+borecaplength;
topofball = length;
difference()
{
union()
{
cylinder(r=primaryOR, h=borelength);
// Taper cap
translate([0,0,borelength-joinfactor])
cylinder(r1=primaryOR, r2=primaryOR/goldenratio, h=borecaplength+joinfactor);
}
// Subtract cylinder for the rod
translate([0,0,-joinfactor])
cylinder(r=primaryIR, h=borelength+joinfactor);
// Subtract out a slanted cylinder to make a snug fit for the rod
// As well as provide a 'no support' build
translate([0, 0, borelength-joinfactor])
cylinder(r1=primaryIR, r2=primaryIR/goldenratio, h=borecaplength-1);
}
}
module swingarm(arcradius, attachradius,
primarybore=5/16*25.4*1.05,
borelength=1/2*25.4,
borecaplength=2)
{
rodsleeve(primarybore, borelength = borelength, borecaplength=borecaplength);
translate([0,0,borelength+borecaplength+arcradius/goldenratio])
rotate([0,-90,0])
curvedarm(arcradius, attachradius);
}
module receiver(arcradius, attachradius, sections=3)
{
cHeight = 8;
cRadius = (arcradius*goldenratio)+attachradius;
secangle = 360 / sections;
difference()
{
cylinder(r=cRadius, h=cHeight, center=true);
for(section = [0:sections])
{
rotate([0,0,section*secangle])
translate([-cRadius, 0, 0])
rotate([90, 0,0])
torcircle(arcradius, attachradius*1.05, $fn=24);
}
cylinder(r=5/16/2*25.4, h=cHeight+2*joinfactor, center=true);
}
}More links to Thingiverse


Food for thought
Automated Generation of Interactive 3D Exploded View Diagrams $("p:not(p:eq(2))").css("border","2px solid pink").css("padding", ".5em");