{"word_count": 1949, "character_count": 12179}
Here's some work-in-progress thoughts on modelling tablet weaving.Although our project is primarily concerned with the ups and downs of weaving, we are also interested in the twists of tablet weaving. Woven and tablet woven fabrics have some similarities but also huge differences, but we are interested in when they are combined in the same fabric, as can be done on the warp-weighted loom.&#160; Dave has already written about his explorations in tablet weaving at great depth, moving between his laptop and a tablet loom, in order to write code for modelling its structure and verify this by making the real thing. As with earlier experiments with modelling 'conventional' weaving, I wondered what would happen if I tried modelling tablet weaving from a different perspective, to see I could arrive at the same results via a different path, in order to broaden understanding of tablet weaving.An important reference point for Dave's work is Philia's String Page on tablet weaving theory. As Philia implies, it makes little sense until you begin to physically work with tablet weaving, and even then it's very difficult to grasp exactly how the warp and weft are interacting. Part of the problem is that tablet weaving is a multi-layered structure, with much of the interaction between warp and weft being hidden inside the fabric.As with some earlier work in our Weaving Codes project, I really wanted to take the perspective of the threads in a weave, and model their movements within the structure. This presents interesting problems, if you assume a thread has no orientation on which to turn 'left' or 'right'; unlike us humans, threads do not have any distinguishing features on which to base a symmetrical left and right, or front and back side. However a thread does know about twisting, as that's a fundamental part of its structure - any thread has either an 'S' or 'Z' twist, twisting downward to the right, or downward to the left respectively (reflected in the diagonal in the letters).From reading Philia's page, understanding Dave's work and doing tablet weaving, I became fascinated by the idea that tablet weaving is about plying. That is, taking the warp threads, and using the tablets to group twist them together into cords. The weft then doesn't go up and down, but through the warp. At this point the programmer in me gets excited with the promise of threads being grouped into higher-level cords; making composite groups of discrete things is just the sort of thing that programming languages are supposed to be good at.Sadly things are much more complicated than that though, because tablet weaving isn't just about twisting, but untwisting. When you keep turning the tablets in the same direction for each weft, everything is simple, but you will at some point have to turn back, as the most practical way of stopping the warp threads from getting twisted up. Where you change direction, the cord is untwisted, loses its identity, and its constituent threads behave independently. For example if you keep turning back and forth in single turns, the two 'inner' warp threads will go up and down over the weft inside the fabric, and the outer threads will 'float' over the top and bottom. At this turn, the neat hierarchical model seems to break apart. Our four threads that are grouped and twisted into a cord, break apart into a very different structure - two of the threads forming a tabby weave inside the band, and twe of them becoming independent outside the band. This way in which threads shift between totally different structures and orders seemed for a moment impossible to approach.This experience is not uncommon in computer programming - a beautiful idea suddenly gets very messy. However with enough pondering and sketching, an insight generally arrives that simplifies things and the mess disappears. In this case the answer was trying to think of myself as an individual threads inside a tablet weave. Question one: what relationship do I have with the other warp threads around me? Question two: what is the reference point for my movement? The answer to question one is always the same - on a basic four-threads-per-tablet weave, I always have the same relationship to the other three threads - we might twist, but we are stuck in our corners and can't change places. In other words, even though we exist within a twisting cord, in terms of the structure of that cord, the composite threads are completely straight. This insight simplifies things hugely - rather than thinking of threads inside a cord as spiraling around each other in a quadruple helix, it's much easier to think of the threads within a cord as straight lines, that lie parallel to each other, pairwise.&#160; The twisting and untwisting then doesn't happen on the level of individual threads, but groups of threads. To then answer the second question, both the individual threads and the composite cords only really move in one dimension! The inner threads are straight, and so is the composite cord, although the latter has an additional freedom of movement - of twist.There is one other important insight I had into how untwisting works, but first lets look at the code! It's in the pure functional language Haskell, so lets have a look at the type structure.First is the Action data type, which I originally made for representing weaves rather than tablet weaves. There are five types of action, but for the tablet woven warp threads, we only use Pull, which is where a thread is pulled straight over a given distance (generally under tension).data Action = Pull Int | Turn | TurnBack | Over | UnderNext is the Twist datatype. This is used for multiple purposes, not only representing the twist in a yarn, but also threading (and 'flipping') of tablets, and rotation of tablets. These are closely related if you consider the twist of tablets to create a new yarn by twisting threads together within the band. S and Z represent the twist direction (as is standard in textiles, S represents a twist in the \ direction and Z in the / direction, as you'd expect from the direction of the central portion of the letters themselves). A straight (non-twisted) thread is represented with I. A Spin is simply a sequence of twists.data Twist = S | Z | Idata Spin = Spin [Twist]A Thread is either a single Strand, or a Ply of composite Threads. This means that a Ply consists either of smaller Plys or individual threads.data Thread = Strand {colour :: Colour Double, roll :: Spin}&#160;&#160;&#160;&#160; &#160; &#160; &#160; &#160;&#160; | Ply {plyThreads :: [Thread], roll :: Spin}A Tablet is then modelled as a set of warp threads, and a twist. This isn't a the twist of the threads, but the twist of the tablet itself. In tablet weaving, if you 'flip' the tablet, then from then onwards, twisting the tablet results in a twist of the threads in the opposite direction.data Tablet = Tablet {warps :: [Thread], yaw :: Twist}A tablet loom is simple a set of tablets and a weft. (I've not dealt with the weft fully yet, but would go through the cords formed by the tablets, and up and down in relation to the threads inside the twisted cords, holding the structure together.)data TabletLoom = TabletLoom {tablets :: [Tablet], tabletWeft :: Thread}The next datatype represents the twists done by the each of the tablet of a TabletLoom, in order to go from one shed to the next. It is possible for some tablets to be turned one way, and others turned the opposite way.type TabletShed = [Twist]Collecting these things together, a TabletWeave is a tablet loom and a sequence of tablet rotations to create sheds, a Band is a set of twisted cords next to each other, drawn together into a band by the weft. As mentioned above, cords aren't curves, but one dimensional lines but with varying S/Z spin. It's the curve of the weft that binds them together (by passing through the cords) on a 2D plane (although the resulting structure is of course three dimensional).data TabletWeave = TabletWeave {tLoom :: TabletLoom, tSheds :: [TabletShed]}data Band = Band {bandCords :: [Thread], bandWeft :: Curve}data Curve = Curve {curveThread :: Thread, curvePath :: [Action]}And that's it for the type structure! As is common with Haskell code, the type structures are on the whole the most important part, but there is one more interesting thing that I alluded to earlier - how the turning of the tablets translates to the twisting of the cord. The rule is quite simple - if you turn the tablet in the same direction as the previous turn, then the yarn twists in sympathy. If you twist in the opposite direction as the previous one, the yarn is not twisted. Here's how I express that in haskell:deriveSpin :: [Twist] -&#62; [Twist]deriveSpin [] = []deriveSpin (x:[]) = I:[]deriveSpin (S:S:xs) = S:(deriveSpin (S:xs))deriveSpin (Z:Z:xs) = Z:(deriveSpin (Z:xs))deriveSpin (x:xs) = I:(deriveSpin xs)This took a while to get, and once I consider interaction with weft more deeply, there will surely be complications, but it's good enough for a simple visualisation of the warp. Speaking of which!Having made this model, there comes a special moment where you begin to visualise the outcome for the first time. This process leads to revealing of bugs to be fixed, but also more than that -- false assumptions that require more radical rethinking. It's an amazing moment really, where after what can be a long holiday during abstract development of ideas as code, your senses come home, re-embedded in thought processes.Anyway, here's an example of a tablet weave and the result:arrowWeave =  TabletWeave {tLoom =    TabletLoom {tablets = [                           threadTablet [b,b,b,b] S,                           threadTablet [b,b,b,b] Z,                           threadTablet [w,w,w,w] S,                           threadTablet [w,w,w,w] S,                           threadTablet [b,w,w,w] S,                           threadTablet [b,b,w,w] S,                           threadTablet [b,g,b,w] S,                           threadTablet [b,g,g,b] S,                           threadTablet [b,g,g,g] S,                           threadTablet [b,g,g,g] Z,                           threadTablet [b,g,g,b] Z,                           threadTablet [b,g,b,w] Z,                           threadTablet [b,b,w,w] Z,                           threadTablet [b,w,w,w] Z,                           threadTablet [w,w,w,w] Z,                           threadTablet [w,w,w,w] Z,                           threadTablet [b,b,b,b] S,                           threadTablet [b,b,b,b] Z                          ],                tabletWeft = thread orange               },               tSheds = map (replicate 18) [S,S,S,S,S,S,S,S,Z,Z,Z,Z,Z,Z,Z,Z]              }  where b = thread black        g = thread green        w = thread whiteI haven't shown the intermediate step - the text-based representation of each cord and constituent threads, because it is rather long. But you can see in the visual rendering of it (created by saving the thread paths in a way readable by the excellent openSCAD software) that a nice arrow pattern appears, as expected. You can see that where the sheds change direction in the middle, the warp straightens out for one step.One interesting thing is that even though I'm not drawing the weft yet, if you view the band from the side, you can see where the weft would go:What's particularly interesting about the above is that the gap left for the weft in the twist of the warp, is where the warp appears to go down, on both sides. This is strange - I would have expected the weft to be pushing the warps up, not down. But it seems that it's more that that the weft is holding the groups of four warp threads in an square configuration (two half-up, two half-down), causing a twist into a diamond configuration (one fully up, one fully down, two to the sides) at the midpoint between two wefts.Ok that's enough for now. If you're interested to look at the code (under a GPLv3 license), the main type structure is in Tablet.hs, some example bands are in test.hs, and the code for rendering into openScad format is in Scad.hs. I hope to develop it into a more usable form soon.