At our house we have enough extra hex tiles to play a five-person Catan game, but not a fifth set of pieces. Today we printed a new full set of Settlers of Catan pieces, including the knight and city wall pieces needed for the Cities and Knights Expansion Pack and a set of rings to attach to LEGOs to hold a new stack of homemade Cities and Knights flip-cards. The standard pieces in this print job came from Arcym's Settlers of Catan Pieces model on Thingiverse, and the Cities and Knights pieces were easy to add in Tinkercad. We also threw in a new print of our Catan numbers from Day 42.
STL file: http://www.geekhaus.com/makerhome/day159_catan_expander.stl
Tinkercad link: https://tinkercad.com/things/b1RgkZvMY4s-day-159-catan-expander
Thingiverse link: http://www.thingiverse.com/thing:239439
Settings: MakerWare .3mm/low on a Replicator 2.
Welcome to MakerHome
We've completed our yearlong print-a-day project!
All new material is now at Hacktastic: www.mathgrrl.com
Saturday, February 1, 2014
Friday, January 31, 2014
Day 158 - One hundred fidget cubes
Actually, it's 105, counting the ones that are printing in the background. We've been making these all week; they print fairly reliably in batches of a dozen. We need to make 400 of these by mid-March for a set of conference giveaways.
STL file: http://www.geekhaus.com/makerhome/day158_fidgetcubesmall.stl
Thingiverse link: http://www.thingiverse.com/make:64083
Settings: MakerWare .2mm/standard with no raft and no support (this layer height and settings are required for the hinges and clearances to work correctly). Each batch of 12 takes a bit over four hours to print.
Technical notes: Here are the customizer settings that make this model. (This is just like the tiny example model from Day 148 except with hinge_clearance increased to 0.5.)
STL file: http://www.geekhaus.com/makerhome/day158_fidgetcubesmall.stl
Thingiverse link: http://www.thingiverse.com/make:64083
Settings: MakerWare .2mm/standard with no raft and no support (this layer height and settings are required for the hinges and clearances to work correctly). Each batch of 12 takes a bit over four hours to print.
Technical notes: Here are the customizer settings that make this model. (This is just like the tiny example model from Day 148 except with hinge_clearance increased to 0.5.)
cube_height = 10
hinge_radius = 1.5
snub = yes
stacking_clearance = .3
hinge_clearance = .5
Thursday, January 30, 2014
Day 157 - One-piece Menger cube without internal supports
The Holy Grail! Owens' model Menger sponge with external support prints a beautiful Level 2 Menger sponge with no internal supports. The difficulty with printing a Menger sponge on a filament-deposition printer is that in the horizontal position, the model is stable on the build platform but requires a vast amount of internal support that is nearly impossible to remove. On the other hand, in the diagonal position, the model has holes with 45-degree sides that are easy to print without support, but as a whole is unstable on the platform.
In hindsight the solution is obvious, but such is the case with all great ideas. The hard part is to have the idea in the first place! The key to owens' model is a specially constructed ring of external support that is easy to break off after printing. It works beautifully!
Thingiverse link: http://www.thingiverse.com/thing:238551
Settings: MakerWare .2mm/standard on a Replicator 2; each model is at 50% scale and took just under an hour to print.
Stuff to change: It would not be difficult to change owens' OpenSCAD code (at the Thingiverse link) to make a Level 3 Menger cube. Or, dare we hope, Level 4??
In hindsight the solution is obvious, but such is the case with all great ideas. The hard part is to have the idea in the first place! The key to owens' model is a specially constructed ring of external support that is easy to break off after printing. It works beautifully!
Thingiverse link: http://www.thingiverse.com/thing:238551
Settings: MakerWare .2mm/standard on a Replicator 2; each model is at 50% scale and took just under an hour to print.
Stuff to change: It would not be difficult to change owens' OpenSCAD code (at the Thingiverse link) to make a Level 3 Menger cube. Or, dare we hope, Level 4??
Wednesday, January 29, 2014
Day 156 - Olee's designs
Today we printed some custom bracelets for my niece, who mailed us a very nice letter that included some awesome designs to start from. Her designs were so good that we decided to print them exactly as she drew them! We tried to size them correctly but if they don't fit then they can be used as picture frames or room decorations.
Tinkercad link for heart: https://tinkercad.com/things/89CANRAiU05-day-156-olee-heart
Tinkercad link for frame: https://tinkercad.com/things/6fmQbUNMfqv-day-156-olee-olee
Thingiverse link: http://www.thingiverse.com/thing:238516
Settings: MakerWare .3mm/low on a Replicator 2.
Technical notes: We used the photo --> Inkscape --> bitmap --> SVG --> Tinkercad chain to make this, just like in Day 109.
Tinkercad link for heart: https://tinkercad.com/things/89CANRAiU05-day-156-olee-heart
Tinkercad link for frame: https://tinkercad.com/things/6fmQbUNMfqv-day-156-olee-olee
Thingiverse link: http://www.thingiverse.com/thing:238516
Settings: MakerWare .3mm/low on a Replicator 2.
Technical notes: We used the photo --> Inkscape --> bitmap --> SVG --> Tinkercad chain to make this, just like in Day 109.
Tuesday, January 28, 2014
Day 155 - Menger slice
Today we printed owens' Diagonal Cut Menger Sponge design from Thingiverse. If you sliced a Level 2 Menger sponge in half along a diagonal plane as shown in the picture, what would the sliced face look like? Before you scroll down, take a look at this picture and try to imagine it: If you could see the hidden diagonal face made by the slice, what would it look like? Would it have holes in it? What kind? Don't peek!
The answer is: Whatever you said, you're wrong. Instead you get this:
Thingiverse link: http://www.thingiverse.com/make:63728
Settings: MakerWare .3mm/low, with no raft and no support. This makes a nice model but the detail on the stars could be better, so next time we'll use a finer setting.
Further reading: Making sliced Menger cubes is a popular sport. MadOverlord's design Diagonally-Sliced 3-Level Menger Sponge is a nice Level 3 version. Over at the Simons Foundation, George Hart has a nice video about slicing Menger cubes. And Gaya has a nice post on her blog A Girl with a 3D Printer about the advantages of printing Menger cubes diagonally instead of in the upright position. Printing upright/horizontally causes great sadness and an impossible amount of support to remove, but diagonal printing allows for beautiful prints without any support material at all.
The answer is: Whatever you said, you're wrong. Instead you get this:
Thingiverse link: http://www.thingiverse.com/make:63728
Settings: MakerWare .3mm/low, with no raft and no support. This makes a nice model but the detail on the stars could be better, so next time we'll use a finer setting.
Further reading: Making sliced Menger cubes is a popular sport. MadOverlord's design Diagonally-Sliced 3-Level Menger Sponge is a nice Level 3 version. Over at the Simons Foundation, George Hart has a nice video about slicing Menger cubes. And Gaya has a nice post on her blog A Girl with a 3D Printer about the advantages of printing Menger cubes diagonally instead of in the upright position. Printing upright/horizontally causes great sadness and an impossible amount of support to remove, but diagonal printing allows for beautiful prints without any support material at all.
Monday, January 27, 2014
Day 154 - First Digitizer Print!
To break in the new MakerBot Digitizer in the JMU 3-SPACE Classroom, my student Patrick scanned and printed a beautiful African woman statue that another student gave me as a gift many years ago. It came out great, with lots of the details intact even with a small print. (This model is also a prototype of a game token that will be part of a later project, so stay tuned.) Does it count as a "print from home" if this print was made at work, and not even by me? It's my blog and I''m really excited about the Digitizer so yes, yes it does.
STL file: http://www.geekhaus.com/makerhome/day154_africanstatue.stl
Thingiverse link: COMING SOON
Settings: MakerWare .2mm/standard. Although we nearly always print in .3mm/low, in this case we wanted to catch some of the finer details.
Call for suggestions: We are finding it surprisingly difficult to find things to scan for some reason. Everything we consider is either something we could design ourselves, or something that has too much interior detail or too many organic features to scan reliably, or something very shiny and therefore difficult to scan, or something we already 3D printed! If you have any good suggestions please let me know. Somehow I thought we would be digitizing everything in sight right away, but we seem to have scanner's block...
STL file: http://www.geekhaus.com/makerhome/day154_africanstatue.stl
Thingiverse link: COMING SOON
Settings: MakerWare .2mm/standard. Although we nearly always print in .3mm/low, in this case we wanted to catch some of the finer details.
Call for suggestions: We are finding it surprisingly difficult to find things to scan for some reason. Everything we consider is either something we could design ourselves, or something that has too much interior detail or too many organic features to scan reliably, or something very shiny and therefore difficult to scan, or something we already 3D printed! If you have any good suggestions please let me know. Somehow I thought we would be digitizing everything in sight right away, but we seem to have scanner's block...
Sunday, January 26, 2014
Day 153 - Stick and lattice trefoil knots
To finish our collection of trefoil conformations, we have a stick knot and a cubic lattice knot:
STL file for stick: http://www.geekhaus.com/makerhome/day153_trefoil_stick_40_25.stl
STL file for lattice: http://www.geekhaus.com/makerhome/day153_trefoil_lattice_40_25.stl
Thingiverse link: http://www.thingiverse.com/thing:234107
Technical notes, math flavor: Usually in knot theory, although the knots we draw are curvy, in the back of our minds we require that the knots we study are nice enough to be put into some piecewise-linear format with a finite number of straight pieces. This is to avoid having to deal with wild knots, which are truly unreasonable and the sort of thing you see in the following diagram from Rolfsen's book Knots and Links (image here from Aaron Heap of SUNY Geneseo):
I remember when I first saw this picture, at literally half the age I am now, while in an REU program learning about knot theory for the first time. My brain fell into a thousand tiny pieces, after which I agreed: we *definitely* do not want to work with knots like these. (Nowadays we have fancier pictures of the terrible and wonderful Alexander horned sphere, if you are interested.)
Anyway, the stick and lattice knots above are very nice knots, not wild at all, but the first question we have to ask about such knots is this: given a knot, can we always represent it in such a fashion? And if so, what is the fewest number of sticks that we can use (the stick number)? In the first example we have a stick knot for which the only requirement is that the sticks be sticks. In the second picture we also require that the sticks sit on a cubic integer lattice, which means that more sticks are required. People also study knots made out of sticks that are all the same length ("equilateral" stick knots) and knots that are made out of sticks with the same length and the same angle between each adjacent pair of sticks ("alpha-regular" stick knots). The stick knot model of the trefoil above illustrates that 6 is the minimum possible number of sticks that can be used to make a trefoil. The right-angled lattice knot on the right side of the picture illustrates that 24 units is the minimum length of rope that can be used to make the trefoil in the cubic lattice.
Technical notes, OpenSCAD flavor: The code for these knots is easy; each knot is constructed from a very small number of spheres at specific coordinates which are combined in "hulls" when adjacent. The coordinate data is from The Knot Server. And yes, this is ridiculously stupid OpenSCAD code but it makes pretty knots anyway!
// trefoil in minimal stick conformation
// http://newweb.cecm.sfu.ca/cgi-bin/KnotPlot/KnotServer/kserver?ncomp=1&ncross=3&id=1
s = 13;
r=2.5;
p1=[s*0.300775, s*1.301248, s*(-0.702434)];
p2=[s*(-0.976281), s*(-0.910795), s*0.701983];
p3=[s*0.976171, s*(-0.910795), s*(-0.702076)];
p4=[s*(-0.300495), s*1.300967, s*0.702620];
p5=[s*(-1.276451), s*(-0.390204), s*(-0.702474)];
p6=[s*1.276282, s*(-0.390420), s*0.702381];
hull(){
translate(p1) sphere(r);
translate(p2) sphere(r);
}
hull(){
translate(p2) sphere(r);
translate(p3) sphere(r);
}
hull(){
translate(p3) sphere(r);
translate(p4) sphere(r);
}
hull(){
translate(p4) sphere(r);
translate(p5) sphere(r);
}
hull(){
translate(p5) sphere(r);
translate(p6) sphere(r);
}
hull(){
translate(p6) sphere(r);
translate(p1) sphere(r);
}
// trefoil as minimal cubic lattice knot
// http://www.knotplot.com/EquiLat/CubicLatticeKnots.html
// http://bit-player.org/wp-content/extras/bph-publications/AmSci-1997-11-Hayes-square-knots/compsci9711.html
s = 11;
r=2.5;
p1=[s*0, s*0, s*2];
p2=[s*0, s*2, s*2];
p3=[s*2, s*2, s*2];
p4=[s*2, s*1, s*2];
p5=[s*3, s*1, s*2];
p6=[s*3, s*1, s*0];
p7=[s*1, s*1, s*0];
p8=[s*1, s*1, s*3];
p9=[s*2, s*1, s*3];
p10=[s*2, s*2, s*3];
p11=[s*3, s*2, s*3];
p12=[s*3, s*2, s*1];
p13=[s*2, s*2, s*1];
p14=[s*2, s*0, s*1];
p15=[s*1, s*0, s*1];
p16=[s*1, s*0, s*2];
p17=[s*0, s*0, s*2];
translate([-1.5*s,-1.5*s,-1.5*s])
union(){
hull(){
translate(p1) sphere(r);
translate(p2) sphere(r);
}
hull(){
translate(p2) sphere(r);
translate(p3) sphere(r);
}
hull(){
translate(p3) sphere(r);
translate(p4) sphere(r);
}
hull(){
translate(p4) sphere(r);
translate(p5) sphere(r);
}
hull(){
translate(p5) sphere(r);
translate(p6) sphere(r);
}
hull(){
translate(p6) sphere(r);
translate(p7) sphere(r);
}
hull(){
translate(p7) sphere(r);
translate(p8) sphere(r);
}
hull(){
translate(p8) sphere(r);
translate(p9) sphere(r);
}
hull(){
translate(p9) sphere(r);
translate(p10) sphere(r);
}
hull(){
translate(p10) sphere(r);
translate(p11) sphere(r);
}
hull(){
translate(p11) sphere(r);
translate(p12) sphere(r);
}
hull(){
translate(p12) sphere(r);
translate(p13) sphere(r);
}
hull(){
translate(p13) sphere(r);
translate(p14) sphere(r);
}
hull(){
translate(p14) sphere(r);
translate(p15) sphere(r);
}
hull(){
translate(p15) sphere(r);
translate(p16) sphere(r);
}
hull(){
translate(p16) sphere(r);
translate(p17) sphere(r);
}
hull(){
translate(p17) sphere(r);
translate(p1) sphere(r);
}
}
STL file for stick: http://www.geekhaus.com/makerhome/day153_trefoil_stick_40_25.stl
STL file for lattice: http://www.geekhaus.com/makerhome/day153_trefoil_lattice_40_25.stl
Thingiverse link: http://www.thingiverse.com/thing:234107
Technical notes, math flavor: Usually in knot theory, although the knots we draw are curvy, in the back of our minds we require that the knots we study are nice enough to be put into some piecewise-linear format with a finite number of straight pieces. This is to avoid having to deal with wild knots, which are truly unreasonable and the sort of thing you see in the following diagram from Rolfsen's book Knots and Links (image here from Aaron Heap of SUNY Geneseo):
I remember when I first saw this picture, at literally half the age I am now, while in an REU program learning about knot theory for the first time. My brain fell into a thousand tiny pieces, after which I agreed: we *definitely* do not want to work with knots like these. (Nowadays we have fancier pictures of the terrible and wonderful Alexander horned sphere, if you are interested.)
Anyway, the stick and lattice knots above are very nice knots, not wild at all, but the first question we have to ask about such knots is this: given a knot, can we always represent it in such a fashion? And if so, what is the fewest number of sticks that we can use (the stick number)? In the first example we have a stick knot for which the only requirement is that the sticks be sticks. In the second picture we also require that the sticks sit on a cubic integer lattice, which means that more sticks are required. People also study knots made out of sticks that are all the same length ("equilateral" stick knots) and knots that are made out of sticks with the same length and the same angle between each adjacent pair of sticks ("alpha-regular" stick knots). The stick knot model of the trefoil above illustrates that 6 is the minimum possible number of sticks that can be used to make a trefoil. The right-angled lattice knot on the right side of the picture illustrates that 24 units is the minimum length of rope that can be used to make the trefoil in the cubic lattice.
Technical notes, OpenSCAD flavor: The code for these knots is easy; each knot is constructed from a very small number of spheres at specific coordinates which are combined in "hulls" when adjacent. The coordinate data is from The Knot Server. And yes, this is ridiculously stupid OpenSCAD code but it makes pretty knots anyway!
// trefoil in minimal stick conformation
// http://newweb.cecm.sfu.ca/cgi-bin/KnotPlot/KnotServer/kserver?ncomp=1&ncross=3&id=1
s = 13;
r=2.5;
p1=[s*0.300775, s*1.301248, s*(-0.702434)];
p2=[s*(-0.976281), s*(-0.910795), s*0.701983];
p3=[s*0.976171, s*(-0.910795), s*(-0.702076)];
p4=[s*(-0.300495), s*1.300967, s*0.702620];
p5=[s*(-1.276451), s*(-0.390204), s*(-0.702474)];
p6=[s*1.276282, s*(-0.390420), s*0.702381];
hull(){
translate(p1) sphere(r);
translate(p2) sphere(r);
}
hull(){
translate(p2) sphere(r);
translate(p3) sphere(r);
}
hull(){
translate(p3) sphere(r);
translate(p4) sphere(r);
}
hull(){
translate(p4) sphere(r);
translate(p5) sphere(r);
}
hull(){
translate(p5) sphere(r);
translate(p6) sphere(r);
}
hull(){
translate(p6) sphere(r);
translate(p1) sphere(r);
}
// trefoil as minimal cubic lattice knot
// http://www.knotplot.com/EquiLat/CubicLatticeKnots.html
// http://bit-player.org/wp-content/extras/bph-publications/AmSci-1997-11-Hayes-square-knots/compsci9711.html
s = 11;
r=2.5;
p1=[s*0, s*0, s*2];
p2=[s*0, s*2, s*2];
p3=[s*2, s*2, s*2];
p4=[s*2, s*1, s*2];
p5=[s*3, s*1, s*2];
p6=[s*3, s*1, s*0];
p7=[s*1, s*1, s*0];
p8=[s*1, s*1, s*3];
p9=[s*2, s*1, s*3];
p10=[s*2, s*2, s*3];
p11=[s*3, s*2, s*3];
p12=[s*3, s*2, s*1];
p13=[s*2, s*2, s*1];
p14=[s*2, s*0, s*1];
p15=[s*1, s*0, s*1];
p16=[s*1, s*0, s*2];
p17=[s*0, s*0, s*2];
translate([-1.5*s,-1.5*s,-1.5*s])
union(){
hull(){
translate(p1) sphere(r);
translate(p2) sphere(r);
}
hull(){
translate(p2) sphere(r);
translate(p3) sphere(r);
}
hull(){
translate(p3) sphere(r);
translate(p4) sphere(r);
}
hull(){
translate(p4) sphere(r);
translate(p5) sphere(r);
}
hull(){
translate(p5) sphere(r);
translate(p6) sphere(r);
}
hull(){
translate(p6) sphere(r);
translate(p7) sphere(r);
}
hull(){
translate(p7) sphere(r);
translate(p8) sphere(r);
}
hull(){
translate(p8) sphere(r);
translate(p9) sphere(r);
}
hull(){
translate(p9) sphere(r);
translate(p10) sphere(r);
}
hull(){
translate(p10) sphere(r);
translate(p11) sphere(r);
}
hull(){
translate(p11) sphere(r);
translate(p12) sphere(r);
}
hull(){
translate(p12) sphere(r);
translate(p13) sphere(r);
}
hull(){
translate(p13) sphere(r);
translate(p14) sphere(r);
}
hull(){
translate(p14) sphere(r);
translate(p15) sphere(r);
}
hull(){
translate(p15) sphere(r);
translate(p16) sphere(r);
}
hull(){
translate(p16) sphere(r);
translate(p17) sphere(r);
}
hull(){
translate(p17) sphere(r);
translate(p1) sphere(r);
}
}
Saturday, January 25, 2014
Day 152 - Petal and tight trefoil knots
Two more trefoil conformations - as a petal knot (all crossings line up along one center stem) and a tight knot (with the smallest amount of rope length possible given its diameter):
STL file for petal: http://www.geekhaus.com/makerhome/day152_trefoil_petal_40_25_3.stl
STL file for tight: http://www.geekhaus.com/makerhome/day152_trefoil_minimumrope_25.stl
Thingiverse link: http://www.thingiverse.com/thing:234107
Settings: MakerWare .3mm/low in 20-25 minutes for the petal knot and even less for the tight knot, with the minimum-support custom slicing profile for knots described on Day 110.
Technical notes, math flavor: The beautiful petal knot conformation is from the paper Bounds on Übercrossing and Petal Numbers for Knots by Colin Adams at Williams College and his amazing team of student researchers. In this work Adams, et al made the startling decision to study "petal" projections of knots where the crossings occur all on top of each other in one place! This is a wild and crazy idea compared to the usual notion that we should look at knot projections where crossings happen nicely and one at a time. But this crazy idea bore some amazing fruit: they proved that every knot admits a petal projection, and went on to discover deep connections between the übercrossing number of knots and other traditional invariants such as crossing and unknotting numbers. I know I'm not supposed to have favorites, but of the eight trefoil knots I am printing in this collection, this is by far my favorite. It's beautiful and surprising each time you turn the knot over and the perspective shifts from one-crossing-at-a-time to all-crossings-lined-up-at-once. Wonderful! See the OpenSCAD code below if you want a (piecewise) parametrization of this knot.
Minimum-length rope knot conformations of the tiny trefoil aren't the most impressive, but for higher-crossing knots they are fascinating, and what started my journey with 3D printing last year. Jason Cantarella at the University of Georgia and Eric Rawdon at the University of St. Thomas, together with some students, have been investigating "tight" knots since their paper Knot Tightening by Constrained Gradient Descent in which they used their ridgerunner algorithm to find minimal conformations of a large number of knots. The data they made available with this paper was what helped me model my first 3D-printable knot models (for example, see Day 9, Day 11, Day 66, and Day 67).
Technical notes, OpenSCAD flavor: By the time of this posting, kitwallace and the GitHub OpenSCAD community had improved this code significantly; see kitwallace's excellent post at his blog The Wallace Line. However the new code requires the new 2014.01.04 snapshot of OpenSCAD, which does not want to work on my machine at the moment. Therefore I will post the old, slow code. It works but it ain't fast. In fact, it ain't pretty either, since getting Adams' petal knot parametrization to work in OpenSCAD required creating a very clunky piecewise function, as you will see in the code below. And it just gets worse for the tight knot; I have a very inefficient piece of code that takes 50 coordinates from Cantarella's data and connects the dots with hulled pairs of spheres. I am sure a nice loop would have made quicker work of the problem, but at the time my clunky mess of code was easier to write. I've put that code under the fold so you have to click through to see my code of shame.
// mathgrrl parametric knots
// tubify module based on tube module from kitwallace
// choose the knot you want and comment out the rest
// trefoil as petal knot
// http://arxiv.org/pdf/1311.0526v1.pdf
// based on mma algorithm from Adams, need to do z-coord in cases
// scaled to 40mm before tubifying
tempstep = .005; //.005/1 is 2/360
function g(t,a,b,u,v) =
[ 3.5*5*cos(180*t)*sin(5*180*t),
3.5*5*sin(180*t)*sin(5*180*t),
8*u*(cos(180*(((5*t-a+1)%5)-1)/2))*(cos(180*(((5*t-a+1)%5)-1)/2))
+ 8*v*(cos(180*(((5*t-b+1)%5)-1)/2))*(cos(180*(((5*t-b+1)%5)-1)/2))
];
translate([0,0,-24])
union(){
color("red")
for (t=[1: tempstep: 1.2-tempstep]) { //replacement for 0 to .2
hull() {
translate(g(t,5,1,4,1)) sphere(2.5);
translate(g(t+tempstep,5,1,4,1)) sphere(2.5);
}
}
color("orange")
for (t=[.2: tempstep: .4]) { //also why here?
hull() {
translate(g(t,1,2,1,3)) sphere(2.5);
translate(g(t+tempstep,1,2,1,3)) sphere(2.5);
}
}
color("yellow")
for (t=[.4: tempstep: .6]) {
hull() {
translate(g(t,2,3,3,5)) sphere(2.5);
translate(g(t+tempstep,2,3,3,5)) sphere(2.5);
}
}
color("green")
for (t=[.6: tempstep: .8]) {
hull() {
translate(g(t,3,4,5,2)) sphere(2.5);
translate(g(t+tempstep,3,4,5,2)) sphere(2.5);
}
}
color("blue")
for (t=[.8: tempstep: 1]) {
hull() {
translate(g(t,4,5,2,4)) sphere(2.5);
translate(g(t+tempstep,4,5,2,4)) sphere(2.5);
}
}
}
STL file for petal: http://www.geekhaus.com/makerhome/day152_trefoil_petal_40_25_3.stl
STL file for tight: http://www.geekhaus.com/makerhome/day152_trefoil_minimumrope_25.stl
Thingiverse link: http://www.thingiverse.com/thing:234107
Settings: MakerWare .3mm/low in 20-25 minutes for the petal knot and even less for the tight knot, with the minimum-support custom slicing profile for knots described on Day 110.
Technical notes, math flavor: The beautiful petal knot conformation is from the paper Bounds on Übercrossing and Petal Numbers for Knots by Colin Adams at Williams College and his amazing team of student researchers. In this work Adams, et al made the startling decision to study "petal" projections of knots where the crossings occur all on top of each other in one place! This is a wild and crazy idea compared to the usual notion that we should look at knot projections where crossings happen nicely and one at a time. But this crazy idea bore some amazing fruit: they proved that every knot admits a petal projection, and went on to discover deep connections between the übercrossing number of knots and other traditional invariants such as crossing and unknotting numbers. I know I'm not supposed to have favorites, but of the eight trefoil knots I am printing in this collection, this is by far my favorite. It's beautiful and surprising each time you turn the knot over and the perspective shifts from one-crossing-at-a-time to all-crossings-lined-up-at-once. Wonderful! See the OpenSCAD code below if you want a (piecewise) parametrization of this knot.
Minimum-length rope knot conformations of the tiny trefoil aren't the most impressive, but for higher-crossing knots they are fascinating, and what started my journey with 3D printing last year. Jason Cantarella at the University of Georgia and Eric Rawdon at the University of St. Thomas, together with some students, have been investigating "tight" knots since their paper Knot Tightening by Constrained Gradient Descent in which they used their ridgerunner algorithm to find minimal conformations of a large number of knots. The data they made available with this paper was what helped me model my first 3D-printable knot models (for example, see Day 9, Day 11, Day 66, and Day 67).
Technical notes, OpenSCAD flavor: By the time of this posting, kitwallace and the GitHub OpenSCAD community had improved this code significantly; see kitwallace's excellent post at his blog The Wallace Line. However the new code requires the new 2014.01.04 snapshot of OpenSCAD, which does not want to work on my machine at the moment. Therefore I will post the old, slow code. It works but it ain't fast. In fact, it ain't pretty either, since getting Adams' petal knot parametrization to work in OpenSCAD required creating a very clunky piecewise function, as you will see in the code below. And it just gets worse for the tight knot; I have a very inefficient piece of code that takes 50 coordinates from Cantarella's data and connects the dots with hulled pairs of spheres. I am sure a nice loop would have made quicker work of the problem, but at the time my clunky mess of code was easier to write. I've put that code under the fold so you have to click through to see my code of shame.
// mathgrrl parametric knots
// tubify module based on tube module from kitwallace
// choose the knot you want and comment out the rest
// trefoil as petal knot
// http://arxiv.org/pdf/1311.0526v1.pdf
// based on mma algorithm from Adams, need to do z-coord in cases
// scaled to 40mm before tubifying
tempstep = .005; //.005/1 is 2/360
function g(t,a,b,u,v) =
[ 3.5*5*cos(180*t)*sin(5*180*t),
3.5*5*sin(180*t)*sin(5*180*t),
8*u*(cos(180*(((5*t-a+1)%5)-1)/2))*(cos(180*(((5*t-a+1)%5)-1)/2))
+ 8*v*(cos(180*(((5*t-b+1)%5)-1)/2))*(cos(180*(((5*t-b+1)%5)-1)/2))
];
translate([0,0,-24])
union(){
color("red")
for (t=[1: tempstep: 1.2-tempstep]) { //replacement for 0 to .2
hull() {
translate(g(t,5,1,4,1)) sphere(2.5);
translate(g(t+tempstep,5,1,4,1)) sphere(2.5);
}
}
color("orange")
for (t=[.2: tempstep: .4]) { //also why here?
hull() {
translate(g(t,1,2,1,3)) sphere(2.5);
translate(g(t+tempstep,1,2,1,3)) sphere(2.5);
}
}
color("yellow")
for (t=[.4: tempstep: .6]) {
hull() {
translate(g(t,2,3,3,5)) sphere(2.5);
translate(g(t+tempstep,2,3,3,5)) sphere(2.5);
}
}
color("green")
for (t=[.6: tempstep: .8]) {
hull() {
translate(g(t,3,4,5,2)) sphere(2.5);
translate(g(t+tempstep,3,4,5,2)) sphere(2.5);
}
}
color("blue")
for (t=[.8: tempstep: 1]) {
hull() {
translate(g(t,4,5,2,4)) sphere(2.5);
translate(g(t+tempstep,4,5,2,4)) sphere(2.5);
}
}
}
Friday, January 24, 2014
Day 151 - Fourier and tritangentless trefoil knots
Continuing our collection of trefoil knots, today we printed a trefoil in a Fourier-(1,1,2) knot conformation and a trefoil knot in a tritangentless conformation. In other words, the first trefoil knot in the picture below is a curve traced out by a collection of cosine functions (1 in the x-coordinate, 1 in the y-coordinate, and 2 in the z-coordinate), and the second has the property that no plane is tangent to three places on the curve at the same time (making this a rocking/rolling knot as seen on Day 110).
STL file for Fourier-(1,1,2): http://www.geekhaus.com/makerhome/day151_trefoil_fourier112_40_25_3.stl
STL file for tritangentless: http://www.geekhaus.com/makerhome/day151_trefoil_tritangentless_40_25_3.stl
Thingiverse link: http://www.thingiverse.com/thing:234107
Settings: MakerWare .3mm/low in 20-25 minutes per knot, with the minimum-support custom slicing profile for knots described on Day 110.
Technical notes, math flavor: A Fourier-(1,1,2) knot is one that can be parametrized as
The tritangentless conformation is a variant of the parametrization of the trefoil that appears in the paper Trefoil knots without tritangent planes by H.R. Morton at the University of Liverpool. For more information see Day 110, and for the explicit equations see the OpenSCAD code below.
Technical notes, OpenSCAD flavor: The code below was based on kitwallace's code from his Rolling Knot on Thingiverse. It's slow to render with F6, taking nearly a half an hour to get a model with step size 3 (which is 120 steps). The code is written so that you can size your knot before setting the strand thickness, which allows us to scale up models without affecting the thickness of the strand.
// mathgrrl parametric knots - fourier and tritangentless trefoils
// tubify module based on tube module from kitwallace
// remove comments for the one you want to compile
/*
// 3_1 tritangentless conformation
// http://blms.oxfordjournals.org/content/23/1/78.full.pdf
a = 0.8;
b = sqrt (1 - a * a);
function f(t) =
[ 8.7 * a * cos (3 * t) / (1 - b* sin (2 *t)),
8.7 * a * sin( 3 * t) / (1 - b* sin (2 *t)),
8.7 * 1.8 * b * cos (2 * t) /(1 - b* sin (2 *t))
];
// create the knot with given radius and step
tubify(2.5, 3, 360);
*/
/*
// trefoil 32 as Fourier-(1,1,2)
// http://arxiv.org/pdf/0708.3590v1.pdf
// note torus knots are not Lissajous (1,1,1)
// scaled to 40mm before tubifying
function f(t) =
[ 9*1.3*cos(3*t),
9*1.5*cos(2*t + 30),
9*(1.3*cos(3*t + 90) + .9*cos(-t + 30*2 - 45/2))
];
// create the knot with given radius and step
tubify(2.5, 3, 360);
*/
module tubify(r, step, end) {
for (t=[0: step: end+step]) {
hull() {
translate(f(t)) sphere(r);
translate(f(t+step)) sphere(r);
}
}
};
STL file for Fourier-(1,1,2): http://www.geekhaus.com/makerhome/day151_trefoil_fourier112_40_25_3.stl
STL file for tritangentless: http://www.geekhaus.com/makerhome/day151_trefoil_tritangentless_40_25_3.stl
Thingiverse link: http://www.thingiverse.com/thing:234107
Settings: MakerWare .3mm/low in 20-25 minutes per knot, with the minimum-support custom slicing profile for knots described on Day 110.
Technical notes, math flavor: A Fourier-(1,1,2) knot is one that can be parametrized as
x = a cos(nt + p)These equations are from the paper Torus knots are Fourier-(1,1,2) Knots by Jim Hoste at Pitzer College. Here a, b, c, d, p, q, r, and s can be any real numbers, and n, m, j, and k are integers. If d=0 then the parametrization is said to be a Fourier-(1,1,1) knot, which is also known as a Lissajous knot. It is known that torus knots do not have Lissajous parametrizations (for more information see this page from Lee Stemkoski at Adelphi University).
y = b cos(mt + q)
z = c cos(jt + r) + d cos(kt + s)
The tritangentless conformation is a variant of the parametrization of the trefoil that appears in the paper Trefoil knots without tritangent planes by H.R. Morton at the University of Liverpool. For more information see Day 110, and for the explicit equations see the OpenSCAD code below.
Technical notes, OpenSCAD flavor: The code below was based on kitwallace's code from his Rolling Knot on Thingiverse. It's slow to render with F6, taking nearly a half an hour to get a model with step size 3 (which is 120 steps). The code is written so that you can size your knot before setting the strand thickness, which allows us to scale up models without affecting the thickness of the strand.
// mathgrrl parametric knots - fourier and tritangentless trefoils
// tubify module based on tube module from kitwallace
// remove comments for the one you want to compile
/*
// 3_1 tritangentless conformation
// http://blms.oxfordjournals.org/content/23/1/78.full.pdf
a = 0.8;
b = sqrt (1 - a * a);
function f(t) =
[ 8.7 * a * cos (3 * t) / (1 - b* sin (2 *t)),
8.7 * a * sin( 3 * t) / (1 - b* sin (2 *t)),
8.7 * 1.8 * b * cos (2 * t) /(1 - b* sin (2 *t))
];
// create the knot with given radius and step
tubify(2.5, 3, 360);
*/
/*
// trefoil 32 as Fourier-(1,1,2)
// http://arxiv.org/pdf/0708.3590v1.pdf
// note torus knots are not Lissajous (1,1,1)
// scaled to 40mm before tubifying
function f(t) =
[ 9*1.3*cos(3*t),
9*1.5*cos(2*t + 30),
9*(1.3*cos(3*t + 90) + .9*cos(-t + 30*2 - 45/2))
];
// create the knot with given radius and step
tubify(2.5, 3, 360);
*/
module tubify(r, step, end) {
for (t=[0: step: end+step]) {
hull() {
translate(f(t)) sphere(r);
translate(f(t+step)) sphere(r);
}
}
};
Thursday, January 23, 2014
Day 150 - Trefoil torus knots
For the next four days we'll be posting various mathematically interesting models of the trefoil knot. Mathematicians consider two knotted forms to be equivalent if one can be transformed into the other by stretching and moving in space, without cutting or joining. The way a knot sits in space is known as its conformation. Two of the best-known shapes for the trefoil knot are the T(2,3) and T(3,2) torus knot conformations:
STL file for T(2,3): http://www.geekhaus.com/makerhome/day150_trefoil_torus23_40_25_3.stl
STL file for T(3,2): http://www.geekhaus.com/makerhome/day150_trefoil_torus32_40_25_3.stl
Thingiverse link: http://www.thingiverse.com/thing:234107
Settings: MakerWare .3mm/low in 20-25 minutes per knot, with the custom slicing profile from Day 110.
Technical notes, math flavor: Torus knots are knots that can be wrapped around a torus (inner-tube or donut shape) without any self-intersections. The torus knot T(p,q) wraps p times around the torus like a clock at the same time that it wraps q times around the handle of the torus. The knot T(p,q) is always equivalent to the knot T(q,p), even though the two conformations can at first glance appear to be quite different. In the picture below from Paul Aspinwall at Duke University, the torus knot T(3,5)=T(5,3) wraps 3 times around the outside and 5 times around the handle.
The parametric equations for a torus with handle radius a and large radius c are (see Wolfram):
Technical notes, OpenSCAD flavor: The knots are made using parametric equations that trace out a curve along the surface of a torus. The code below samples points along this curve, puts spheres at those points, and then connects adjacent points with a hull. You can control the thickness of the curve by changing the radius of the spheres. Much thanks to kitwallace who had the idea to model curves this way in OpenSCAD. Making knot models that can export to STL files is easy to do in Mathematica (see Day 110), but Mathematica is not a free tool and not everyone has access to it. In addition, Mathematica does not always export reliable STL files. OpenSCAD is free and makes fairly stable STL files; the only penalty is that it is SLOW. Here is the commented OpenSCAD code that produced the two models in this post:
// remove comments for the one you want to compile
/*
// trefoil as the torus knot T(2,3)
// http://mathworld.wolfram.com/Torus.html
// take parameterization of torus (u,v)->R^3
// and let u=2t, v=3t
// scaled to 40mm before tubifying
function f(t) =
[ 3.9*(3+1.6*cos(2*t))*cos(3*t),
3.9*(3+1.6*cos(2*t))*sin(3*t),
3.9*(1.6*sin(2*t))
];
// create the knot with given radius and step
tubify(2.5, 12, 360);
*/
/*
// trefoil as the torus knot T(3,2)
// http://mathworld.wolfram.com/Torus.html
// take parameterization of torus (u,v)->R^3
// and let u=2t, v=3t
// scaled to 40mm before tubifying
function f(t) =
[ 3.9*(3+1.6*cos(3*t))*cos(2*t),
3.9*(3+1.6*cos(3*t))*sin(2*t),
3.9*(1.6*sin(3*t))
];
// create the knot with given radius and step
tubify(2.5, 3, 360);
*/
module tubify(r, step, end) {
for (t=[0: step: end+step]) {
hull() {
translate(f(t)) sphere(r);
translate(f(t+step)) sphere(r);
}
}
};
STL file for T(2,3): http://www.geekhaus.com/makerhome/day150_trefoil_torus23_40_25_3.stl
STL file for T(3,2): http://www.geekhaus.com/makerhome/day150_trefoil_torus32_40_25_3.stl
Thingiverse link: http://www.thingiverse.com/thing:234107
Settings: MakerWare .3mm/low in 20-25 minutes per knot, with the custom slicing profile from Day 110.
Technical notes, math flavor: Torus knots are knots that can be wrapped around a torus (inner-tube or donut shape) without any self-intersections. The torus knot T(p,q) wraps p times around the torus like a clock at the same time that it wraps q times around the handle of the torus. The knot T(p,q) is always equivalent to the knot T(q,p), even though the two conformations can at first glance appear to be quite different. In the picture below from Paul Aspinwall at Duke University, the torus knot T(3,5)=T(5,3) wraps 3 times around the outside and 5 times around the handle.
The parametric equations for a torus with handle radius a and large radius c are (see Wolfram):
x = (c + a cos v) cos uIf we substitute u=pt and v=qt then as t runs from 0 to 2휋 we obtain a curve that traces the T(p,q) torus knot around the surface of the torus (and if p and q are reversed then we get the T(q,p) torus knot).
y = (c + a cos v) sin u
z = a sin v
Technical notes, OpenSCAD flavor: The knots are made using parametric equations that trace out a curve along the surface of a torus. The code below samples points along this curve, puts spheres at those points, and then connects adjacent points with a hull. You can control the thickness of the curve by changing the radius of the spheres. Much thanks to kitwallace who had the idea to model curves this way in OpenSCAD. Making knot models that can export to STL files is easy to do in Mathematica (see Day 110), but Mathematica is not a free tool and not everyone has access to it. In addition, Mathematica does not always export reliable STL files. OpenSCAD is free and makes fairly stable STL files; the only penalty is that it is SLOW. Here is the commented OpenSCAD code that produced the two models in this post:
// mathgrrl parametric knots - torus trefoils
// tubify module based on tube module from kitwallace
// http://www.thingiverse.com/thing:230557/// remove comments for the one you want to compile
/*
// trefoil as the torus knot T(2,3)
// http://mathworld.wolfram.com/Torus.html
// take parameterization of torus (u,v)->R^3
// and let u=2t, v=3t
// scaled to 40mm before tubifying
function f(t) =
[ 3.9*(3+1.6*cos(2*t))*cos(3*t),
3.9*(3+1.6*cos(2*t))*sin(3*t),
3.9*(1.6*sin(2*t))
];
// create the knot with given radius and step
tubify(2.5, 12, 360);
*/
/*
// trefoil as the torus knot T(3,2)
// http://mathworld.wolfram.com/Torus.html
// take parameterization of torus (u,v)->R^3
// and let u=2t, v=3t
// scaled to 40mm before tubifying
function f(t) =
[ 3.9*(3+1.6*cos(3*t))*cos(2*t),
3.9*(3+1.6*cos(3*t))*sin(2*t),
3.9*(1.6*sin(3*t))
];
// create the knot with given radius and step
tubify(2.5, 3, 360);
*/
module tubify(r, step, end) {
for (t=[0: step: end+step]) {
hull() {
translate(f(t)) sphere(r);
translate(f(t+step)) sphere(r);
}
}
};
Wednesday, January 22, 2014
Day 149 - Balloon dog
Today we rest. And print a balloon dog:
Thingiverse link: http://www.thingiverse.com/make:63096
Settings: MakerWare .3mm/low scaled to 57mm across, in 29 minutes with raft and support on a MakerBot Replicator 2.
Technical notes: We predict that the 3D-printed balloon dog will last infinitely longer than the one made out of a balloon.
Thingiverse link: http://www.thingiverse.com/make:63096
Settings: MakerWare .3mm/low scaled to 57mm across, in 29 minutes with raft and support on a MakerBot Replicator 2.
Technical notes: We predict that the 3D-printed balloon dog will last infinitely longer than the one made out of a balloon.
Tuesday, January 21, 2014
Day 148 - Shrinking and Remeshing the Fidget Cube
Now that the hinges on the Fidget Cube are smaller (see yesterday's post), we can make the cube itself smaller. Let's start by going down from cube length 20mm to cube length 15mm:
And now down to 10mm! This tiny fidget cube actually works, and it is very quick to print. I think this is pretty much the limit of how small we can go without the hinges becoming too short. (In fact, to get this print to work I had recode the outside hinges to be a bit larger so they wouldn't break apart when the model unsnaps for the first time.)
STL file for 15mm: http://www.geekhaus.com/makerhome/day148_fidgetcube_red.stl
STL file for 10mm: http://www.geekhaus.com/makerhome/day148_fidgetcube_white.stl
Thingiverse link: http://www.thingiverse.com/thing:230139
Settings: MakerWare .2mm/Standard with linear fill, with the 15mm model printing in about 40 minutes and the 10mm model printing in about 20 minutes.
Technical notes, MeshLab flavor: Nicbane commented on Thingiverse that my original models did not slice with Slic3r due to being non-manifold, meaning that somewhere in the mesh something bad happens, for example more than two faces meeting at the same edge, or faces being connected only by vertices, as shown in this picture from Martin Sälzle at PCL Developer's Blog:
Although MakerWare's slicer could handle whatever weirdness was happening from my OpenSCAD STL file, apparently Slic3r couldn't. I couldn't see the problem in MeshLab so I tried as many repairs as I could do without MeshLab crashing, which turned out to be the following list of repairs (all under Filters --> Cleaning and Repairing):
And now down to 10mm! This tiny fidget cube actually works, and it is very quick to print. I think this is pretty much the limit of how small we can go without the hinges becoming too short. (In fact, to get this print to work I had recode the outside hinges to be a bit larger so they wouldn't break apart when the model unsnaps for the first time.)
STL file for 15mm: http://www.geekhaus.com/makerhome/day148_fidgetcube_red.stl
STL file for 10mm: http://www.geekhaus.com/makerhome/day148_fidgetcube_white.stl
Thingiverse link: http://www.thingiverse.com/thing:230139
Settings: MakerWare .2mm/Standard with linear fill, with the 15mm model printing in about 40 minutes and the 10mm model printing in about 20 minutes.
Technical notes, MeshLab flavor: Nicbane commented on Thingiverse that my original models did not slice with Slic3r due to being non-manifold, meaning that somewhere in the mesh something bad happens, for example more than two faces meeting at the same edge, or faces being connected only by vertices, as shown in this picture from Martin Sälzle at PCL Developer's Blog:
Although MakerWare's slicer could handle whatever weirdness was happening from my OpenSCAD STL file, apparently Slic3r couldn't. I couldn't see the problem in MeshLab so I tried as many repairs as I could do without MeshLab crashing, which turned out to be the following list of repairs (all under Filters --> Cleaning and Repairing):
Remove Duplicate FacesFrom looking at the edge/vertex counts, I think the only one of the above that did anything was the T-Vertices repair, but better safe than sorry. According to Nicbane this did the trick.
Remove Duplicated Vertex
Remove Faces From Non Manifold Edges
Remove T-Vertices by Edge Flip
Interestingly, the T-Vertices repair in MeshLab only works without crashing for STL files generated directly from OpenSCAD and not for STL files that are generated by the Thingiverse Customizer. I think this might be because the Customizer already fixes the problem somehow; perhaps running the T-Vertices command on an already-fixed model crashes MeshLab?
Monday, January 20, 2014
Day 147 - Fidget Cube with Smaller Hinges
After more testing we figured out how small we can make the hinges on the Fidget Cube and still have it print reliably in one piece. (The answer: 1.5mm radius.)
STL file: http://www.geekhaus.com/makerhome/day147_fidgetcube_black.stl
Thingiverse link: http://www.thingiverse.com/thing:230139
Settings: MakerWare .2mm/standard in about 90 minutes, with no raft and no supports, one one piece. In the Customizer settings below, 1.5mm is the smallest that I could make hinge_radius before things got unreliable. However, hinge_clearance could safely be reduced if a stiffer model was desired.
UPDATE: The Print-In-Place Fidget Cube was Featured on Thingiverse today! Thank you, Thingiverse!
STL file: http://www.geekhaus.com/makerhome/day147_fidgetcube_black.stl
Thingiverse link: http://www.thingiverse.com/thing:230139
Settings: MakerWare .2mm/standard in about 90 minutes, with no raft and no supports, one one piece. In the Customizer settings below, 1.5mm is the smallest that I could make hinge_radius before things got unreliable. However, hinge_clearance could safely be reduced if a stiffer model was desired.
snub = yesFun fact: The picture below shows what it means to "design to fail". To make the Customizable Print-In-Place Fidget Cube we went through a lot of iterations of testing, re-testing, and failure.
cube_height = 20
stacking_clearance = .3
hinge_radius = 1.5
hinge_clearance = .5
UPDATE: The Print-In-Place Fidget Cube was Featured on Thingiverse today! Thank you, Thingiverse!
Sunday, January 19, 2014
Day 146 - Customizable Print-In-Place Fidget Cube
Today we finished our customizable print-in-place fidget cube model. By changing just a few parameters in OpenSCAD code, we can decide whether the fidget cube will have a snub configuration (as shown below), set the sizes of the blocks and the hinges, and fine-tune the clearance between moving parts. It still amazes me that this model can print in place, all in one piece, with functioning hinges - especially since during the print some of the hinges are horizontal while others are vertical!
STL file: http://www.geekhaus.com/makerhome/day146_fidgetcube_blue.stl
Thingiverse link: http://www.thingiverse.com/thing:230139
Settings: Replicator 2 with MakerWare .2mm/standard in about an hour and a half. In addition to looking cool, the snub sides reduce the print time by about 30 minutes and save some plastic. We used a custom profile to get linear fill instead of hexagons. No raft or support are needed! Customizer settings were as follows below (although I suggest setting hinge_clearance lower for future models).
// mathgrrl print-in-place fidget cube
//////////////////////////////////////////////////////
// PARAMETERS ////////////////////////////////////////
// Decide whether you want the pieces to be full cubes or snub on one side
snub = "yes"; // [no:Cube Pieces,yes:Snub Pieces]
// Choose a side length for the cubes, in mm
cube_height = 20;
// Choose a stacking clearance factor, in mm (controls distance between cubes)
stacking_clearance = .3;
// Choose a hinge radius, in mm
hinge_radius = 1.5;
// Choose a hinge clearance factor, in mm (controls distance around hinge parts)
hinge_clearance = .45;
// Other variables that people don't get to choose
$fn=24*1;
fudge = .01*1;
corner_radius = .1*cube_height;
outside_height = .4*(cube_height-2*stacking_clearance);
inside_height = (cube_height-2*stacking_clearance)-2*outside_height;
cone_height = 1.4*hinge_radius;
//////////////////////////////////////////////////////
// RENDERS ///////////////////////////////////////////
rotate(-45,[0,0,1])
translate([0,0,2*cube_height])
rotate(90,[0,1,0])
union(){
// one row of four cubes
row_assembly();
// another row of four cubes
translate([0,2*cube_height,2*cube_height])
rotate(-90,[1,0,0])
mirror([0,0,1])
mirror([1,0,0])
row_assembly();
}
//////////////////////////////////////////////////////
// MODULES ///////////////////////////////////////////
// one row of the assembly
module row_assembly(){
union(){
color("blue")
hinged_cube(180,[1,0,0],[1,0,0]);
color("red")
translate([-cube_height/2,cube_height/2,0])
mirror([0,1,0])
translate([-cube_height/2,cube_height/2,0])
rotate(90,[1,0,0])
hinged_cube(0,[1,0,0],[0,0,0]);
color("green")
translate([cube_height,cube_height/2,cube_height/2])
rotate(-90,[0,1,0])
rotate(180,[1,0,0])
mirror([0,1,0])
translate([-cube_height/2,cube_height/2,0])
rotate(90,[1,0,0])
hinged_cube(180,[0,1,0],[0,1,0]);
color("yellow")
translate([-cube_height,cube_height,cube_height])
rotate(-90,[1,0,0])
rotate(90,[0,0,1])
rotate(-90,[1,0,0])
hinged_cube(0,[1,0,0],[0,0,0]);
}
}
// one cube to rule them all
module hinged_cube(the_angle,the_vector,the_mirror){
difference(){
// cube and cylinders to start
union(){
// cube with inside top and bottom cylinders carved out
difference(){
// start with clearance cube in corner
translate([cube_height/2,cube_height/2,cube_height/2])
rotate(the_angle,the_vector)
mirror(the_mirror)
rounded_cube([cube_height,cube_height,cube_height]);
// take away inside top cylinder with clearance
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height+inside_height])
cylinder( h=outside_height+fudge,
r1=hinge_radius+fudge+hinge_clearance,
r2=hinge_radius+fudge+hinge_clearance);
// take away inside bottom cylinder with clearance
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance-fudge])
cylinder( h=outside_height+fudge,
r1=hinge_radius+fudge+hinge_clearance,
r2=hinge_radius+fudge+hinge_clearance);
}
// top cylinder on outside hinge
translate([0,0,stacking_clearance+outside_height+inside_height+hinge_clearance])
cylinder( h=outside_height-hinge_clearance-corner_radius/2,
r1=hinge_radius,
r2=hinge_radius);
// bottom cylinder on outside hinge
translate([0,0,stacking_clearance+corner_radius/2])
cylinder( h=outside_height-hinge_clearance-corner_radius/2,
r1=hinge_radius,
r2=hinge_radius);
// inside hinge cylinder
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height])
cylinder( h=inside_height,
r1=hinge_radius,
r2=hinge_radius);
// attacher for inside hinge cylinder
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height])
rotate(45,[0,0,1])
translate([-.8*hinge_radius,0,0])
cube([1.6*hinge_radius,2*hinge_radius,inside_height]);
// inside hinge top cone
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height+inside_height])
cylinder( h=cone_height,
r1=hinge_radius,
r2=0);
// inside hinge bottom cone
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height-cone_height])
cylinder( h=cone_height,
r1=0,
r2=hinge_radius);
}
// take away middle cylinder with clearance
translate([0,0,stacking_clearance+outside_height-hinge_clearance-fudge])
cylinder( h=inside_height+2*hinge_clearance+2*fudge,
r1=hinge_radius+fudge+hinge_clearance,
r2=hinge_radius+fudge+hinge_clearance);
// take away top cone with clearance
translate([0,0,stacking_clearance+outside_height+inside_height+hinge_clearance-fudge])
cylinder(h=cone_height, r1=hinge_radius, r2=0);
// take away bottom cone with clearance
translate([0,0,stacking_clearance+outside_height-cone_height-hinge_clearance+fudge])
cylinder(h=cone_height, r1=0, r2=hinge_radius);
}
}
// module for making rounded cubes from convex hull of corners
module rounded_cube() {
dist = cube_height/2-corner_radius-stacking_clearance;
hull() {
// seven of the eight vertices of a cube
translate([dist,dist,dist])
sphere(r=corner_radius);
translate([-dist,dist,dist])
sphere(r=corner_radius);
translate([dist,-dist,dist])
sphere(r=corner_radius);
translate([-dist,-dist,dist])
sphere(r=corner_radius);
translate([dist,dist,-dist])
sphere(r=corner_radius);
translate([dist,-dist,-dist])
sphere(r=corner_radius);
translate([-dist,-dist,-dist])
sphere(r=corner_radius);
// don't include the eighth if snub desired
if (snub=="yes"){
}
else{
translate([-dist,dist,-dist])
sphere(r=corner_radius);
}
}
}
UPDATE: Featured on 1/29/2014 as Thing-of-the-Day by AlexHuff at 3dideaform.com.
UPDATE: The print-in-place fidget cube made an appearance on the Adafruit blog with a comment from emmet himself (original creator of the printable snap-together fidget cube):
STL file: http://www.geekhaus.com/makerhome/day146_fidgetcube_blue.stl
Thingiverse link: http://www.thingiverse.com/thing:230139
Settings: Replicator 2 with MakerWare .2mm/standard in about an hour and a half. In addition to looking cool, the snub sides reduce the print time by about 30 minutes and save some plastic. We used a custom profile to get linear fill instead of hexagons. No raft or support are needed! Customizer settings were as follows below (although I suggest setting hinge_clearance lower for future models).
snub = yesTechnical notes: I tried to keep my previous OpenSCAD projects (Days 96, 112, 113, and 133) well-written and commented so that people could learn from what I was learning. But I'm notoriously bad at rotating and reflecting objects mentally so this code is full of random transformations to put objects where I needed them to be. It isn't efficient and it isn't pretty, but here it is:
cube_height = 20
stacking_clearance = .3
hinge_radius = 2.5
hinge_clearance = .5
// mathgrrl print-in-place fidget cube
//////////////////////////////////////////////////////
// PARAMETERS ////////////////////////////////////////
// Decide whether you want the pieces to be full cubes or snub on one side
snub = "yes"; // [no:Cube Pieces,yes:Snub Pieces]
// Choose a side length for the cubes, in mm
cube_height = 20;
// Choose a stacking clearance factor, in mm (controls distance between cubes)
stacking_clearance = .3;
// Choose a hinge radius, in mm
hinge_radius = 1.5;
// Choose a hinge clearance factor, in mm (controls distance around hinge parts)
hinge_clearance = .45;
// Other variables that people don't get to choose
$fn=24*1;
fudge = .01*1;
corner_radius = .1*cube_height;
outside_height = .4*(cube_height-2*stacking_clearance);
inside_height = (cube_height-2*stacking_clearance)-2*outside_height;
cone_height = 1.4*hinge_radius;
//////////////////////////////////////////////////////
// RENDERS ///////////////////////////////////////////
rotate(-45,[0,0,1])
translate([0,0,2*cube_height])
rotate(90,[0,1,0])
union(){
// one row of four cubes
row_assembly();
// another row of four cubes
translate([0,2*cube_height,2*cube_height])
rotate(-90,[1,0,0])
mirror([0,0,1])
mirror([1,0,0])
row_assembly();
}
//////////////////////////////////////////////////////
// MODULES ///////////////////////////////////////////
// one row of the assembly
module row_assembly(){
union(){
color("blue")
hinged_cube(180,[1,0,0],[1,0,0]);
color("red")
translate([-cube_height/2,cube_height/2,0])
mirror([0,1,0])
translate([-cube_height/2,cube_height/2,0])
rotate(90,[1,0,0])
hinged_cube(0,[1,0,0],[0,0,0]);
color("green")
translate([cube_height,cube_height/2,cube_height/2])
rotate(-90,[0,1,0])
rotate(180,[1,0,0])
mirror([0,1,0])
translate([-cube_height/2,cube_height/2,0])
rotate(90,[1,0,0])
hinged_cube(180,[0,1,0],[0,1,0]);
color("yellow")
translate([-cube_height,cube_height,cube_height])
rotate(-90,[1,0,0])
rotate(90,[0,0,1])
rotate(-90,[1,0,0])
hinged_cube(0,[1,0,0],[0,0,0]);
}
}
// one cube to rule them all
module hinged_cube(the_angle,the_vector,the_mirror){
difference(){
// cube and cylinders to start
union(){
// cube with inside top and bottom cylinders carved out
difference(){
// start with clearance cube in corner
translate([cube_height/2,cube_height/2,cube_height/2])
rotate(the_angle,the_vector)
mirror(the_mirror)
rounded_cube([cube_height,cube_height,cube_height]);
// take away inside top cylinder with clearance
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height+inside_height])
cylinder( h=outside_height+fudge,
r1=hinge_radius+fudge+hinge_clearance,
r2=hinge_radius+fudge+hinge_clearance);
// take away inside bottom cylinder with clearance
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance-fudge])
cylinder( h=outside_height+fudge,
r1=hinge_radius+fudge+hinge_clearance,
r2=hinge_radius+fudge+hinge_clearance);
}
// top cylinder on outside hinge
translate([0,0,stacking_clearance+outside_height+inside_height+hinge_clearance])
cylinder( h=outside_height-hinge_clearance-corner_radius/2,
r1=hinge_radius,
r2=hinge_radius);
// bottom cylinder on outside hinge
translate([0,0,stacking_clearance+corner_radius/2])
cylinder( h=outside_height-hinge_clearance-corner_radius/2,
r1=hinge_radius,
r2=hinge_radius);
// inside hinge cylinder
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height])
cylinder( h=inside_height,
r1=hinge_radius,
r2=hinge_radius);
// attacher for inside hinge cylinder
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height])
rotate(45,[0,0,1])
translate([-.8*hinge_radius,0,0])
cube([1.6*hinge_radius,2*hinge_radius,inside_height]);
// inside hinge top cone
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height+inside_height])
cylinder( h=cone_height,
r1=hinge_radius,
r2=0);
// inside hinge bottom cone
translate([cube_height,0,0])
rotate(90,[0,0,1])
rotate(90,[0,1,0])
translate([0,0,stacking_clearance+outside_height-cone_height])
cylinder( h=cone_height,
r1=0,
r2=hinge_radius);
}
// take away middle cylinder with clearance
translate([0,0,stacking_clearance+outside_height-hinge_clearance-fudge])
cylinder( h=inside_height+2*hinge_clearance+2*fudge,
r1=hinge_radius+fudge+hinge_clearance,
r2=hinge_radius+fudge+hinge_clearance);
// take away top cone with clearance
translate([0,0,stacking_clearance+outside_height+inside_height+hinge_clearance-fudge])
cylinder(h=cone_height, r1=hinge_radius, r2=0);
// take away bottom cone with clearance
translate([0,0,stacking_clearance+outside_height-cone_height-hinge_clearance+fudge])
cylinder(h=cone_height, r1=0, r2=hinge_radius);
}
}
// module for making rounded cubes from convex hull of corners
module rounded_cube() {
dist = cube_height/2-corner_radius-stacking_clearance;
hull() {
// seven of the eight vertices of a cube
translate([dist,dist,dist])
sphere(r=corner_radius);
translate([-dist,dist,dist])
sphere(r=corner_radius);
translate([dist,-dist,dist])
sphere(r=corner_radius);
translate([-dist,-dist,dist])
sphere(r=corner_radius);
translate([dist,dist,-dist])
sphere(r=corner_radius);
translate([dist,-dist,-dist])
sphere(r=corner_radius);
translate([-dist,-dist,-dist])
sphere(r=corner_radius);
// don't include the eighth if snub desired
if (snub=="yes"){
}
else{
translate([-dist,dist,-dist])
sphere(r=corner_radius);
}
}
}
UPDATE: Featured on 1/29/2014 as Thing-of-the-Day by AlexHuff at 3dideaform.com.
UPDATE: The print-in-place fidget cube made an appearance on the Adafruit blog with a comment from emmet himself (original creator of the printable snap-together fidget cube):
Guest Curator Emmett Lalish has this to say about this 3DxMechanicals project: “This is why I love Thingiverse: I post a snap-assemble design, then someone figures out how to print it pre-assembled. It definitely pushes the boundaries of what’s printable and how the slicers work. This is how we push the technology forward.”UPDATE: From this post by Kevin Osborn on the Ultimaker forum, I learned that you can pick up prints of my fidget cubes at the MakerBot retail store!
Subscribe to:
Posts (Atom)