Quilting Circle Template: Why I Loves Me My 3D Printer(s)

Mary just started an ambitious pieced quilt that requires 50-some-odd precisely sized 1-1/2 inch circles, with marks to locate a 1 inch circle in the middle. She started using a drafting template to mark the smaller circle on freezer paper (don’t ask, it’s complicated), but we couldn’t find the template I know I have with the larger circles.

[Update: It’s a Bittersweet Briar traditional quilt. See all those little dots-for-berries?]

So I says to my wife, I sez, “Hey, we have the technology. What would really simplify what you’re doing?” After a bit of doodling, we came up with a ring having the proper ID and OD, plus a flat handle of some sort.

Half an hour later, I had a solid model:

An hour after that I handed her a warm piece of plastic:

The bottom ring is exactly 1-1/2 inch OD, 1 inch ID, and thin enough to draw around. The handle keeps her fingers out of the way and even has grips and a hole for a string.

The print quality near the hole isn’t as good as I’d like, because the slicer turned that entire volume into a solid slab of plastic. I can fix that in the second version, but right now she has something to work with, evaluate, and figure out what would improve it.

3D printing isn’t for everybody, but it’s a vital part of my shop!

The OpenSCAD source code has parameters for everything, so we can crank out more templates without fuss:

```// Quilting - Circle Template
// Ed Nisley KE4ZNU - July 2013

Layout = "Show";                    // Show Build Circle Handle

//-------
//- Extrusion parameters must match reality!
//  Print with 2 shells

HoleFinagle = 0.2;
HoleFudge = 1.00;

function HoleAdjust(Diameter) = HoleFudge*Diameter + HoleFinagle;

Protrusion = 0.1;           // make holes end cleanly

function IntegerMultiple(Size,Unit) = Unit * ceil(Size / Unit);
function IntegerMultipleMin(Size,Unit) = Unit * floor(Size / Unit);

inch = 25.4;

//-------
// Dimensions

CircleID = (1) * inch;

SeamAllowance = (1/4) * inch;

CircleOD = CircleID + 2*SeamAllowance;

CircleSides = 12*4;

HandleHeight = (2) * inch;
HandleSides = 12*4;

StringDia = 4.0;
StringSides = 8;
StringHeight = 0.75*HandleHeight;

DentDepth = HandleThick/4;
DentDia = 15.0;

//-------

module PolyCyl(Dia,Height,ForceSides=0) {           // based on nophead's polyholes
Sides = (ForceSides != 0) ? ForceSides : (ceil(Dia) + 2);
FixDia = Dia / cos(180/Sides);
}

module ShowPegGrid(Space = 10.0,Size = 1.0) {

RangeX = floor(100 / Space);
RangeY = floor(125 / Space);

for (x=[-RangeX:RangeX])
for (y=[-RangeY:RangeY])
translate([x*Space,y*Space,Size/2])
%cube(Size,center=true);

}

//-------
// Circle ring plate

module CircleRing() {

rotate(180/CircleSides)
difference() {
cylinder(r=CircleOD/2,h=CircleThick,\$fn=CircleSides);
translate([0,0,-Protrusion])
cylinder(r=CircleID/2,h=(CircleThick + 2*Protrusion),\$fn=CircleSides);
}
}

//-------
// Handle

module Handle() {

difference() {
rotate([0,90,0])
scale([HandleHeight/(CircleOD/2),0.9,1])
rotate(180/HandleSides)
cylinder(r=CircleOD/2,h=HandleThick,center=true,\$fn=HandleSides);
translate([0,0,-HandleHeight])
cube([2*CircleOD,2*CircleOD,2*HandleHeight],center=true);
translate([-HandleThick,0,StringHeight])
rotate([0,90,0])
rotate(180/StringSides)
PolyCyl(StringDia,2*HandleThick,StringSides);
#		for (i=[-1,1]) {
}
}

}

module Template() {
CircleRing();
Handle();
}

//-------
// Build it!

ShowPegGrid();

if (Layout == "Circle")
CircleRing();

if (Layout == "Handle")
Handle();

if (Layout == "Show")
Template();
```