Zombie Apocalypse Preparations

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

Finned CO2 Cartridge on build platform
Finned CO2 Cartridge on build platform

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

Finned CO2 Cartridge Array
Finned CO2 Cartridge Array

In real life, they’re 12 gram CO2 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:

Fin Array on build platform
Fin Array on build platform

The solid model looks about like you’d expect:

Fin Assembly- solid model
Fin Assembly- solid model

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:

Fin Block - solid model
Fin Block - solid model

Minus the CO2 cartridge that should fit inside:

CO2 Cartridge - solid model
CO2 Cartridge - solid model

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

Cartridge nozzle template
Cartridge nozzle template

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.

CO2 Capsule Nozzle - solid model detail
CO2 Capsule Nozzle - solid model detail

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:

CO2 Cartridge Fin Doodles
CO2 Cartridge Fin Doodles

7 thoughts on “Zombie Apocalypse Preparations

    1. Somebody at LiLUG suggested that they’d be a great handout for Crosman salesmen: just change the text printed on the cartridge!

      It turns out that the fins don’t stabilize the capsule, though, as demonstrated by some drop tests at the meeting.

  1. I’ve been saving those cartridges too, never sure what I could do with them, but looking too nice to throw away.

    Now I know why I’ve been saving them…..

    1. Perhaps you could ream the nozzles and turn them into JATO bottles for model airplanes. [grin]

      1. I had a plan, at one point, involving two empty cartridges, with the nozzles cleaned up, one clamped to each chainstay pointing backwards, and a bucket of high test peroxide nearby, and some silver mesh… but it’s probably better that the plan never went anywhere.

Comments are closed.