weavingspace.weave_matrices

Functions to generate the matrices summarising tiles of tileable repeating geometries that when repeated across a map area give the appearance of a
woven surface composed of criss-crossing strand.

Implementation is based on ideas discussed in variously

  • Glassner, A. 2002. Digital weaving. 1. IEEE Computer Graphics and Applications 22 (6):108–118.
  • ———. 2003a. Digital weaving. 3. IEEE Computer Graphics and Applications 23 (2):80-83.
  • ———. 2003b. Digital weaving. 2. IEEE Computer Graphics and Applications 23 (1):77-90.

and (unpublished)

where weaving is shown to be a matrix multiplication of tie-up, threading and treadling matrices. An accessible introduction can be found at https://www.youtube.com/watch?v=oMOSiag3dxg

  1#!/usr/bin/env python
  2# coding: utf-8
  3
  4"""Functions to generate the matrices summarising tiles of tileable repeating 
  5geometries that when repeated across a map area give the appearance of a  
  6woven surface composed of criss-crossing strand. 
  7
  8Implementation is based on ideas discussed in variously
  9 
 10+ Glassner, A. 2002. Digital weaving. 1. IEEE Computer Graphics and Applications 22 (6):108–118.
 11+ ———. 2003a. Digital weaving. 3. IEEE Computer Graphics and Applications 23 (2):80-83.
 12+ ———. 2003b. Digital weaving. 2. IEEE Computer Graphics and Applications 23 (1):77-90.
 13 
 14and (unpublished)
 15
 16+ Griswold, R. 2006. Mathematical and Computational Topics in Weaving
 17https://www2.cs.arizona.edu/patterns/weaving/webdocs/mo/Griswold-MO.pdf 
 18(accessed 29/10/21).
 19 
 20where weaving is shown to be a matrix multiplication of tie-up, threading and 
 21treadling matrices. An accessible introduction can be found at 
 22https://www.youtube.com/watch?v=oMOSiag3dxg
 23"""
 24
 25from typing import Union
 26import numpy as np
 27
 28def reps_needed(x1:int, x2:int) -> tuple[int]:
 29  """Returns how many repetitions of sequences of length x1 and x2 are 
 30  needed to make a matched length sequence 
 31
 32  Args:
 33    x1 (int): length of first sequence.
 34    x2 (int): length of second sequence.
 35
 36  Returns:
 37    tuple[int]: (number of repeats of x1, number of repeats of x2).
 38  """  
 39  n = np.lcm(x1, x2)
 40  return tuple(i for i in (n // x1, n // x2))
 41
 42
 43def get_pattern(tie_up:np.ndarray, treadling:np.ndarray, threading:np.ndarray,
 44        warp_n:int, weft_n:int, rep:int = 1) -> np.ndarray:
 45  """Returns a 0/1 encoded weave matrix. 
 46  
 47  Given tie_up, treadling and threading matrices. The following conditions  must be satisfied to avoid non-conformable matrix error:
 48  
 49    treadling.shape[1] == tie_up.shape[0]
 50    tie_up.shape[1] == threading.shape[0]
 51  
 52  The "twill", "random", "basket" and "plain" options should guarantee
 53  this, but the "this" option requires the user to make this happen
 54  If the warp_n and weft_n values are not factors of treadling.shape[0] and
 55  threading.shape[1] respectively, the output matrix will be repeated as
 56  needed to make this match
 57
 58  Args:
 59    tie_up (np.ndarray): the tie up matrix.
 60    treadling (np.ndarray): the treadling matrix.
 61    threading (np.ndarray): the threading matrix.
 62    warp_n (int): the number of uniquely labelled warp threads.
 63    weft_n (int): the number of uniquely labelled weft threads.
 64    rep (int, optional): optional additional repetition of the output       
 65      applied in both directions. Defaults to 1.
 66
 67  Returns:
 68    np.ndarray: _description_
 69  """    
 70  pattern = (treadling @ tie_up @ threading > 0) + 0
 71  rep_warp = reps_needed(warp_n, pattern.shape[1])
 72  rep_weft = reps_needed(weft_n, pattern.shape[0])
 73  return np.tile(pattern, (rep_weft[1] * rep, rep_warp[1] * rep))
 74
 75
 76# Note that as currently written this function requires the warp and weft
 77# matrices to be the same size, which get_weave_pattern_matrix will ensure,
 78# but which may not be the case if called from elsewhere
 79def _encode_biaxial_weave(pattern:np.ndarray, warp:np.ndarray, 
 80             weft:np.ndarray) -> np.ndarray:
 81  """Encodes a biaxial weave pattern as below.
 82
 83    1 - warp is absent
 84    2 - weft is absent
 85    3 - both threads are absent
 86    4 - weft is on top
 87    5 - warp is on top 
 88  
 89  Args:
 90    pattern (np.ndarray): pattern matrix with 1 where warp is on top, 
 91      0 where weft is on top.
 92    warp (np.ndarray): warp matrix where -1 values indicate absent threads.
 93    weft (np.ndarray): weft matrix where -1 values indicate absent threads.
 94
 95  Returns:
 96    np.ndarray: matrix of values encoded as above.
 97  """    
 98  # Can't recall why this particular encoding, but don't think it matters...
 99  pattern = np.where(pattern == 1, 5, pattern)           # warp on top
100  pattern = np.where(pattern == 0, 4, pattern)           # weft on top
101  pattern = np.where(warp < 0, 1, pattern)               # warp absent
102  pattern = np.where(weft < 0, 2, pattern)               # weft absent
103  return np.where((warp < 0) & (weft < 0), 3, pattern)   # both absent
104
105
106def make_plain_pattern(warp_n:int = 1, weft_n:int = 1) -> np.ndarray:
107  """Returns plain weave (checkerboard) matrix.
108
109  Args:
110    warp_n (int, optional): number of warp thread labels. Defaults to 1.
111    weft_n (int, optional): number of weft thread labels. Defaults to 1.
112
113  Returns:
114    np.ndarray: 0/1 matrix where 1 = warp on top.
115  """    
116  return make_twill_pattern(n = 1, warp_n = warp_n, weft_n = weft_n)
117
118
119def make_twill_pattern(n:Union[int, tuple[int]] = 2, 
120             warp_n:int = 2, weft_n:int = 2) -> np.ndarray:
121  """Returns twill pattern matrix extended for warp and weft patterns.
122
123  n is the number of over-unders. With n = 1 we get a plain weave.
124
125  Args:
126    n (Union[int,tuple[int]], optional): specifies over-under sequence in
127      the weave. Defaults to 2.
128    warp_n (int, optional): number of warp thread labels. Defaults to 2.
129    weft_n (int, optional): number of weft thread labels. Defaults to 2.
130
131  Returns:
132    np.ndarray: _description_
133  """    
134  tie_up = make_twill_matrix(n)
135  threading = np.diag(np.ones(tie_up.shape[0]))
136  treadling = np.diag(np.ones(tie_up.shape[1]))
137  return get_pattern(tie_up, treadling, threading, warp_n, weft_n)
138
139
140def make_over_under_row(n:Union[int,tuple[int]]) -> list[int]:
141  """Returns a tuple of runs of 1s and 0s.
142
143  Returns a tuple of runs of 1s and 0s per supplied n. 
144  
145  If n is an integer, returned tuple will be a series of n 1s followed by
146  n 0s.
147  
148  If n is a tuple of odd length it will be repeated to produce an even
149  length over-under sequence. This is required to avoid cases such as
150  e.g, (1,2,3) -> 100111 which repeated is 1001111001111, i.e. a (2,4)
151  pattern. Repeating it yields 100111011000 which is the requested pattern.
152
153  Args:
154    n (Union[int,tuple[int]]): requested over-under sequence. See details.
155
156  Returns:
157    list[int]: list of runs of 1s and 0s in the requested pattern. 
158  """    
159  over_under = n
160  if type(over_under) == int:
161    over_under = [n, n]
162  elif len(n) % 2 != 0:
163    over_under = n * 2
164  x = 1
165  row = []
166  for y in over_under:
167    row.extend([x] * y)
168    x = 1 - x
169  return row
170
171
172def wrap_row(r:list, by:int = 1) -> list:
173  """Wraps the list r by number of positions.
174  
175  Positive by will shift right.
176  Negative shifts left.
177
178  Args:
179    r (list): list to wrap.
180    by (int, optional): number of positions to shift by. Defaults to 1.
181
182  Returns:
183    list: wrapped list.
184  """    
185  return r[-by:] + r[:-by]
186
187
188def make_twill_matrix(over_under:Union[int, tuple[int]]) -> np.ndarray:
189  """Makes a twill 0/1 matrix.
190
191  Makes a matrix like
192  
193    1 1 0 0
194    0 1 1 0
195    0 0 1 1
196    1 0 0 1
197    
198  where the repeat runs in each row are lengths returned by
199  make_over_under_rown(n)
200
201  Args:
202    over_under (Union[int,tuple[int]]): over-under run specification. See
203      make_over_under_row().
204
205  Returns:
206    np.ndarray: a matrix of 0s and 1s.
207  """    
208  row = make_over_under_row(over_under)
209  d = len(row)
210  out = []
211  for i in range(d):
212    row = wrap_row(row, 1)
213    out.extend(row)
214  return np.array(out).reshape(d, d)
215
216
217def make_basket_pattern(n:int = 2, warp_n:int = 2, 
218            weft_n:int = 2) -> np.ndarray: 
219  """Returns basket pattern matrix extended for warp and weft patterns.
220
221  Args:
222    n (int, optional): over under count. Defaults to 2.
223    warp_n (int, optional): number of warp thread labels. Defaults to 2.
224    weft_n (int, optional): number of weft thread labels. Defaults to 2.
225
226  Returns:
227    np.ndarray: _description_
228  """    
229  tie_up = make_basket_matrix(n)
230  threading = np.diag(np.ones(tie_up.shape[0]))
231  treadling = np.diag(np.ones(tie_up.shape[1]))
232  return get_pattern(tie_up, treadling, threading, warp_n, weft_n)
233
234
235def make_basket_matrix(n:int) -> np.ndarray:
236  """Returns a basket weave pattern matrix.
237
238  Makes a matrix like
239  
240    1 1 0 0
241    1 1 0 0
242    0 0 1 1
243    0 0 1 1
244  
245  where the repeat runs in each row are length n
246
247  Args:
248    n (int): dimension of the 'basket' over-under pattern.
249
250  Returns:
251    np.ndarray: 0/1 matrix in basket weave pattern.
252  """    
253  return np.array((([1] * n + [0] * n) * n) + 
254          (([0] * n + [1] * n) * n)).reshape(n * 2, n * 2)
255
256
257def make_this_pattern(tie_up:np.ndarray, 
258            threading:np.ndarray = None,
259            treadling:np.ndarray = None,
260            warp_n:int = 1, weft_n:int = 1) -> np.ndarray:
261  """Pass through returns weave pattern matrix from supplied input.
262
263  This is just a pass through function which applies suitable size identity. Could try to enforce
264  
265    treadling.shape[1] == tie_up.shape[0] and 
266    tie_up.shape[1] == threading.shape[0]
267  
268  but unsure what would be an appropriate way to do this...
269
270  Args:
271    tie_up (np.ndarray): desired weave pattern.
272    threading (np.ndarray): desired threading pattern.
273    treadling (np.ndarray): desired treadling pattern.
274    warp_n (int, optional): number of warp thread labels. Defaults to 1.
275    weft_n (int, optional): number of weft thread labels. Defaults to 1.
276
277  Returns:
278    np.ndarray: resulting 0/1 weave pattern matrix.
279  """    
280  threading = (np.diag(np.ones(tie_up.shape[0]))
281         if threading is None
282         else threading)
283  treadling = (np.diag(np.ones(tie_up.shape[1]))
284         if treadling is None
285         else treadling)
286  return get_pattern(tie_up, treadling, threading, warp_n, weft_n)
287
288
289def get_weave_pattern_matrix(weave_type:str = "plain", 
290               n:Union[int, tuple[int]] = 2, 
291               warp:Union[list[str], tuple[str]] = ["a", "b"],
292               weft:Union[list[str], tuple[str]] = ["c", "d"], 
293               tie_up:np.ndarray = make_twill_matrix((2, 2)), 
294               tr:np.ndarray = None, 
295               th:np.ndarray = None) -> np.ndarray:
296  """Returns encoded weave pattern matrix.
297  
298  See `_encode_biaxial_weave()` for the encoding.
299
300  Allowed weave_types: "plain", "twill", "basket", and "this" (pass-thru).
301  These are explained in the respective functions to which this function
302  delegates construction of the base matrices before applying the encoding.
303
304  Args:
305    weave_type (str, optional): one of "plain", "twill", "basket" or
306      "this". Defaults to "plain".
307    n (Union[int,tuple[int]], optional): over under pattern. See 
308      make_over_under_row() for details. Defaults to 2.
309    warp (Union[list[str],tuple[str]], optional): list of labels for warp 
310      strands. Defaults to ["a", "b"].
311    weft (Union[list[str],tuple[str]], optional): list of labels for weft 
312      strands. Defaults to ["c", "d"].
313    tie_up (np.ndarray, optional): a weave pattern matrix to pass thru in 
314      the "this" case. Defaults to make_twill_matrix((2, 2)).
315    tr (np.ndarray, optional): treadling matrix for the "this" case.        
316      Defaults to None.
317    th (np.ndarray, optional): threading matrix for the "this" case.        
318      Defaults to None.
319
320  Returns:
321    np.ndarray: encoded weave pattern matrix.
322  """    
323  warps = [-1 if c == "-" else i for i, c in enumerate(warp)]
324  wefts = [-1 if c == "-" else i for i, c in enumerate(weft)]
325  width = len(warp)
326  height = len(weft)
327  
328  if weave_type == "plain":
329    p = make_plain_pattern(warp_n = width, weft_n = height)
330  elif weave_type == "twill":
331    p = make_twill_pattern(n = n, warp_n = width, weft_n = height)
332  elif weave_type == "basket":
333    p = make_basket_pattern(n = n, warp_n = width, weft_n = height)
334  else:
335    p = make_this_pattern(tie_up = tie_up, threading = th, treadling = tr,
336                warp_n = width, weft_n = height)
337  nr, nc = p.shape
338  warp_threads = np.array(warps * 
339      reps_needed(nc, len(warps))[1] * nr).reshape((nr, nc))
340  weft_threads = np.array(wefts * 
341      reps_needed(nr, len(wefts))[1] * nc).reshape((nc, nr)).transpose()
342  # encode to reflect missing threads
343  return _encode_biaxial_weave(p, warp_threads, weft_threads)
def reps_needed(x1: int, x2: int) -> tuple[int]:
29def reps_needed(x1:int, x2:int) -> tuple[int]:
30  """Returns how many repetitions of sequences of length x1 and x2 are 
31  needed to make a matched length sequence 
32
33  Args:
34    x1 (int): length of first sequence.
35    x2 (int): length of second sequence.
36
37  Returns:
38    tuple[int]: (number of repeats of x1, number of repeats of x2).
39  """  
40  n = np.lcm(x1, x2)
41  return tuple(i for i in (n // x1, n // x2))

Returns how many repetitions of sequences of length x1 and x2 are needed to make a matched length sequence

Arguments:
  • x1 (int): length of first sequence.
  • x2 (int): length of second sequence.
Returns:

tuple[int]: (number of repeats of x1, number of repeats of x2).

def get_pattern( tie_up: numpy.ndarray, treadling: numpy.ndarray, threading: numpy.ndarray, warp_n: int, weft_n: int, rep: int = 1) -> numpy.ndarray:
44def get_pattern(tie_up:np.ndarray, treadling:np.ndarray, threading:np.ndarray,
45        warp_n:int, weft_n:int, rep:int = 1) -> np.ndarray:
46  """Returns a 0/1 encoded weave matrix. 
47  
48  Given tie_up, treadling and threading matrices. The following conditions  must be satisfied to avoid non-conformable matrix error:
49  
50    treadling.shape[1] == tie_up.shape[0]
51    tie_up.shape[1] == threading.shape[0]
52  
53  The "twill", "random", "basket" and "plain" options should guarantee
54  this, but the "this" option requires the user to make this happen
55  If the warp_n and weft_n values are not factors of treadling.shape[0] and
56  threading.shape[1] respectively, the output matrix will be repeated as
57  needed to make this match
58
59  Args:
60    tie_up (np.ndarray): the tie up matrix.
61    treadling (np.ndarray): the treadling matrix.
62    threading (np.ndarray): the threading matrix.
63    warp_n (int): the number of uniquely labelled warp threads.
64    weft_n (int): the number of uniquely labelled weft threads.
65    rep (int, optional): optional additional repetition of the output       
66      applied in both directions. Defaults to 1.
67
68  Returns:
69    np.ndarray: _description_
70  """    
71  pattern = (treadling @ tie_up @ threading > 0) + 0
72  rep_warp = reps_needed(warp_n, pattern.shape[1])
73  rep_weft = reps_needed(weft_n, pattern.shape[0])
74  return np.tile(pattern, (rep_weft[1] * rep, rep_warp[1] * rep))

Returns a 0/1 encoded weave matrix.

Given tie_up, treadling and threading matrices. The following conditions must be satisfied to avoid non-conformable matrix error:

treadling.shape[1] == tie_up.shape[0] tie_up.shape[1] == threading.shape[0]

The "twill", "random", "basket" and "plain" options should guarantee this, but the "this" option requires the user to make this happen If the warp_n and weft_n values are not factors of treadling.shape[0] and threading.shape[1] respectively, the output matrix will be repeated as needed to make this match

Arguments:
  • tie_up (np.ndarray): the tie up matrix.
  • treadling (np.ndarray): the treadling matrix.
  • threading (np.ndarray): the threading matrix.
  • warp_n (int): the number of uniquely labelled warp threads.
  • weft_n (int): the number of uniquely labelled weft threads.
  • rep (int, optional): optional additional repetition of the output
    applied in both directions. Defaults to 1.
Returns:

np.ndarray: _description_

def make_plain_pattern(warp_n: int = 1, weft_n: int = 1) -> numpy.ndarray:
107def make_plain_pattern(warp_n:int = 1, weft_n:int = 1) -> np.ndarray:
108  """Returns plain weave (checkerboard) matrix.
109
110  Args:
111    warp_n (int, optional): number of warp thread labels. Defaults to 1.
112    weft_n (int, optional): number of weft thread labels. Defaults to 1.
113
114  Returns:
115    np.ndarray: 0/1 matrix where 1 = warp on top.
116  """    
117  return make_twill_pattern(n = 1, warp_n = warp_n, weft_n = weft_n)

Returns plain weave (checkerboard) matrix.

Arguments:
  • warp_n (int, optional): number of warp thread labels. Defaults to 1.
  • weft_n (int, optional): number of weft thread labels. Defaults to 1.
Returns:

np.ndarray: 0/1 matrix where 1 = warp on top.

def make_twill_pattern( n: Union[int, tuple[int]] = 2, warp_n: int = 2, weft_n: int = 2) -> numpy.ndarray:
120def make_twill_pattern(n:Union[int, tuple[int]] = 2, 
121             warp_n:int = 2, weft_n:int = 2) -> np.ndarray:
122  """Returns twill pattern matrix extended for warp and weft patterns.
123
124  n is the number of over-unders. With n = 1 we get a plain weave.
125
126  Args:
127    n (Union[int,tuple[int]], optional): specifies over-under sequence in
128      the weave. Defaults to 2.
129    warp_n (int, optional): number of warp thread labels. Defaults to 2.
130    weft_n (int, optional): number of weft thread labels. Defaults to 2.
131
132  Returns:
133    np.ndarray: _description_
134  """    
135  tie_up = make_twill_matrix(n)
136  threading = np.diag(np.ones(tie_up.shape[0]))
137  treadling = np.diag(np.ones(tie_up.shape[1]))
138  return get_pattern(tie_up, treadling, threading, warp_n, weft_n)

Returns twill pattern matrix extended for warp and weft patterns.

n is the number of over-unders. With n = 1 we get a plain weave.

Arguments:
  • n (Union[int,tuple[int]], optional): specifies over-under sequence in the weave. Defaults to 2.
  • warp_n (int, optional): number of warp thread labels. Defaults to 2.
  • weft_n (int, optional): number of weft thread labels. Defaults to 2.
Returns:

np.ndarray: _description_

def make_over_under_row(n: Union[int, tuple[int]]) -> list[int]:
141def make_over_under_row(n:Union[int,tuple[int]]) -> list[int]:
142  """Returns a tuple of runs of 1s and 0s.
143
144  Returns a tuple of runs of 1s and 0s per supplied n. 
145  
146  If n is an integer, returned tuple will be a series of n 1s followed by
147  n 0s.
148  
149  If n is a tuple of odd length it will be repeated to produce an even
150  length over-under sequence. This is required to avoid cases such as
151  e.g, (1,2,3) -> 100111 which repeated is 1001111001111, i.e. a (2,4)
152  pattern. Repeating it yields 100111011000 which is the requested pattern.
153
154  Args:
155    n (Union[int,tuple[int]]): requested over-under sequence. See details.
156
157  Returns:
158    list[int]: list of runs of 1s and 0s in the requested pattern. 
159  """    
160  over_under = n
161  if type(over_under) == int:
162    over_under = [n, n]
163  elif len(n) % 2 != 0:
164    over_under = n * 2
165  x = 1
166  row = []
167  for y in over_under:
168    row.extend([x] * y)
169    x = 1 - x
170  return row

Returns a tuple of runs of 1s and 0s.

Returns a tuple of runs of 1s and 0s per supplied n.

If n is an integer, returned tuple will be a series of n 1s followed by n 0s.

If n is a tuple of odd length it will be repeated to produce an even length over-under sequence. This is required to avoid cases such as e.g, (1,2,3) -> 100111 which repeated is 1001111001111, i.e. a (2,4) pattern. Repeating it yields 100111011000 which is the requested pattern.

Arguments:
  • n (Union[int,tuple[int]]): requested over-under sequence. See details.
Returns:

list[int]: list of runs of 1s and 0s in the requested pattern.

def wrap_row(r: list, by: int = 1) -> list:
173def wrap_row(r:list, by:int = 1) -> list:
174  """Wraps the list r by number of positions.
175  
176  Positive by will shift right.
177  Negative shifts left.
178
179  Args:
180    r (list): list to wrap.
181    by (int, optional): number of positions to shift by. Defaults to 1.
182
183  Returns:
184    list: wrapped list.
185  """    
186  return r[-by:] + r[:-by]

Wraps the list r by number of positions.

Positive by will shift right. Negative shifts left.

Arguments:
  • r (list): list to wrap.
  • by (int, optional): number of positions to shift by. Defaults to 1.
Returns:

list: wrapped list.

def make_twill_matrix(over_under: Union[int, tuple[int]]) -> numpy.ndarray:
189def make_twill_matrix(over_under:Union[int, tuple[int]]) -> np.ndarray:
190  """Makes a twill 0/1 matrix.
191
192  Makes a matrix like
193  
194    1 1 0 0
195    0 1 1 0
196    0 0 1 1
197    1 0 0 1
198    
199  where the repeat runs in each row are lengths returned by
200  make_over_under_rown(n)
201
202  Args:
203    over_under (Union[int,tuple[int]]): over-under run specification. See
204      make_over_under_row().
205
206  Returns:
207    np.ndarray: a matrix of 0s and 1s.
208  """    
209  row = make_over_under_row(over_under)
210  d = len(row)
211  out = []
212  for i in range(d):
213    row = wrap_row(row, 1)
214    out.extend(row)
215  return np.array(out).reshape(d, d)

Makes a twill 0/1 matrix.

Makes a matrix like

1 1 0 0 0 1 1 0 0 0 1 1 1 0 0 1

where the repeat runs in each row are lengths returned by make_over_under_rown(n)

Arguments:
  • over_under (Union[int,tuple[int]]): over-under run specification. See make_over_under_row().
Returns:

np.ndarray: a matrix of 0s and 1s.

def make_basket_pattern(n: int = 2, warp_n: int = 2, weft_n: int = 2) -> numpy.ndarray:
218def make_basket_pattern(n:int = 2, warp_n:int = 2, 
219            weft_n:int = 2) -> np.ndarray: 
220  """Returns basket pattern matrix extended for warp and weft patterns.
221
222  Args:
223    n (int, optional): over under count. Defaults to 2.
224    warp_n (int, optional): number of warp thread labels. Defaults to 2.
225    weft_n (int, optional): number of weft thread labels. Defaults to 2.
226
227  Returns:
228    np.ndarray: _description_
229  """    
230  tie_up = make_basket_matrix(n)
231  threading = np.diag(np.ones(tie_up.shape[0]))
232  treadling = np.diag(np.ones(tie_up.shape[1]))
233  return get_pattern(tie_up, treadling, threading, warp_n, weft_n)

Returns basket pattern matrix extended for warp and weft patterns.

Arguments:
  • n (int, optional): over under count. Defaults to 2.
  • warp_n (int, optional): number of warp thread labels. Defaults to 2.
  • weft_n (int, optional): number of weft thread labels. Defaults to 2.
Returns:

np.ndarray: _description_

def make_basket_matrix(n: int) -> numpy.ndarray:
236def make_basket_matrix(n:int) -> np.ndarray:
237  """Returns a basket weave pattern matrix.
238
239  Makes a matrix like
240  
241    1 1 0 0
242    1 1 0 0
243    0 0 1 1
244    0 0 1 1
245  
246  where the repeat runs in each row are length n
247
248  Args:
249    n (int): dimension of the 'basket' over-under pattern.
250
251  Returns:
252    np.ndarray: 0/1 matrix in basket weave pattern.
253  """    
254  return np.array((([1] * n + [0] * n) * n) + 
255          (([0] * n + [1] * n) * n)).reshape(n * 2, n * 2)

Returns a basket weave pattern matrix.

Makes a matrix like

1 1 0 0 1 1 0 0 0 0 1 1 0 0 1 1

where the repeat runs in each row are length n

Arguments:
  • n (int): dimension of the 'basket' over-under pattern.
Returns:

np.ndarray: 0/1 matrix in basket weave pattern.

def make_this_pattern( tie_up: numpy.ndarray, threading: numpy.ndarray = None, treadling: numpy.ndarray = None, warp_n: int = 1, weft_n: int = 1) -> numpy.ndarray:
258def make_this_pattern(tie_up:np.ndarray, 
259            threading:np.ndarray = None,
260            treadling:np.ndarray = None,
261            warp_n:int = 1, weft_n:int = 1) -> np.ndarray:
262  """Pass through returns weave pattern matrix from supplied input.
263
264  This is just a pass through function which applies suitable size identity. Could try to enforce
265  
266    treadling.shape[1] == tie_up.shape[0] and 
267    tie_up.shape[1] == threading.shape[0]
268  
269  but unsure what would be an appropriate way to do this...
270
271  Args:
272    tie_up (np.ndarray): desired weave pattern.
273    threading (np.ndarray): desired threading pattern.
274    treadling (np.ndarray): desired treadling pattern.
275    warp_n (int, optional): number of warp thread labels. Defaults to 1.
276    weft_n (int, optional): number of weft thread labels. Defaults to 1.
277
278  Returns:
279    np.ndarray: resulting 0/1 weave pattern matrix.
280  """    
281  threading = (np.diag(np.ones(tie_up.shape[0]))
282         if threading is None
283         else threading)
284  treadling = (np.diag(np.ones(tie_up.shape[1]))
285         if treadling is None
286         else treadling)
287  return get_pattern(tie_up, treadling, threading, warp_n, weft_n)

Pass through returns weave pattern matrix from supplied input.

This is just a pass through function which applies suitable size identity. Could try to enforce

treadling.shape[1] == tie_up.shape[0] and tie_up.shape[1] == threading.shape[0]

but unsure what would be an appropriate way to do this...

Arguments:
  • tie_up (np.ndarray): desired weave pattern.
  • threading (np.ndarray): desired threading pattern.
  • treadling (np.ndarray): desired treadling pattern.
  • warp_n (int, optional): number of warp thread labels. Defaults to 1.
  • weft_n (int, optional): number of weft thread labels. Defaults to 1.
Returns:

np.ndarray: resulting 0/1 weave pattern matrix.

def get_weave_pattern_matrix( weave_type: str = 'plain', n: Union[int, tuple[int]] = 2, warp: Union[list[str], tuple[str]] = ['a', 'b'], weft: Union[list[str], tuple[str]] = ['c', 'd'], tie_up: numpy.ndarray = array([[0, 1, 1, 0], [0, 0, 1, 1], [1, 0, 0, 1], [1, 1, 0, 0]]), tr: numpy.ndarray = None, th: numpy.ndarray = None) -> numpy.ndarray:
290def get_weave_pattern_matrix(weave_type:str = "plain", 
291               n:Union[int, tuple[int]] = 2, 
292               warp:Union[list[str], tuple[str]] = ["a", "b"],
293               weft:Union[list[str], tuple[str]] = ["c", "d"], 
294               tie_up:np.ndarray = make_twill_matrix((2, 2)), 
295               tr:np.ndarray = None, 
296               th:np.ndarray = None) -> np.ndarray:
297  """Returns encoded weave pattern matrix.
298  
299  See `_encode_biaxial_weave()` for the encoding.
300
301  Allowed weave_types: "plain", "twill", "basket", and "this" (pass-thru).
302  These are explained in the respective functions to which this function
303  delegates construction of the base matrices before applying the encoding.
304
305  Args:
306    weave_type (str, optional): one of "plain", "twill", "basket" or
307      "this". Defaults to "plain".
308    n (Union[int,tuple[int]], optional): over under pattern. See 
309      make_over_under_row() for details. Defaults to 2.
310    warp (Union[list[str],tuple[str]], optional): list of labels for warp 
311      strands. Defaults to ["a", "b"].
312    weft (Union[list[str],tuple[str]], optional): list of labels for weft 
313      strands. Defaults to ["c", "d"].
314    tie_up (np.ndarray, optional): a weave pattern matrix to pass thru in 
315      the "this" case. Defaults to make_twill_matrix((2, 2)).
316    tr (np.ndarray, optional): treadling matrix for the "this" case.        
317      Defaults to None.
318    th (np.ndarray, optional): threading matrix for the "this" case.        
319      Defaults to None.
320
321  Returns:
322    np.ndarray: encoded weave pattern matrix.
323  """    
324  warps = [-1 if c == "-" else i for i, c in enumerate(warp)]
325  wefts = [-1 if c == "-" else i for i, c in enumerate(weft)]
326  width = len(warp)
327  height = len(weft)
328  
329  if weave_type == "plain":
330    p = make_plain_pattern(warp_n = width, weft_n = height)
331  elif weave_type == "twill":
332    p = make_twill_pattern(n = n, warp_n = width, weft_n = height)
333  elif weave_type == "basket":
334    p = make_basket_pattern(n = n, warp_n = width, weft_n = height)
335  else:
336    p = make_this_pattern(tie_up = tie_up, threading = th, treadling = tr,
337                warp_n = width, weft_n = height)
338  nr, nc = p.shape
339  warp_threads = np.array(warps * 
340      reps_needed(nc, len(warps))[1] * nr).reshape((nr, nc))
341  weft_threads = np.array(wefts * 
342      reps_needed(nr, len(wefts))[1] * nc).reshape((nc, nr)).transpose()
343  # encode to reflect missing threads
344  return _encode_biaxial_weave(p, warp_threads, weft_threads)

Returns encoded weave pattern matrix.

See _encode_biaxial_weave() for the encoding.

Allowed weave_types: "plain", "twill", "basket", and "this" (pass-thru). These are explained in the respective functions to which this function delegates construction of the base matrices before applying the encoding.

Arguments:
  • weave_type (str, optional): one of "plain", "twill", "basket" or "this". Defaults to "plain".
  • n (Union[int,tuple[int]], optional): over under pattern. See make_over_under_row() for details. Defaults to 2.
  • warp (Union[list[str],tuple[str]], optional): list of labels for warp strands. Defaults to ["a", "b"].
  • weft (Union[list[str],tuple[str]], optional): list of labels for weft strands. Defaults to ["c", "d"].
  • tie_up (np.ndarray, optional): a weave pattern matrix to pass thru in the "this" case. Defaults to make_twill_matrix((2, 2)).
  • tr (np.ndarray, optional): treadling matrix for the "this" case.
    Defaults to None.
  • th (np.ndarray, optional): threading matrix for the "this" case.
    Defaults to None.
Returns:

np.ndarray: encoded weave pattern matrix.