tracing is one of the earliest forms of computer arts, a good read if you’ve never heard of it via retweeted by BitcraftLab. the more recent takes, with bigger formats and the use of colors always strike me with the complexity of their patterns and yet plotters use the simplest tools available: points, lines and curves. there are so many things to say about this topic but that’s way beyond the scope of this humble article. what I like the most is that, as opposed to a printer which will output a clean snapshot of a sketch, a plotter will make (lots of) mistakes.
last december I saw Anders Hoff having bags of fun with his plotter and two weeks ago the XY plotter 2.0 arrived. I’m probably the clumsiest handyman on the face of the earth, yet after 10 hours (over 3 days), I managed to mount it. later, I found this carefully documented step by step tutorial, it would have helped.
some things I did to make my life easier
- lower the servo by a good centimeter to use regular pens or brushes ; by default they are quickly blocked by the beam
- use one of the 30*4 screws & a bolt at the end of the lever and tie the elastic on this rather than the default setting ; the pen needs to be pressed on the paper and by default, the elastic’s tension is to weak
- replace the 30*4 screws by 60*4 screws as it allows bigger pens to fit
- use a 50*50*3cm wooden frame and a linoleum surface. I attached the plotter to the frame to provides better stability as the plotter may move a bit during fast or frequent moves. linoleum is flat, waterproof, easy to clean up and good to stick or move crepe tape (something you should use if you don’t want to tear off the paper when you remove it) but more importantly the linoleum damps the “pen down” move, when plotting big sketches this noise becomes extremely bothering.
on a side note, the cables from the board to the pen are short, they can’t reach the top left corner (x=0, y=1) I should change them to use the whole surface.
then I tried to trace something and it worked! it was properly calibrated and just worked.
unfortunately, the available software are rather limited ; mDraw is a generic purpose tool: you have to place the sketch manually, on import, it resizes every sketch to a 15*15 cm representation, it’s possible to set the width and height yet no way to set the X/Y coordinates which is really irritating (if you want 2 or more colors, it’s a no go). well at least it properly uploads the firmware to the arduino board and gets you started quickly.
there is a second software called BenBox, more of “technical” thing, I couldn’t get it to work (Win 10) even though I tried to install & run each and every version I could get my hands on.
the third option is to use Processing but then again the demo won’t work for some reason (controls won’t show once connected) and the code on the repo is pretty cryptic for a beginner like me. I gave up after 4 hours of struggle but I should really try harder and make some sense of all this, especially the GCode bit that seems to be well supported. some leads: lead 1 , lead 2, lead 3, lead 4
the last option is to use Python and send the CNC formatted instructions directly to the board, let’s call it the advanced approach (probably the most efficient).
after the first tests, I tried to print something more complex and used the result of the MST from the previous article.
the sketch is made of 23714 edges, it’s a very tricky subject as there are numerous small elements.
little did I know how much time it would take (hint: loooooooong ), which, after years spent working in (near) real-time graphics, was a bit unsettling.
after 15 hours of work, the plotter had not even reached 10% of the total task. this is because strokes can be traced in a random order ; it doesn’t matter if we start at the top, the bottom, or the center. each time the plotter moves the pen to trace the next segment, it’ll take some time (roughly 50px/second with the default settings), then it’ll take some time again to draw the line. the servo moves pretty fast so the pen up/down move’s duration is negligible.
to help visualize what happens, I painted the unordered segments with a hsl mode where the hue corresponds to their position in the array to the left and a single semi transparent polyline that goes through all the edges’ centers (click for larger pics).
we can clearly see that the edges are almost randomly distributed, so the plotter will have to do the series of moveTo (to the right) + all the moveTos/lineTos described by the segments (to the left) to finish the work. the length of the grey polyline is ~9.569.766 pixels. if we don’t resize the sketch and if the plotter moves at a speed of 50px/s it means it would take 43h for the plotter to simply move over the drawing.
if we want to plot something even fairly simple in a reasonable amount of time, we need to find a way to sort the line segments. below is the same graph with vertices sorted on the horizontal axis.
the length of the path between all segments’ centers is now ~6.674.923 px which is 66%of the original, so far so good ( + the “victorian veiled widow” comes for free)
let’s try with a polar sort (sorting by angle to the center):
a ~2.208.824 px long polyline, 20% of the original work time!
in fact this boils down to finding the shortest path between edges ; this is a very famous problem in graph theory that usually goes by the name of Traveling Salesman Problem or TSP. there are various ways to address it, often involving neural networks or genetic algorithm (I believe the latter is more robust) but there’s another approach called Simulated Annealing that mimics the way atomic structure reorganizes itself in a medium as its temperature lowers. I had a take at the algorithm in actionscript a while back, and tried to apply this to find the shortest path. if it is very slow to obtain decent shortest path, it is relatively fast to obtain a coarse shortest path, here’s a codepen (click to reset).
so I split the polar sorted segment set into bins of 500 vertices and applied the TSP on each bin, it looked like this:
the total length of all the bins using a coarse TSP was ~79.446 px, roughly 3.6% of the polar sorted version and ~0.7% of the original ; theoretically ~30 minutes to move the pen around. this doesn’t take the actual drawing into account but it’s already much better.
you can clearly see the clockwise progression of the plot and the point at which it decided to stipple rather than draw lines. this is because I thought it would be clever to use a contraption of my own, namely 2 springs pushing the caret against the lever to pinch the pen ; my plan was to allow a simpler pen swap. this – of course – induced mechanical float so after hitting the board 2500 times, the pen went (╯°□°)╯︵ ┻━┻
most strokes in this sketch have a length equal to or shorter than 1 mm, if there is mechanical float, it won’t work ; the pen will go down, the plotter will move it in a given direction but not enough to compensate the float so the pen will remain stuck. during the plot, I locked the pen firmly and added an extra elastic to maintain it on the surface of the paper. from “noon” to nine, the drawing worked nicely and only took ~5h30, as compared to the first attempt it was a brilliant failure.
I believe the way the svg is formatted is important too ; in some previous attempts, I described each stroke as a <path> element resulting in a 2.5+ Mo files. here I turned coordinates into ints and packed each TSP bin as a path element, the file became 450 Ko and the plotter seemed happier about it.
there are still things that I don’t understand ; for instance this “hulled clusters” version of the mesh took roughly 20 minutes to plot for a 25 cm high drawing (which is big for the max surface is 31*38 cm).
to improve the render time, we can group series of consecutive segments into a path, minimize the moveTos, simplify the paths, use SVG’s built-in shapes ; for instance this series of shapes uses straight lines and quadratic curves (this is 2D btw).
the Curve SVG instruction is much faster than tracing the same with a series of segments but at the end of the day, a complex shape will take more time than a simple shape…
now as I mentioned Andreas at the beginning of the article, I had to try this shape! (I don’t know how it’s called for realz, I called it Growth, it’s a recursively subdividing polyline)
and TADA! (15*15cm)
what about pointillism?
dots have a lot in common with particles, you need lots of them to get something visually interesting. fortunately, computers like to compute and plotters like to plot so with a proper sorting method, sky is the limit (well not exactly but you get the idea). there are techniques I’d like to explore, the first is the stippling, the second is the dithering, both can lead to better dots distributions and allow optical grayscale (shades of grey by means of dots densities). dithering can lead to photorealistic representations and can be performed on the GPU. I’ll write about it if/when I manage to get it to work. for now, I’ll leave you with this zebra-striped giraffe
one sure thing is that I’ve never been so excitedly happy with any device for the past 10 years :)
also I’ve posted some intermediate renders/bugs here