The T-Shirt Plotter

by imoyer@mit.edu

For this project I experimented with computerized plotting on T-shirts using Micron brand drawing pens. To date this has been the most fun thing that I’ve made on my Multifab personal fabricator . I’m starting to think that fashion might be the under-explored killer app for personal fabrication.

A Three-Color-Process Face

Step 1: Start with an Image

Step 2: Decompose into Three Colors

Step 3: Apply Charcoal Filter in Photoshop

Step 4: Convert to Black and White

Step 5: Trace Images and Generate Toolpath using Prof. Gershenfeld’s FAB Modules

Note: I adjusted the tracing parameters so that the green layer appeared dominant with the greatest level of rendering.

Step 6: Load a T-Shirt into the Multifab

Step 7: Load a Pen and Run Toolpath

Step 8: Repeat for Red and Blue

T-Shirt Typing

Algorithmic Generation of Toolpaths: The Dragon Curve


With a color change every 1024 segments:

Several re-draws with different colors:

This toolpath was generated in real-time as it was drawn, using an L-system algorithm called the “Dragon Curve”. I learned about the algorithm from the Wikipedia page on L-Systems. The basic rules to generate the pattern (from the Wikipedia page) are:

Actions: F, +, and -

F: draw forward

+: turn right 90 degrees

-: turn left 90 degrees

Functions: X and Y

X -> X+YF

Y-> FX-Y

Starting Function Call: FX

Because the rules are recursive, the functions can call themselves. I recursed 11 calls deep to generate the first pattern, and 10 calls deep for the second pattern.

The algorithm was written in python, and was run within the Multifab control system to generate motion:

# THIS PROGRAM, DESIGNED TO RUN WITHIN THE VIRTUAL MACHINE ENVIRONMENT,
# DRAWS A DRAGON CURVE ACCORDING TO EXAMPLE 7 OF
# http://en.wikipedia.org/wiki/L-system
# WRITTEN BY ILAN MOYER 4/28/11
# THE RULES:
# X,Y are the variables
# F,+,- are the constants
# FX is the starting condition
# X -> X+YF
# Y -> FX-Y
# F means draw forwards
# – means turn left 90 degrees
# + means turn right 90 degrees
# MACHINE STARTING CONDITIONS
mtm.machine_position = [0.0, 0.0, 0.0]
global traverse_height
global draw_height
global draw_speed
global updown_speed
global itercount
global colorchangecount
traverse_height = 0.05 #units in inches
draw_height = -0.05 #units in inches
draw_speed = 100 #units in inches/min
updown_speed = 10
curve_start_x = 4.5
curve_start_y = 4.5
#TRAVERSE TO STARTING POSITION
mtm.move(0.0, 0.0, traverse_height, updown_speed)
mtm.move(curve_start_x, curve_start_y, traverse_height, draw_speed)
mtm.move(curve_start_x, curve_start_y, draw_height, updown_speed)
#CURVE PARAMETERS
global segment_length
global iterations
segment_length = 0.06 #inches
iterations = 12
#CURVE VARIABLES
global orientation
orientation = 0 # 0 = right, 1 = up, 2 = left, 3 = down
#CHANGE PARAMETERS
itercount = 0
colorchangecount = 1025
#FUNCTIONS
global change_color
def change_color():
global traverse_height
print “CHANGE COLOR NOW!”
mtm.move(mtm.machine_position[0], mtm.machine_position[1], traverse_height, updown_speed)
donothing = raw_input(“HIT ENTER WHEN READY”)
mtm.move(mtm.machine_position[0], mtm.machine_position[1], draw_height, updown_speed)
global rotate_right
def rotate_right():
global orientation
orientation = orientation-1
if orientation == -1:
orientation = 3
global rotate_left
def rotate_left():
global orientation
orientation = orientation +1
if orientation == 4:
orientation = 0
global take_step
def take_step():
global itercount
global change_color
global colorchangecount
itercount = itercount +1
global segment_length
steps = {0:[segment_length, 0], 1:[0, segment_length], 2:[-segment_length, 0], 3:[0, -segment_length]}
current_steps = steps[orientation]
x_pos = mtm.machine_position[0]+float(current_steps[0])
y_pos = mtm.machine_position[1]+float(current_steps[1])
mtm.move(x_pos, y_pos, draw_height, draw_speed)
if itercount == colorchangecount:
itercount = 0
#        change_color()
global x_rule
def x_rule(current_iteration):
global x_rule
global y_rule
global take_step
global iterations
this_iteration = current_iteration+1
if this_iteration>iterations:
return
x_rule(this_iteration)
rotate_right()
y_rule(this_iteration)
take_step()
global y_rule
def y_rule(current_iteration):
global x_rule
global y_rule
global take_step
global iterations
this_iteration = current_iteration+1
if this_iteration>iterations:
return
take_step()
x_rule(this_iteration)
rotate_left()
y_rule(this_iteration)
#STARTING CONDITION
take_step()
x_rule(0)
mtm.move(mtm.machine_position[0], mtm.machine_position[1], traverse_height, updown_speed)
mtm.move(0, 0, traverse_height, draw_speed)
print “ITERATIONS: ” + str(itercount)