Cutting
1 Vinyl: Star Key Sticker
For the vinyl-cutting project, I made a sticker out of an svg drawing of an ornate key inset with a star.
Printing was straightforward. The only two roadblocks were ensuring that the svg units were appropriately scaled (this wasn't an issue for the rasterized graphics I had seen demonstrated before), and ensuring that the printer head was down in order to begin cutting.
2 Cardboard: Toothed Polygons
Moving on to the laser cutter, I first wrote a parametric comb program which generated teeth of various widths, so that I could find the most snug fit for the cardboard in question (and account for kerf).
In the picture shown here, the teeth also have chamfers—a later addition. I added a module for drop-in replacements of square teeth with chamfered teeth. I experimented with various designs for the chamfer (e.g. specifying the angle and length of the chamfer versus specifying its rectangular dimensions) and had the best success when setting its rectangular dimensions.
comb_thickness = 2.54*1; comb_width = 2.54 * 60; comb_height = 2.54 * 6; teeth_height = comb_height*0.4; teeth_start = 2; teeth_end = 5; teeth_gap = 10; num_teeth = 10; module chamfer_slot( box_width, box_height, slot_width, slot_height, chamfer_padding, chamfer_height) { union() { square(size=[slot_width,slot_height], center=true); polygon(points=[ [-chamfer_padding/2, box_width], // A [+chamfer_padding/2, box_width], // B [+chamfer_padding/2,0], // C [+slot_width/2, -chamfer_height], // D [-slot_width/2, -chamfer_height], //E [-chamfer_padding/2,0], // F ]) /* polygon(points=[ [-slot_width/2, -(slot_height-chamfer_height)/2], [-chamfer_padding/2,slot_height/2], [+chamfer_padding/2,slot_height/2], [+slot_width/2, -(slot_height-chamfer_height)/2]]); */ } } // COMBS IN 2D module tooth_array_2D(num_teeth, teeth_width, dt, offset_x, teeth_gap) { chamfer_padding=0.5; chamfer_height=1; extra = teeth_height; if(num_teeth!=0) { translate([offset_x,0]) polygon(points=[ [-teeth_width/2-chamfer_padding,extra], [-teeth_width/2-chamfer_padding,0], [-teeth_width/2,-chamfer_height], [-teeth_width/2,-teeth_height], [+teeth_width/2,-teeth_height], [+teeth_width/2,-chamfer_height], [+teeth_width/2+chamfer_padding, 0], [+teeth_width/2+chamfer_padding,extra]]); translate([offset_x, -teeth_height-4]) text(size=2,halign="center",str(num_teeth)); // square(size=[teeth_width,teeth_height*2],center=true); tooth_array_2D(num_teeth-1, teeth_width + dt, dt, offset_x + teeth_width + teeth_gap, teeth_gap); } } union() { difference() { translate([comb_width/2,0]) square(size=[comb_width, comb_height], center=true); translate([0,comb_height/2]) tooth_array_2D(num_teeth=22, teeth_width=2, dt=0.08, offset_x=4, teeth_gap=4); } /* translate([0,-comb_height/2]) tooth_array_2D(num_teeth=21, teeth_width=2, dt=0.05, offset_x=4, teeth_gap=4); */ } outer_radius = 10; /* intersection() { difference() { circle(outer_radius); circle(outer_radius*0.7); }*/ square(outer_radius); }
As for the project itself, I envisioned a bunch of regular polygons with different numbers of sides. If you could calculate the appropriate angles, you could make regular polygonal sides that could be fitted together with a straight-edged join.
After some trigonometric calculation, I managed to pull it off:
scale = 2 * 1; rect_width = scale * 32; rect_height = scale * 5; slot_width = scale * 1; slot_height = scale * 1.5 ; chamfer_padding = scale * 0.1; chamfer_height = scale * 0.25; font_size = scale * 2; horizontal_slot_num = 7; horizontal_slot_spacing = slot_width * 1.5 * 2; vertical_slot_spacing = horizontal_slot_spacing/2; vertical_slot_num = 1; vertical_sep_factor = 1.4; disk_num = 5; circular_slot_num = 8; circular_radius = rect_height*0.75; //2.25 * slot_height; module standard_rectangle(center=false) { square(size=[rect_width, rect_height],center=center); } module chamfer( slot_width, slot_height, chamfer_padding, chamfer_height, extra=10, center=false ) { polygon( points = [ [-slot_width/2-chamfer_padding, -extra], [+slot_width/2+chamfer_padding, -extra], [+slot_width/2+chamfer_padding, 0], [+slot_width/2, chamfer_height], [+slot_width/2, slot_height], [-slot_width/2, slot_height], [-slot_width/2, chamfer_height], [-slot_width/2-chamfer_padding, 0], ] ); } module pillar_rectangle(width=rect_width) { difference() { square(size=[width,rect_height],center=true) /* standard_rectangle(true)*/; g=1.16; # translate([width/2-g*horizontal_slot_spacing,0]) color("blue") text(size=font_size,text=str(2),valign="center",halign="center"); # translate([-(width/2-g*horizontal_slot_spacing),0]) rotate([0,0,180]) text(size=font_size,text=str(2),valign="center",halign="center"); // LONG SPINE k = horizontal_slot_num+4; for(angle=[0,180]) { for(i=[0:1: k-1]) { rotate([0,0,angle]) translate([(i-(k-1)/2)*horizontal_slot_spacing,-rect_height/2]) chamfer(slot_width, slot_height, chamfer_padding , chamfer_height); }} // NARROW SPINE for(angle=[90,270]) { for(i=[0:1: vertical_slot_num-1]) { rotate([0,0,angle]) translate([ (i-(vertical_slot_num-1)/2)*vertical_slot_spacing, -width/2,]) chamfer(slot_width, slot_height, chamfer_padding ,chamfer_height); }}} } module polybar(n=5, width=rect_width, height=rect_height, center=false) { polyangle = (n-2)*180/n; flare_width = height / tan(polyangle/2); translate(true ? [-width/2,-height/2] : [0,0]) translate(center ? [width/2,height/2] : [0,0]) difference() { union() { standard_rectangle(true); // TRIANGULAR WEDGES for(j=[-1,1]) { translate([j*width/2,-height/2]) polygon(points=[[0,0],[j*flare_width,0],[0,rect_height]]); } } // ANGLED CHAMFERS translate([width/2+slot_width,0]) rotate([0,0,180-polyangle/2]) translate([0,(7-n)*scale*-0.3]) chamfer(slot_width, slot_height, chamfer_padding, chamfer_height); translate([-width/2-slot_width,0]) rotate([0,0,180+polyangle/2]) translate([0,(7-n)*scale*-0.3]) chamfer(slot_width, slot_height, chamfer_padding, chamfer_height); // TEXT # translate([rect_width/2-horizontal_slot_spacing,0]) text(size=font_size,text=str(n),valign="center",halign="center"); # translate([-(rect_width/2-horizontal_slot_spacing),0]) rotate([0,0,180]) text(size=font_size,text=str(n),valign="center",halign="center"); // LONG SPINE for(angle=[0,180]) { for(i=[0:1: horizontal_slot_num-1]) { rotate([0,0,angle]) translate([(i-(horizontal_slot_num-1)/2)*horizontal_slot_spacing,-rect_height/2]) chamfer(slot_width, slot_height, chamfer_padding , chamfer_height); }} } } module solarium() { difference() { circle(circular_radius); for(i=[1:1:circular_slot_num]) { rotate([0,0,180]) rotate([0,0,i/circular_slot_num*360]) translate([0,-circular_radius]) chamfer(slot_width, slot_height, chamfer_padding , chamfer_height); } # text(size=font_size,text=str(1),valign="center",halign="center"); } } // difference() { // // // #translate([width/2,height/2]) text(size=2,halign="center",valign="center",str(n)); // // translate([slot_width,height/2]) rotate([0,0,90-polyangle/2]) // square(size=[slot_width*2,slot_height],center=true); // // translate([width-slot_width,height/2]) rotate([0,0,90+polyangle/2]) square(size=[slot_width*2,slot_height],center=true); nmin = 3; nmax = 7; pillar_rectangle(width=rect_width+2*rect_height); for(n=[nmin:1:nmax]) { translate([0,(n+1-nmin)*rect_height*vertical_sep_factor]) polybar(center=true, n=n); } translate([0,(2+1-nmin)*rect_height*vertical_sep_factor]) pillar_rectangle(width=rect_width+2*rect_height); translate([0,-1*rect_height*1.5]) for(i=[1:1:disk_num]) { translate([circular_radius*2.25*(i-(disk_num+1)/2),0]) solarium(); } *standard_rectangle(true); /* chamfer(slot_width, slot_height, chamfer_padding,chamfer_height);*/
The result is a suite of different regularly-angled pieces that can be joined to form architectural figures. I even attempted making a joined hexagon-pentagon duo reminiscent of a guanine molecule.