weavingspace.weave_matrices

Functions to generate the matrices associated with woven patterns.

Such patterns 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. Glassner A. 2003. Digital weaving. 2. IEEE Computer Graphics and Applications 23(1):77-90. Glassner A. 2003. Digital weaving. 3. IEEE Computer Graphics and Applications 23(2):80-83.

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

Return number of sequences of length x1 and x2 are needed to match lengths.

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:
47def get_pattern(
48    tie_up:np.ndarray,
49    treadling:np.ndarray,
50    threading:np.ndarray,
51    warp_n:int,
52    weft_n:int,
53    rep:int = 1,
54  ) -> np.ndarray:
55  """Return a 0/1 encoded weave matrix.
56
57  Given tie_up, treadling and threading matrices. The following conditions
58  must be satisfied to avoid non-conformable matrix error:
59
60    treadling.shape[1] == tie_up.shape[0]
61    tie_up.shape[1] == threading.shape[0]
62
63  The "twill", "basket" and "plain" options should guarantee this. If the
64  warp_n and weft_n values are not factors of treadling.shape[0] and
65  threading.shape[1] respectively, the output matrix will be repeated as needed
66  to make this match
67
68  Args:
69    tie_up (np.ndarray): the tie up matrix.
70    treadling (np.ndarray): the treadling matrix.
71    threading (np.ndarray): the threading matrix.
72    warp_n (int): the number of uniquely labelled warp threads.
73    weft_n (int): the number of uniquely labelled weft threads.
74    rep (int, optional): optional additional repetition of the output
75      applied in both directions. Defaults to 1.
76
77  Returns:
78    np.ndarray: the matrix weave pattern generated by the supplied parameters.
79
80  """
81  pattern = (treadling @ tie_up @ threading > 0) + 0
82  rep_warp = reps_needed(warp_n, pattern.shape[1])
83  rep_weft = reps_needed(weft_n, pattern.shape[0])
84  return np.tile(pattern, (rep_weft[1] * rep, rep_warp[1] * rep))

Return 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", "basket" and "plain" options should guarantee this. 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: the matrix weave pattern generated by the supplied parameters.

def make_plain_pattern(warp_n: int = 1, weft_n: int = 1) -> numpy.ndarray:
120def make_plain_pattern(
121    warp_n:int = 1,
122    weft_n:int = 1,
123  ) -> np.ndarray:
124  """Return plain weave (checkerboard) matrix.
125
126  Args:
127    warp_n (int, optional): number of warp thread labels. Defaults to 1.
128    weft_n (int, optional): number of weft thread labels. Defaults to 1.
129
130  Returns:
131    np.ndarray: 0/1 matrix where 1 = warp on top.
132
133  """
134  return make_twill_pattern(n = 1, warp_n = warp_n, weft_n = weft_n)

Return 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: int | tuple[int] = 2, warp_n: int = 2, weft_n: int = 2) -> numpy.ndarray:
137def make_twill_pattern(
138    n:int|tuple[int] = 2,
139    warp_n:int = 2,
140    weft_n:int = 2,
141  ) -> np.ndarray:
142  """Return twill pattern matrix extended for warp and weft patterns.
143
144  n is the number of over-unders. With n = 1 we get a plain weave.
145
146  Args:
147    n (int|tuple[int], optional): specifies over-under sequence in
148      the weave. Defaults to 2.
149    warp_n (int, optional): number of warp thread labels. Defaults to 2.
150    weft_n (int, optional): number of weft thread labels. Defaults to 2.
151
152  Returns:
153    np.ndarray: _description_
154
155  """
156  tie_up = make_twill_matrix(n)
157  threading = np.diag(np.ones(tie_up.shape[0]))
158  treadling = np.diag(np.ones(tie_up.shape[1]))
159  return get_pattern(tie_up, treadling, threading, warp_n, weft_n)

Return 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 (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: int | tuple[int]) -> list[int]:
162def make_over_under_row(n:int|tuple[int]) -> list[int]:
163  """Return a tuple of runs of 1s and 0s.
164
165  Returns a tuple of runs of 1s and 0s per supplied n.
166
167  If n is an integer, returned tuple will be a series of n 1s followed by
168  n 0s.
169
170  If n is a tuple of odd length it will be repeated to produce an even
171  length over-under sequence. This is required to avoid cases such as
172  e.g, (1,2,3) -> 100111 which repeated is 1001111001111, i.e. a (2,4)
173  pattern. Repeating it yields 100111011000 which is the requested pattern.
174
175  Args:
176    n (int|tuple[int]): requested over-under sequence. See details.
177
178  Returns:
179    list[int]: list of runs of 1s and 0s in the requested pattern.
180
181  """
182  over_under = n
183  if isinstance(over_under, int):
184    over_under = [n, n]
185  elif len(n) % 2 != 0:
186    over_under = n * 2
187  x = 1
188  row = []
189  for y in over_under:
190    row.extend([x] * y)
191    x = 1 - x
192  return row

Return 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 (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:
195def wrap_row(
196    r:list,
197    by:int = 1,
198  ) -> list:
199  """Wrap the list r by number of positions.
200
201  Positive by will shift right.
202  Negative shifts left.
203
204  Args:
205    r (list): list to wrap.
206    by (int, optional): number of positions to shift by. Defaults to 1.
207
208  Returns:
209    list: wrapped list.
210
211  """
212  return r[-by:] + r[:-by]

Wrap 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: int | tuple[int]) -> numpy.ndarray:
215def make_twill_matrix(over_under:int|tuple[int]) -> np.ndarray:
216  """Make a twill 0/1 matrix.
217
218  Makes a matrix like
219
220    1 1 0 0
221    0 1 1 0
222    0 0 1 1
223    1 0 0 1
224
225  where the repeat runs in each row are lengths returned by
226  make_over_under_rown(n)
227
228  Args:
229    over_under (int|tuple[int]): over-under run specification. See
230      make_over_under_row().
231
232  Returns:
233    np.ndarray: a matrix of 0s and 1s.
234
235  """
236  row = make_over_under_row(over_under)
237  d = len(row)
238  out = []
239  for i in range(d):
240    row = wrap_row(row, 1)
241    out.extend(row)
242  return np.array(out).reshape(d, d)

Make 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 (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:
245def make_basket_pattern(
246    n:int = 2,
247    warp_n:int = 2,
248    weft_n:int = 2,
249  ) -> np.ndarray:
250  """Return basket pattern matrix extended for warp and weft patterns.
251
252  Args:
253    n (int, optional): over under count. Defaults to 2.
254    warp_n (int, optional): number of warp thread labels. Defaults to 2.
255    weft_n (int, optional): number of weft thread labels. Defaults to 2.
256
257  Returns:
258    np.ndarray: _description
259
260  """
261  tie_up = make_basket_matrix(n)
262  threading = np.diag(np.ones(tie_up.shape[0]))
263  treadling = np.diag(np.ones(tie_up.shape[1]))
264  return get_pattern(tie_up, treadling, threading, warp_n, weft_n)

Return 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:
267def make_basket_matrix(n:int) -> np.ndarray:
268  """Return a basket weave pattern matrix.
269
270  Makes a matrix like
271
272    1 1 0 0
273    1 1 0 0
274    0 0 1 1
275    0 0 1 1
276
277  where the repeat runs in each row are length n
278
279  Args:
280    n (int): dimension of the 'basket' over-under pattern.
281
282  Returns:
283    np.ndarray: 0/1 matrix in basket weave pattern.
284
285  """
286  return np.array((([1] * n + [0] * n) * n) +
287          (([0] * n + [1] * n) * n)).reshape(n * 2, n * 2)

Return 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:
290def make_this_pattern(
291    tie_up:np.ndarray,
292    threading:np.ndarray = None,
293    treadling:np.ndarray = None,
294    warp_n:int = 1,
295    weft_n:int = 1,
296  ) -> np.ndarray:
297  """Pass through returns weave pattern matrix from supplied input.
298
299  This is just a pass through function which applies suitable size identity.
300  Could try to enforce
301
302    treadling.shape[1] == tie_up.shape[0] and
303    tie_up.shape[1] == threading.shape[0]
304
305  but unsure what would be an appropriate way to do this...
306
307  Args:
308    tie_up (np.ndarray): desired weave pattern.
309    threading (np.ndarray): desired threading pattern.
310    treadling (np.ndarray): desired treadling pattern.
311    warp_n (int, optional): number of warp thread labels. Defaults to 1.
312    weft_n (int, optional): number of weft thread labels. Defaults to 1.
313
314  Returns:
315    np.ndarray: resulting 0/1 weave pattern matrix.
316
317  """
318  threading = (np.diag(np.ones(tie_up.shape[0]))
319               if threading is None
320               else threading)
321  treadling = (np.diag(np.ones(tie_up.shape[1]))
322               if treadling is None
323               else treadling)
324  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: int | tuple[int] = 2, warp: list[str] | tuple[str] = ('a', 'b'), weft: list[str] | tuple[str] = ('c', 'd'), tie_up: numpy.ndarray = None, tr: numpy.ndarray = None, th: numpy.ndarray = None) -> numpy.ndarray:
327def get_weave_pattern_matrix(
328    weave_type:str = "plain",
329    n:int|tuple[int] = 2,
330    warp:list[str]|tuple[str] = ("a", "b"),
331    weft:list[str]|tuple[str] = ("c", "d"),
332    tie_up:np.ndarray = None,
333    tr:np.ndarray = None,
334    th:np.ndarray = None,
335  ) -> np.ndarray:
336  """Return encoded weave pattern matrix.
337
338  See `_encode_biaxial_weave()` for the encoding.
339
340  Allowed weave_types: "plain", "twill", "basket", and "this" (pass-thru).
341  These are explained in the respective functions to which this function
342  delegates construction of the base matrices before applying the encoding.
343
344  Args:
345    weave_type (str, optional): one of "plain", "twill", "basket" or
346      "this". Defaults to "plain".
347    n (int|tuple[int], optional): over under pattern. See
348      make_over_under_row() for details. Defaults to 2.
349    warp (list[str]|tuple[str], optional): list of labels for warp
350      strands. Defaults to ["a", "b"].
351    weft (list[str]|tuple[str], optional): list of labels for weft
352      strands. Defaults to ["c", "d"].
353    tie_up (np.ndarray, optional): a weave pattern matrix to pass thru in
354      the "this" case. Defaults to make_twill_matrix((2, 2)).
355    tr (np.ndarray, optional): treadling matrix for the "this" case.
356      Defaults to None.
357    th (np.ndarray, optional): threading matrix for the "this" case.
358      Defaults to None.
359
360  Returns:
361    np.ndarray: encoded weave pattern matrix.
362
363  """
364  warps = [-1 if c == "-" else i for i, c in enumerate(warp)]
365  wefts = [-1 if c == "-" else i for i, c in enumerate(weft)]
366  width = len(warp)
367  height = len(weft)
368
369  if weave_type == "plain":
370    p = make_plain_pattern(warp_n = width, weft_n = height)
371  elif weave_type == "twill":
372    p = make_twill_pattern(n = n, warp_n = width, weft_n = height)
373  elif weave_type == "basket":
374    p = make_basket_pattern(n = n, warp_n = width, weft_n = height)
375  else:
376    p = make_this_pattern(tie_up = tie_up, threading = th, treadling = tr,
377                warp_n = width, weft_n = height)
378  nr, nc = p.shape
379  warp_threads = np.array(warps *
380      reps_needed(nc, len(warps))[1] * nr).reshape((nr, nc))
381  weft_threads = np.array(wefts *
382      reps_needed(nr, len(wefts))[1] * nc).reshape((nc, nr)).transpose()
383  # encode to reflect missing threads
384  return _encode_biaxial_weave(p, warp_threads, weft_threads)

Return 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 (int|tuple[int], optional): over under pattern. See make_over_under_row() for details. Defaults to 2. warp (list[str]|tuple[str], optional): list of labels for warp strands. Defaults to ["a", "b"]. weft (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.