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 strands.

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 woven surface 
  6composed of criss-crossing strands. 
  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 
 48  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))
 75
 76
 77# Note that as currently written this function requires the warp and weft
 78# matrices to be the same size, which get_weave_pattern_matrix will ensure,
 79# but which may not be the case if called from elsewhere
 80def _encode_biaxial_weave(pattern:np.ndarray, warp:np.ndarray, 
 81             weft:np.ndarray) -> np.ndarray:
 82  """Encodes a biaxial weave pattern as below.
 83
 84    1 - warp is absent
 85    2 - weft is absent
 86    3 - both threads are absent
 87    4 - weft is on top
 88    5 - warp is on top 
 89  
 90  Args:
 91    pattern (np.ndarray): pattern matrix with 1 where warp is on top, 
 92      0 where weft is on top.
 93    warp (np.ndarray): warp matrix where -1 values indicate absent threads.
 94    weft (np.ndarray): weft matrix where -1 values indicate absent threads.
 95
 96  Returns:
 97    np.ndarray: matrix of values encoded as above.
 98  """    
 99  # Can't recall why this particular encoding, but don't think it matters...
100  pattern = np.where(pattern == 1, 5, pattern)           # warp on top
101  pattern = np.where(pattern == 0, 4, pattern)           # weft on top
102  pattern = np.where(warp < 0, 1, pattern)               # warp absent
103  pattern = np.where(weft < 0, 2, pattern)               # weft absent
104  return np.where((warp < 0) & (weft < 0), 3, pattern)   # both absent
105
106
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)
118
119
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)
139
140
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
171
172
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]
187
188
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)
216
217
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)
234
235
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)
256
257
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. 
265  Could try to enforce
266  
267    treadling.shape[1] == tie_up.shape[0] and 
268    tie_up.shape[1] == threading.shape[0]
269  
270  but unsure what would be an appropriate way to do this...
271
272  Args:
273    tie_up (np.ndarray): desired weave pattern.
274    threading (np.ndarray): desired threading pattern.
275    treadling (np.ndarray): desired treadling pattern.
276    warp_n (int, optional): number of warp thread labels. Defaults to 1.
277    weft_n (int, optional): number of weft thread labels. Defaults to 1.
278
279  Returns:
280    np.ndarray: resulting 0/1 weave pattern matrix.
281  """    
282  threading = (np.diag(np.ones(tie_up.shape[0]))
283         if threading is None
284         else threading)
285  treadling = (np.diag(np.ones(tie_up.shape[1]))
286         if treadling is None
287         else treadling)
288  return get_pattern(tie_up, treadling, threading, warp_n, weft_n)
289
290
291def get_weave_pattern_matrix(weave_type:str = "plain", 
292               n:Union[int, tuple[int]] = 2, 
293               warp:Union[list[str], tuple[str]] = ["a", "b"],
294               weft:Union[list[str], tuple[str]] = ["c", "d"], 
295               tie_up:np.ndarray = make_twill_matrix((2, 2)), 
296               tr:np.ndarray = None, 
297               th:np.ndarray = None) -> np.ndarray:
298  """Returns encoded weave pattern matrix.
299  
300  See `_encode_biaxial_weave()` for the encoding.
301
302  Allowed weave_types: "plain", "twill", "basket", and "this" (pass-thru).
303  These are explained in the respective functions to which this function
304  delegates construction of the base matrices before applying the encoding.
305
306  Args:
307    weave_type (str, optional): one of "plain", "twill", "basket" or
308      "this". Defaults to "plain".
309    n (Union[int,tuple[int]], optional): over under pattern. See 
310      make_over_under_row() for details. Defaults to 2.
311    warp (Union[list[str],tuple[str]], optional): list of labels for warp 
312      strands. Defaults to ["a", "b"].
313    weft (Union[list[str],tuple[str]], optional): list of labels for weft 
314      strands. Defaults to ["c", "d"].
315    tie_up (np.ndarray, optional): a weave pattern matrix to pass thru in 
316      the "this" case. Defaults to make_twill_matrix((2, 2)).
317    tr (np.ndarray, optional): treadling matrix for the "this" case.        
318      Defaults to None.
319    th (np.ndarray, optional): threading matrix for the "this" case.        
320      Defaults to None.
321
322  Returns:
323    np.ndarray: encoded weave pattern matrix.
324  """    
325  warps = [-1 if c == "-" else i for i, c in enumerate(warp)]
326  wefts = [-1 if c == "-" else i for i, c in enumerate(weft)]
327  width = len(warp)
328  height = len(weft)
329  
330  if weave_type == "plain":
331    p = make_plain_pattern(warp_n = width, weft_n = height)
332  elif weave_type == "twill":
333    p = make_twill_pattern(n = n, warp_n = width, weft_n = height)
334  elif weave_type == "basket":
335    p = make_basket_pattern(n = n, warp_n = width, weft_n = height)
336  else:
337    p = make_this_pattern(tie_up = tie_up, threading = th, treadling = tr,
338                warp_n = width, weft_n = height)
339  nr, nc = p.shape
340  warp_threads = np.array(warps * 
341      reps_needed(nc, len(warps))[1] * nr).reshape((nr, nc))
342  weft_threads = np.array(wefts * 
343      reps_needed(nr, len(wefts))[1] * nc).reshape((nc, nr)).transpose()
344  # encode to reflect missing threads
345  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

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

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

Returns plain weave (checkerboard) matrix.

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

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

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

Wraps the list r by number of positions.

Positive by will shift right. Negative shifts left.

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

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

Returns basket pattern matrix extended for warp and weft patterns.

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

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

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

Args: 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.