diff --git a/host/config.json b/host/config.json
index 565ee1f03e1a11cdf61c302b6a680c80234b165c..bd635ae82d2dcc8038f99edf5778855305314cda 100644
--- a/host/config.json
+++ b/host/config.json
@@ -6,7 +6,9 @@
     "yes_no": "img/yes_no.png",
     "3": "img/3.png",
     "2": "img/2.png",
-    "1": "img/1.png"
+    "1": "img/1.png",
+    "processing": "img/processing.png",
+    "plotting": "img/plotting.png"
   },
   "ports": {
     "solenoid": "4150325537323119",
diff --git a/host/filtering.py b/host/filtering.py
index 5c7ce0bdf151370b205a92e625082285e7a778ea..ae58e3b5e82c239b109b4d4078f1176db8d82341 100644
--- a/host/filtering.py
+++ b/host/filtering.py
@@ -26,8 +26,7 @@ def bf(img):
     return edges
 
 
-def stroke(img):
-    img_copy = np.ones_like(img)*255
+def get_polylines(img, min_length=5.0, n_max=200):
     img2 = bf(img)
     img_float = img2.astype(np.float32) / 255.0
     img_binary = img_float > 0.5
@@ -40,13 +39,49 @@ def stroke(img):
         rects = []
         polys = trace_skeleton_old.traceSkeleton(im, 0, 0, im.shape[1], im.shape[0], 10, 999, rects)
 
+    polys = [np.array(x, dtype=np.float32) for x in polys]
+
+    polys_length_keep = []
+    for line in polys:
+        deltas = line[1:] - line[:-1]
+        length = np.sum(np.linalg.norm(deltas, axis=1))
+        if length >= min_length:
+            polys_length_keep.append([line, length])
+
+    polys_length_keep = sorted(polys_length_keep, key=lambda x: x[1])[::-1]
+    polys_length_keep = polys_length_keep[:n_max]
+
+    polys_keep = [x[0] for x in polys_length_keep]
+    return polys_keep
+
+
+def draw_polylines(img, polys):
     for l in polys:
-        # c = (200 * random.random(), 200 * random.random(), 200 * random.random())
         for i in range(0, len(l) - 1):
-            # cv2.line(img_copy, (l[i][0], l[i][1]), (l[i + 1][0], l[i + 1][1]), c)
-            cv2.line(img_copy, (l[i][0], l[i][1]), (l[i + 1][0], l[i + 1][1]), (0, 0, 0))
+            cv2.line(img, (int(l[i][0]), int(l[i][1])), (int(l[i + 1][0]), int(l[i + 1][1])), (0, 0, 0), 2)
+
+
+def scale_offset_polylines(polys, img_w, img_h, mm_w, offset):
+    scale = mm_w / img_w
+
+    polys_new = [np.copy(x) for x in polys]
 
-    return img_copy, polys
+    polys_new = sorted(polys_new, key=lambda x: -x[0, 1])
+
+    for i in range(len(polys)):
+        # flip
+        polys_new[i][:, 1] = img_h - polys_new[i][:, 1]
+        # zero center
+        polys_new[i][:, 0] -= img_w/2
+        polys_new[i][:, 1] -= img_h/2
+        # scale to mm
+        polys_new[i][:, :] *= scale
+
+        # offset
+        polys_new[i][:, 0] += offset[0]
+        polys_new[i][:, 1] += offset[1]
+
+    return polys_new
 
 
 if __name__ == "__main__":
@@ -59,10 +94,30 @@ if __name__ == "__main__":
     #     plt.plot(cnt[:, 0], cnt[:, 1])
     # plt.show()
     # # print(contours[0])
-    img = cv2.imread("test.png", cv2.IMREAD_UNCHANGED)
+    img = cv2.imread("test/test.png", cv2.IMREAD_UNCHANGED)
     img = img[:, :, :3]
+    h, w, _ = img.shape
     # img_copy = np.copy(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))*0
-    img_stroke, polys = stroke(img)
+    polys = get_polylines(img)
+    img_draw = 255*np.ones((h, w, 3), dtype=np.uint8)
+    draw_polylines(img_draw, polys)
+
+    lines = scale_offset_polylines(polys, w, h, 100, (130, 118))
+
+    import matplotlib.pyplot as plt
+
+    plt.figure()
+    plt.imshow(img_draw)
+
+    plt.figure()
+    for xy in lines:
+        plt.plot(xy[:, 0], xy[:, 1])
+    plt.axis("equal")
+    plt.show()
+
+    # import pickle
+    # with open("test/polys.obj", "wb") as f:
+    #     pickle.dump(polys, f)
 
-    cv2.imshow("test", img_stroke)
-    cv2.waitKey(0)
+    # cv2.imshow("test", img_stroke)
+    # cv2.waitKey(0)
diff --git a/host/img/plotting.png b/host/img/plotting.png
new file mode 100644
index 0000000000000000000000000000000000000000..5583954622eb3ca7568c7dd379a9add5f29aea5a
Binary files /dev/null and b/host/img/plotting.png differ
diff --git a/host/img/processing.png b/host/img/processing.png
new file mode 100644
index 0000000000000000000000000000000000000000..cc633c34cfda44a3f52f8e322be2c96e1d8d944f
Binary files /dev/null and b/host/img/processing.png differ
diff --git a/host/machine.py b/host/machine.py
index b39c3d0e0922c6ad59d1c60dd2aa7b654c79c49f..63ca139444ddab7ffddc95967cbcc51c62b096a1 100644
--- a/host/machine.py
+++ b/host/machine.py
@@ -9,7 +9,7 @@ home_rate = 60
 home_accel = 2000
 home_backoff_time = 0.2
 
-go_rate = 150
+go_rate = 180
 go_accel = 2000
 
 use_current = 0.4
@@ -35,25 +35,6 @@ class Machine:
         self.x_top_motor.set_current(use_current)
 
     def home(self):
-        # home Y ....
-        # if we're on the switch, backoff:
-        if self.y_motor.get_states()['limit'] > 0:
-            self.y_motor.set_target_velocity(home_rate, home_accel)
-            time.sleep(home_backoff_time)
-            self.y_motor.set_target_velocity(0, home_accel)
-            time.sleep(home_backoff_time)
-
-        # let's home it,
-        self.y_motor.set_target_velocity(-home_rate, home_accel)
-
-        # then check-wait on states,
-        while True:
-            states = self.y_motor.get_states()
-            if states['limit'] > 0:
-                break
-
-        self.y_motor.set_target_velocity(0, home_accel)
-
         # home X ...
         if self.x_bottom_motor.get_states()['limit'] > 0:
             self.x_bottom_motor.set_target_velocity(home_rate, home_accel)
@@ -75,6 +56,25 @@ class Machine:
         self.x_top_motor.set_target_velocity(0, home_accel)
         time.sleep(home_backoff_time)
 
+        # home Y ....
+        # if we're on the switch, backoff:
+        if self.y_motor.get_states()['limit'] > 0:
+            self.y_motor.set_target_velocity(home_rate, home_accel)
+            time.sleep(home_backoff_time)
+            self.y_motor.set_target_velocity(0, home_accel)
+            time.sleep(home_backoff_time)
+
+        # let's home it,
+        self.y_motor.set_target_velocity(-home_rate, home_accel)
+
+        # then check-wait on states,
+        while True:
+            states = self.y_motor.get_states()
+            if states['limit'] > 0:
+                break
+
+        self.y_motor.set_target_velocity(0, home_accel)
+
         # set zeroes,
         self.x_bottom_motor.set_position(0)
         self.x_top_motor.set_position(0)
@@ -128,15 +128,34 @@ if __name__ == "__main__":
     m.goto(0, origin[1])
     m.goto(origin[0], origin[1])
 
-    w = 25
-    h = 25
+    # w = 35
+    # h = 35
+    #
+    # m.goto(origin[0]+w, origin[1]+h)
+    # m.pen_action(2, True)
+    # m.goto(origin[0]-w, origin[1]+h)
+    # m.goto(origin[0]-w, origin[1]-h)
+    # m.goto(origin[0]+w, origin[1]-h)
+    # m.goto(origin[0]+w, origin[1]+h)
+    # m.pen_action(2, False)
+    # m.goto(0, origin[1])
+    # m.goto(0, 0)
+
+    import pickle
+
+    with open("test/polys_np_keep.obj", "rb") as f:
+        data = pickle.load(f)
+
+    for line, _ in data:
+        m.goto(line[0, 0], line[0, 1])
+        m.pen_action(2, True)
+        m.goto_list(line[:, 0], line[:, 1])
+        m.pen_action(2, False)
+        # for x, y in line:
+        #     print(x, y)
 
-    m.goto(origin[0]+w, origin[1]+h)
-    m.pen_action(2, True)
-    m.goto(origin[0]-w, origin[1]+h)
-    m.goto(origin[0]-w, origin[1]-h)
-    m.goto(origin[0]+w, origin[1]-h)
-    m.goto(origin[0]+w, origin[1]+h)
-    m.pen_action(2, False)
+    m.goto(origin[0], origin[1])
     m.goto(0, origin[1])
     m.goto(0, 0)
+
+    # print(data)
diff --git a/host/main.py b/host/main.py
index 757d68719395764120855f7a8f809d7b78a459ff..f408f2a1df9fbd93111deea19735fc48dd3f81b1 100644
--- a/host/main.py
+++ b/host/main.py
@@ -5,6 +5,7 @@ import json
 import time
 import datetime
 import filtering
+import machine
 
 STATE_INIT = 0
 STATE_STREAM = 1
@@ -30,6 +31,8 @@ class MainApplication:
         self.rotate = rotate
         self.t_state = 0
         self.dt_state = 0
+        self.strokes = None
+        self.machine = None
         cv2.imshow("main", self.img)
         cv2.setMouseCallback("main", self.on_click)
 
@@ -97,11 +100,46 @@ class MainApplication:
                     else:
                         self.state = STATE_STREAM
         elif self.state == STATE_VECTORIZED:
-            img_strokes, strokes = filtering.stroke(self.img_captured)
-
-            self.img = img_strokes
-            self.state = STATE_DRAWING
-            # self.running = False
+            if self.dt_state < 0.5:
+                self.img = np.zeros((self.height, self.width, 3), dtype=np.uint8)
+                overlay = "processing"
+            else:
+                if self.strokes is None:
+                    polys = filtering.get_polylines(self.img_captured)
+                    img_draw = 255 * np.ones((self.height, self.width, 3), dtype=np.uint8)
+                    filtering.draw_polylines(img_draw, polys)
+                    self.strokes = filtering.scale_offset_polylines(polys,
+                                                                    self.width,
+                                                                    self.height,
+                                                                    100,
+                                                                    machine.origin)
+                    self.img = np.copy(img_draw)
+                overlay = "yes_no"
+                if self.click is not None:
+                    x, y = self.click
+                    self.click = None
+                    if x < self.width // 2:
+                        self.state = STATE_DRAWING
+                    else:
+                        self.state = STATE_STREAM
+        elif self.state == STATE_DRAWING:
+            if self.dt_state < 0.5:
+                self.img = np.zeros((self.height, self.width, 3), np.uint8)
+                overlay = "plotting"
+            else:
+                if self.strokes is not None and self.machine is not None:
+                    self.machine.goto(0, machine.origin[1])
+                    self.machine.goto(machine.origin[0], machine.origin[1])
+                    for line in self.strokes:
+                        self.machine.goto(line[0, 0], line[0, 1])
+                        self.machine.pen_action(2, True)
+                        self.machine.goto_list(line[:, 0], line[:, 1])
+                        self.machine.pen_action(2, False)
+                    self.machine.goto(machine.origin[0], machine.origin[1])
+                    self.machine.goto(0, machine.origin[1])
+                    self.machine.goto(0, 0)
+                self.strokes = None
+                self.state = STATE_STREAM
 
         self.show(overlay=overlay)
         if self.state != previous_state:
@@ -131,7 +169,12 @@ class MainApplication:
 def main():
     with open("config.json", "r") as f:
         config = json.load(f)
+
+    m = machine.Machine(config["ports"])
+    m.pen_action(2, False)
+    m.home()
     app = MainApplication(fullscreen=config["fullscreen"], rotate=config["rotate"])
+    app.machine = m
     app.load_overlays(config["overlays"])
     app.run()
     app.video.release()
@@ -140,3 +183,4 @@ def main():
 
 if __name__ == "__main__":
     main()
++
\ No newline at end of file
diff --git a/host/test/polys.obj b/host/test/polys.obj
new file mode 100644
index 0000000000000000000000000000000000000000..6071ce638da07f83ad167efc0b4be66b6b8ddbcc
Binary files /dev/null and b/host/test/polys.obj differ
diff --git a/host/test/polys_np_keep.obj b/host/test/polys_np_keep.obj
new file mode 100644
index 0000000000000000000000000000000000000000..5b96882813f09081c65cfe2ec4e9b5378595c84f
Binary files /dev/null and b/host/test/polys_np_keep.obj differ
diff --git a/host/test.png b/host/test/test.png
similarity index 100%
rename from host/test.png
rename to host/test/test.png
diff --git a/host/test/test_prune.py b/host/test/test_prune.py
new file mode 100644
index 0000000000000000000000000000000000000000..2be1e607b1a3c01c99c2d72ef5a71ae30a9fb68d
--- /dev/null
+++ b/host/test/test_prune.py
@@ -0,0 +1,104 @@
+import pickle
+import cv2
+import numpy as np
+import matplotlib.pyplot as plt
+
+
+def process_polylines(polylines, img_w, img_h, mm_w, offset):
+    polys_np_keep = []
+    for line in polylines:
+        deltas = line[1:] - line[:-1]
+        length = np.sum(np.linalg.norm(deltas, axis=1))
+        if length > 5.0:
+            polys_np_keep.append([line, length])
+
+    polys_np_keep = sorted(polys_np_keep, key=lambda x : x[1])[::-1]
+
+    n_max = 200
+
+    scale = mm_w / img_w
+
+    polys_np_keep = polys_np_keep[:n_max]
+
+    for i in range(len(polys_np_keep)):
+        # flip
+        polys_np_keep[i][0][:, 1] = img_h - polys_np_keep[i][0][:, 1]
+        # zero center
+        polys_np_keep[i][0][:, 0] -= img_w/2
+        polys_np_keep[i][0][:, 1] -= img_h/2
+        # scale to mm
+        polys_np_keep[i][0][:, :] *= scale
+        polys_np_keep[i][1] *= scale
+
+        # offset
+        polys_np_keep[i][0][:, 0] += offset[0]
+        polys_np_keep[i][0][:, 1] += offset[1]
+
+    return polys_np_keep
+
+"""
+def main():
+    with open("polys.obj", "rb") as f:
+        polys = pickle.load(f)
+
+    img = cv2.imread("test.png", cv2.IMREAD_UNCHANGED)
+    polys_np = [np.array(x, dtype=np.float32) for x in polys]
+    print(polys_np[0].shape)
+    polys_np_keep = []
+    # lengths = []
+    for line in polys_np:
+        deltas = line[1:] - line[:-1]
+        length = np.sum(np.linalg.norm(deltas, axis=1))
+        if length > 5.0:
+            polys_np_keep.append([line, length])
+
+    polys_np_keep = sorted(polys_np_keep, key=lambda x : x[1])[::-1]
+
+    n_max = 200
+
+    polys_np_keep = polys_np_keep[:n_max]
+
+    h, w, _ = img.shape
+    # for line in
+
+    print(w, h)
+
+    # mm per px
+    scale = 100 / w
+    offset = (130, 118)
+    # offset = (0, 0)
+
+    for i in range(len(polys_np_keep)):
+        # flip
+        polys_np_keep[i][0][:, 1] = h - polys_np_keep[i][0][:, 1]
+        # zero center
+        polys_np_keep[i][0][:, 0] -= w/2
+        polys_np_keep[i][0][:, 1] -= h/2
+        # scale to mm
+        polys_np_keep[i][0][:, :] *= scale
+        polys_np_keep[i][1] *= scale
+
+        # offset
+        polys_np_keep[i][0][:, 0] += offset[0]
+        polys_np_keep[i][0][:, 1] += offset[1]
+
+    # for line, length in polys_np_keep:
+    #     plt.plot(line[:, 0], -line[:, 1])
+    #
+    # # print(polys_np_keep[:50])
+    plt.figure()
+    for line, _ in polys_np_keep:
+        plt.plot(line[:, 0], line[:, 1])
+    # plt.hist(lengths, bins=np.linspace(0, 160, 64))
+    plt.axis("equal")
+    plt.show()
+
+    polys_np_keep = sorted(polys_np_keep, key=lambda x: x[0][0, 1])
+
+    with open("polys_np_keep.obj", "wb") as f:
+        pickle.dump(polys_np_keep, f)
+"""
+
+
+# if __name__ == "__main__":
+#     main()