# Archive for October 21st, 2011

### Zombie Apocalypse Preparations

Posted by Ed in Machine Shop on 2011-10-21

When in doubt, nuke ’em from orbit. It’s the only way to be sure:

When confronted with a zombie horde, though, nothing exceeds like excess:

In real life, they’re 12 gram CO_{2} capsules, of the type used in tire inflators and air pistols. I knew I’d find something to do with the box of empties I’d been accumulating: they became (somewhat threatening) tchotchkes. This was inspired by that thing, although that STL file doesn’t render into anything and, as with many interesting Thingiverse things, there’s no source code.

These fins were an exercise in thin-wall printing: the outer square is one thread thick, the diagonal struts are two threads, and the ring around the nozzle has just a touch of fill inside, with a one-thread-thick base below the cartridge nozzle:

The solid model looks about like you’d expect:

The teeny little quarter-cylinders in the corners encourage Skeinforge to do the right thing: build each quadrant in one pass, leaving the corners unfinished. The diagonals must be exactly two threads wide to make that possible: each strut thread connects to the corresponding single-thread outer edge.

Now that I’m trying to be a subtractive kind of guy, that’s actually a fin block:

Minus the CO_{2} cartridge that should fit inside:

It turns out that my box has several different types of CO_{2} cartridges and the nozzle ends are all different. To get it right, there’s a template for matching the curves:

That end of the cartridge consists of a cylinder for the body, a sphere mated to a tangential conic section, another conic fillet, and then the cylindrical nozzle. Basically, you twiddle with the parameters until the template comes pretty close to fitting, then fire off a few trial fins until it comes out right.

They were a big hit at the Long Island Linux Users Group meeting…

The OpenSCAD source code:

// CO2 capsule tail fins // Ed Nisley KE4ZNU - Oct 2011 Layout = "Show"; // Show Build FinBlock Cartridge Fit include //------- //- Extrusion parameters must match reality! // Print with +0 shells and 3 solid layers ThreadThick = 0.33; ThreadWidth = 2.0 * ThreadThick; HoleWindage = 0.2; Protrusion = 0.1; // make holes end cleanly function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit); //------- // Capsule dimensions BodyDia = 18.70; BodyRad = BodyDia/2; BodyLength = 53.0; // between hemispherical endcap centers BodyBaseLength = 21; // tip to endcap center TipDia = 7.40; TipRad = TipDia/2; TipLength = IntegerMultiple(4.0,ThreadThick); FilletLength = 5.0; // fillet between tip and cone FilletTop = TipLength + FilletLength; FilletBaseDia = 8.60; FilletBaseRad= FilletBaseDia/2; FilletTopDia = 9.5; FilletTopRad = FilletTopDia/2; ConeTop = 16.0; // tip to tangent with endcap ConeLength = ConeTop - FilletTop; echo(str("Cone Length: ",ConeLength)); IntersectZ = ConeTop; // coordinates of intersect tangent IntersectX = sqrt(pow(BodyRad,2) - pow(BodyBaseLength - ConeTop,2)); echo(str("IntersectZ: ",IntersectZ)); echo(str("IntersectX: ",IntersectX," dia: ",2*IntersectX)); //------- // Fin dimensions FinThick = 1*ThreadWidth; // outer square StrutThick = 2*FinThick; // diagonal struts FinSquare = 24.0; FinTaperLength = sqrt(2)*FinSquare/2 - sqrt(2)*FinThick - ThreadWidth; FinBaseLength = 2*TipLength; //------- module PolyCyl(Dia,Height,ForceSides=0) { // based on nophead's polyholes Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2); FixDia = Dia / cos(180/Sides); cylinder(r=(FixDia + HoleWindage)/2,h=Height,$fn=Sides); } module ShowPegGrid(Space = 10.0,Size = 1.0) { Range = floor(50 / Space); for (x=[-Range:Range]) for (y=[-Range:Range]) translate([x*Space,y*Space,Size/2]) %cube(Size,center=true); } //------- // CO2 cartridge outline module Cartridge() { $fn = 48; union() { translate([0,0,BodyBaseLength]) { cylinder(r=BodyDia/2,h=BodyLength); translate([0,0,BodyLength]) sphere(r=BodyRad); } intersection() { translate([0,0,BodyBaseLength]) sphere(r=BodyRad); union() { translate([0,0,(TipLength + FilletLength+ConeLength)]) cylinder(r=BodyRad,h=(BodyBaseLength - ConeLength)); translate([0,0,(TipLength + FilletLength)]) cylinder(r1=FilletTopRad,r2=IntersectX,h=(ConeLength + Protrusion)); translate([0,0,TipLength]) cylinder(r1=FilletBaseRad,r2=FilletTopRad,h=(FilletLength + Protrusion)); } } translate([0,0,FilletTop]) cylinder(r1=FilletTopRad,r2=IntersectX,h=ConeLength); translate([0,0,TipLength]) cylinder(r1=FilletBaseRad,r2=FilletTopRad,h=(FilletLength + Protrusion)); translate([0,0,-Protrusion]) PolyCyl(TipDia,(TipLength + 2*Protrusion)); } } //------- // Diagonal fin strut module FinStrut() { rotate([90,0,45]) translate([0,0,-StrutThick/2]) linear_extrude(height=StrutThick) polygon(points=[ [0,0], [FinTaperLength,0], [FinTaperLength,FinBaseLength], [0,(FinBaseLength + FinTaperLength)] ]); } //------- // Fin outline module FinBlock() { union() { translate([0,0,FinBaseLength/2]) difference() { cube([FinSquare,FinSquare,FinBaseLength],center=true); difference() { cube([(FinSquare - 2*FinThick), (FinSquare - 2*FinThick), (FinBaseLength + 2*Protrusion)],center=true); for (Index = [0:3]) rotate(Index*90) translate([(FinSquare/2 - FinThick),(FinSquare/2 - FinThick),0]) cylinder(r=StrutThick,h=(FinBaseLength + 2*Protrusion),center=true,$fn=16); } } for (Index = [0:3]) rotate(Index*90) FinStrut(); cylinder(r=IntegerMultiple((FilletBaseRad + StrutThick),ThreadWidth),h=TipLength); } } //------- // Fins module FinAssembly() { difference() { FinBlock(); translate([0,0,ThreadThick]) // add one layer to close base cylinder Cartridge(); } } module FinFit() { translate([0,0.75*BodyBaseLength,2*ThreadThick]) rotate([90,0,0]) difference() { translate([-FinSquare/2,-2*ThreadThick,0]) cube([IntegerMultiple(FinSquare,ThreadWidth), 4*ThreadThick, 1.5*BodyBaseLength]); translate([0,0,5*ThreadWidth]) Cartridge(); } } //------- // Build it! ShowPegGrid(); if (Layout == "FinBlock") FinBlock(); if (Layout == "Cartridge") Cartridge(); if (Layout == "Show") { FinAssembly(); color(LG) Cartridge(); } if (Layout == "Fit") FinFit(); if (Layout == "Build") FinAssembly();

The original doodles:

## Blowback