Textiel ontwerpen, voor wevende nerds¶

In een inspiratie-loze periode voor mijn Leerlingstuk voor Weef Opleiding Nederland heb ik besloten hieraan mee te doen aan Weefnetwerk's servetontwerpwedstrijd. Want voor het Leerlingstuk is een technische beperking van maximaal 4 schachten aanwezig, zodat je de ontwerpvrijheid van zo'n "eenvoudig" getouw gaat ontdekken. Maar ik hou wel van complex, en daardoor voelde ik me wat beperkt. De creatieve "beperking" die een servet levert, gaf me weer goede sturing om verder te kunnen. Door persoonlijke omstandigheden kon ik het product niet weven voor de servettenwedstrijd, en heb ik uiteindelijk gekozen om het gekozen ontwerp om te zetten naar een omslagdoek.

Inhoudsopgave

  1. Specificaties
  2. Bindingstechniek
  3. Materiaal en kleur
    1. Experimenten
  4. Ontwerpen van een tweebloks patroon
    1. Bindingstekeningen genereren
    2. Lucas-reeksen van ongeveer gewenste lengte
    3. Compositie van één Lucas-reeks
      1. Simpele reeks
      2. Spiegeling
      3. Tegengestelde richting
      4. Gespiegelde tegengestelde richting
      5. Ongelijke aantallen
    4. Inslag ≠ inrijg
      1. Simpel, twee reeksen
      2. Spiegeling, twee reeksen
      3. Tegengestelde richting, twee reeksen
      4. Gespiegelde tegengestelde richting, twee reeksen
      5. Ongelijke aantallen, twee reeksen
    5. Niet geheel wiskundige ontwerpen
    6. Geselecteerde compositie
  5. Detaillering
  6. Realisatie
  7. Conclusie en evaluatie

Specificaties¶

Enkele specificaties die ik aan de servetten zal stellen, zijn:

  1. Absorptievermogen. Het materiaal moet goed bruikbaar zijn voor het doeleinde: je gebruikt een servet om viezigheid van je mond te halen zonder het aan te raken.
  2. Onderhoudsgemak. Na elk gebruik wil je de cosmetica- en voedingsvlekken makkelijk uit de servetten kunnen halen. Deze vlekken zijn onder andere vet-gebaseerd, en hebben vaak een hoge wastemperatuur nodig. Daarnaast hou ik niet van strijken, en dus moet het materiaal ook niet erg kreukelen.
  3. Prettig in mondcontact. Aangezien je je mond met een servet dept, moet het contact van de servet met de mond aangenaam zijn. Dat betekent dat het materiaal zacht moet zijn, maar niet harig.
  4. Dun maar stevig. Ik heb zin om te werken met dunnere garens om kleinere én grotere patroonstructuren te kunnen behalen. Het materiaal moet dus ook in dunne garens (vanaf garennummer 4/1 Nm of vergelijkbaar) verkrijgbaar zijn.
  5. Dubbelzijdig bruikbaar. Er mogen dus geen lange flotteringen aanwezig zijn.
  6. Dubbelzijdig interessant. Zowel voor- als achterkant zien er interessant uit.
  7. Passend bij twee serviezen. De servettenwedstrijd heeft een aantal moodboards voor bijpassende serviezen aangeleverd. Eén van die moodboards, die van Royal Delft's Peacock Symphony komt in sfeer ook wel overeen met het servies wat wij thuis hebben, namelijk Heinen Delftsblauw Sharing Moments Aapjes (productoverzicht). De grote dinerborden uit beide productlijnen hebben een doorsnede van 26 cm. De servet moet (na in tweeën vouwen) proportioneel hierbij zijn; niet te klein en niet te groot.
  8. Ongeveer vierkante lap na zomen. Hoewel langwerpig een prima optie kan zijn voor servetten, zie ik de mijne als bijna-vierkant voor me. Bij het maken van een uiteindelijke bindingstekening moet rekening gehouden worden met een naadtoeslag aan zowel boven- als onderkant. Die zone zal geen patroondraden bevatten om het zo dun mogelijk te kunnen vouwen. Mijn zelfkanten hoop ik mooi genoeg te maken dat ze toonbaar zijn.

Bindingstechniek¶

Net klaar met de cursus Blok- en Groepsinrijgingen had ik mijn techniek al klaarliggen: het zal uitgevoerd worden in zomer & winter, aangezien dit weefsel flotteringen van maximaal 3 lang heeft, en aan beide zijden interessant is om te zien. Door paarsgewijs in te slaan, is de achterzijde niet alleen een kleurnegatief van de voorzijde maar ook subtiel anders.

Materiaal en kleur¶

Vanuit de specificaties vallen een boel materialen al af. Eiwit-gebaseerde vezels zoals wol, alpaca, zijde en soja zijn ongeschikt omdat ze delicaat gewassen moeten worden; de vezels die op dierlijke haren zijn gebaseerd zijn ook ongeschikt in verband met het mondcontact. Kunstvezels hebben een slecht absorberend vermogen. We hebben nu nog alleen de cellulose-gebaseerde vezels over. Al deze vezels hebben een hoog genoeg absorptievermogen, maar zullen verschillen in hun onderhoudsgemak, dat ik verder uitgezet heb in criteria hete-was-bestendigd (weinig krimp, geen delicate behandeling nodig) en kreukvrij (weinig strijkwerk nodig om toonbaar te maken).

  • Katoen komt in grofweg twee vormen: ongemerceriseerd katoen absorbeerd beter dan gemerceriseerd katoen, dat daarentegen weer meer glants. Het kan goed tegen de hete was, en kreukt niet erg. Het is geen harig garen, waardoor het mondcontact prettig is. Gemerceriseerd katoen heb ik in huis van 8/2 Ne, en ongemerceriseerd katoen in 8/2 en 16/2 Ne. Ongemerceriseerd katoen is het enige garen waarmee ik eerder een schering heb gemaakt.
  • Linnen neemt wat meer vocht op dan katoen, maar is ook goed te wassen in de wasmachine. Maar: het kreukt enorm, en heeft een goede strijkbout nodig om toonbaar te zijn. Het kan daarom gebruikt worden voor kleine stukjes, maar niet als hoofdgaren. Ook zou het weven op een linnen schering met allerlei uitdagingen komen, maar dat heb ik niet verder onderzocht.
  • Cottolin (alhoewel geen "eigen" vezelsoort maar een veelvoorkomend mengsel) verenigt het wat ruwere effect van linnen met fijne eigenschappen van ongemerceriseerd katoen: een stuk minder kreukels, en een makkelijk(er) te gebruiken schering.
  • Viscose (van bijvoorbeeld bamboe) en gerelateerde materialen (zoals lyocell) zijn minder geschikt voor dit project, omdat ze minder goed kunnen tegen de hete was.
  • Ramie en hennep zouden beide stijver kunnen worden na meerdere wasbeurten. Dat beïnvloedt het mondcontact op een negatieve manier.

Ik heb ervoor gekozen om de grootste deel van de servetten te maken uit ongemerceriseerd katoen, omdat het de absorbtie bevordert, een hoog onderhoudsgemak heeft, fijn in het mondcontact is, en ook in dunne garens geschikt als schering. Gemerceriseerd katoen en linnen zijn beschikbaar voor dikkere patroondraden. Met de glans van gemerceriseerd katoen haal ik een aspect van het servies ook naar de servetten, terwijl de stoere ruwheid van linnen een groter contrast vormt.

Experimenten: binding, materiaal en kleur¶

Om het geheel passend bij het servies te maken, heb ik een kleurenstudie gedaan. Hoofdkleuren zullen (porselein) wit en (Delfts)blauw zijn. Ook heb ik onderzocht of ik tevredener ben met een schering van 8/2 Ne of 16/2 Ne ongemerceriseerd katoen. Er zijn twee proefscheringen gemaakt, waarbij materiaalkeuze niet alleen is gebaseerd op kleur en dikte maar ook of ik er al beschikking over heb:

  • Proeflap 1: een blauwe schering van 8/2 Ne ongemerceriseerd katoen;
  • Proeflap 2: een witte schering van 16/2 Ne ongemerceriseerd katoen.

Op beide scheringen is geëxperimenteerd met meerdere kleuren en soorten inslagen voor zowel grondbinding als patroondraad. Voor de inrijg is op de blauwe schering gekozen om te onderzoeken wat halve Z&W-blokken doen (inrijgingen 1-3-2-4 en 1-4-2-3). Bij de tweede schering is hier verder mee geëxperimenteerd.

Op beide scheringen is ook geëxperimenteerd met inslagpatronen voor de patroondraad. Er is gekeken naar het effect van het inslaan als singles, X- en O-paarsgewijs en kolomsgewijs, en het effect van welke van de twee linnenbindingsinslagen ertussen zitten. Ik neig naar het gebruik van één inslagpatroon voor het gehele werk. Waarschijnlijk zal dit O-paarsgewijs zijn. Dit element heeft nog meer experimentatie nodig tijdens het weven van de gekozen compositie.

Uit deze dubbele studie is gekomen dat blauwe patroondraden op een witte schering (en witte grondbinding) het meest passend lijkt bij het servies. Er is geëxperimenteerd met verschillende patroondraden, waaronder geel katoen en linnen om iets aan spanning te introduceren. Dat vond ik voor deze doelstelling toch niet zo mooi. Het ruwe karakter van linnen vond ik niet passend bij de verfijndheid van deze serviezen. Ook zijn er verschillende blauwe patroondraden gebruikt, waaronder 8/2 Ne gemerceriseerd katoen (zelf geverfd), 8/2 ongemerceriseerd katoen (koningsblauw van Venne), 33/2 Ne2 cottolin (lichtblauw, Garnhuset i Kinna) en 16/2 ongemerceriseerd katoen (zelf geverfd). Het glanzende van het gemerceriseerde katoen verbindt zoals gehoopt met het servies. Alle gebruikte soorten blauw zijn net niet een goede match met het servies. In verdere verfexperimenten (hier niet gedocumenteerd) heb ik een betere match kunnen vinden.

Het zelf geverfde garen heeft bewust verschillen in de kleurintensiteit, die de verschillende tinten van de Delftsblauwe schilderingen moeten voorstellen. Dit is deels een succes; ik wil nóg dramatischere verschillen in de garenkleuring aanbrengen. Dit effect zou deels reproduceerbaar zijn met óf meerdere garens, óf nog fijnere garens te kiezen met meer afwisseling van wit en blauw, door technieken van halftoon drukwerk te gebruiken. Daar zijn twee argumenten tegen voor te verzinnen: zomer & winter heeft al van nature halftoon-structuren; een nog groter contrast wordt moeilijk te bereiken met deze garendikte. Door te werken met een substantieel dunner garen en meer afwisseling van blokdichtheden (hoeveelheid wisseling tussen blokken A en B) zou dit wel kunnen, maar het ontwerpen van een patroon op groter niveau wordt dan wel érg uitdagend.

Voor het witte katoen in 16/2 Ne heb ik eerst geprobeerd naturel, ongebleekt katoen te bleken. Na enige tests kreeg ik dat toch niet heel consistent wit, of werd het materiaal bros. Er is daarom gekozen om hiervoor een nieuwe cone te bestellen.

Wat betreft garendiktes vond ik de 16/2 Ne wit ongemerceriseerd katoen voor schering op 12 dr/cm erg goed bevallen. Er zijn verfijnde patronen mogelijk, die samen weer grotere elementen kunnen vormen. Voor de grondbinding kies ik hetzelfde 16/2 Ne wit ongemerceriseerd katoen. Voor de patroondraad kies ik steeds één inslag van 8/2 gemerceriseerd, zelf geverfd katoen in Delftsblauwe tinten. Hiermee is het grondweefsel (linnenbinding) wél geweven met een vierkantsinstelling, maar wanneer een patroondraad wordt toegevoegd niet. Dit verlengt het ontwerp, wat voor servetten niet de bedoeling was, maar voor een omslagdoek juist goed uitkomt. Met 12 dr/cm, een projectbreedte van ongeveer 50 cm, en 4 dr/blok komen we uit op $12 \times 50 / 4 \approx 150$ blokken.

In [1]:
TOTAL_BLOCKS = 150

Ontwerpen van een tweebloks patroon¶

Een standaard gestreept of blokjespatroon kan ik natuurlijk zelf ontwerpen, of ik kan me richten op de wiskunde. Heel wat wiskundige rijen zijn om te zetten naar een tweebloks ontwerp. Het boek Summer and winter: a weave for all seasons van Donna Sullivan (1982), dat gratis te leen is in The Internet Archive, heeft de eerste ideeën hiervoor gegeven.

De Fibonacci-rij is misschien wel bekend. Twee opeenvolgende elementen $F_n$ en $F_{n+1}$ vormen een benadering van de gulden snede $\phi \approx F_{n+1} / F_n$. Een tijd werd er gedacht dat de gulden snede een verhouding was die door onder andere Leonardo da Vinci werd gebruikt, en daardoor zijn composities zo mooi waren. Ook werd beweerd dat de verhouding tussen ledematen, en de spiraal van schelpen van nautilussen verband zouden hebben met de gulden snede. Dat blijkt allemaal achterhaald te zijn, maar het kan desalniettemin mooie patronen opleveren.

De Lucas-rijen vormen een familie van rijen, waar de Fibonacci-rij ook in valt. Je kiest namelijk de startgetallen. Het $n$-de element uit de Lucas-rij $L^{a,b}$ met startgetallen $L^{a,b}_0 = a, L^{a,b}_1 = b$ is gedefinieerd als de som van de twee voorgaande elementen: $$ L^{a,b}_n := \begin{cases} a & \text{als } n = 0; \\ b & \text{als } n = 1; \\ L^{a,b}_{n-1}+L^{a,b}_{n-2} & \text{als } n > 1. \end{cases} $$

De Fibonacci-rij is dus een voorbeeld van de concrete Lucas-rij $F = L^{1,1}$.

Een eigenschap van Lucas-rijen die later handig blijkt, is dat de som van $L^{a,b}_0$ tot $L^{a,b}_{n-1}$ gelijk is aan $L^{a,b}_{n+1} - b$. We kunnen zo gemakkelijk uitrekenen hoeveel draden er gebruikt zullen worden door een deel van een Lucas-rij.

De notatie "van $L^{a,b}_0$ tot $L^{a,b}_{n}$" zal nog zo vaak voorkomen, dat ik dat afkort tot $L^{a,b}_{0:n}$. Let op: de rij $L^{a,b}_{0:n}$ bevat dus $L^{a,b}_{n-1}$ als grootste element.

Laten we code schrijven die elementen uit zo'n rij efficiënt kan berekenen. De eerste 10 waarden van de Fibonacci-rij $F_{0:10} = L^{1,1}_{0:10}$ zijn: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55.

In [2]:
from functools import cache

@cache
def lucas(a: int, b: int, n: int) -> int:
    """Compute a Lucas sequence from L_0 to L_{n-1}"""
    if n < 0:
        raise ValueError("n should be a positive integer.")
    if n == 0:
        return a
    if n == 1:
        return b
    return lucas(a, b, n-1) + lucas(a, b, n-2)

class LucasSequence(list[int]):
    def __init__(self, a: int, b: int, n: int, start=0):
        """
        Generate a Lucas sequence from L^{a, b}_0 up to but not including L^{a, b}_{n}.
        """
        super().__init__([lucas(a, b, i) for i in range(start, n)])
        self.a = a
        self.b = b
        self.n = n
        self.start = start

    def sum(self) -> int:
        """Efficient computation of sum of L^{a,b}_0 up to L^{a,b}_n."""
        return (lucas(self.a, self.b, self.n + 1) - self.b
                - (lucas(self.a, self.b, self.start + 1) - self.b))

    def __repr__(self) -> str:
        return f"{self.__class__.__name__}(a={self.a}, b={self.b}, n={self.n})"
    
sequence = LucasSequence(1, 1, 10)
print(sequence)
print(list(sequence))
print(sequence.sum())
LucasSequence(a=1, b=1, n=10)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
143

Profieltekeningen genereren¶

Om het ontwerpproces wat te versnellen, wil ik versimpelde profieltekeningen ook willen laten genereren. Daarvoor heb ik een eenvoudige generator gemaakt, die ik heb geschreven voor het weergeven van de verhoudingen tussen tweebloksontwerpen.

Wanneer de patroondraad over de schering gaat, is een vakje blauw gekleurd door deze generator, vanwege de blauwe patrooninslag. Anders zie je de witte schering. Ik heb geen inrijg-, inslag- of aanbindvlak erbij laten tekenen, omdat dat een grotere technische uitdaging werd (en de focus op weven ligt). De geselecteerde compositie zal wel worden uitgewerkt tot een complete bindingstekening in WinWeef.

In [3]:
from collections.abc import Iterable, Iterator, Sequence, Sized
import matplotlib.pyplot as plt
import matplotlib.colors as mpl_colors
import numpy as np
import os

FIGURE_NUMBER = 0

# Creating a custom color map, to fit this project, ranging
# from white to Delft Blue.
DelftBlueColormap = mpl_colors.ListedColormap(["white", "#1F305E"])

# Threadings and treadlings are a series of shaft or treadle 
# numbers. We're fairly flexible with what we want to do with 
# them, but most of the time, we will only use operators
# reverse and + on them.  In the rare case
DraftSequence = Iterable[int]

def generate_draft(threading: DraftSequence,
                   treadling: DraftSequence = None, 
                   tie_up: dict[int, list[int]] = None,
                   num_shafts: int = None,
                   title: str = None):
    """
    Generate a weaving draft from the threading and treadling.

    A rising shed loom (for example, a table loom) is assumed.
    
    Each element in threading corresponds to a warp thread.  The value of the 
    element is the shaft its heddle is connected to.  Each element in treadling
    corresponds to a weft pick, and its value is the number of the pressed 
    treadle.

    If no treadling is provided, writ as tromp is assumed.

    If tie_up is not provided, a direct tie-up is assumed.  Otherwise, you can
    provide a dictionary that maps treadle numbers to a list of connected
    shafts.

    You can provide a value for num_shafts if for some reason the number of
    shafts in your design should be a higher number than occurs in either 
    threading or connected shafts in tie_up.
    """
    global FIGURE_NUMBER

    if treadling is None:
        treadling = threading[:]

    if not isinstance(threading, Sized):
        threading = list(threading)
    if not isinstance(treadling, Sized):
        treadling = list(treadling)
    num_warp = len(threading)
    num_picks = len(treadling)

    if num_shafts is None:
        if tie_up is None:
            num_shafts = max(threading)
        else:
            num_shafts = max(threading, 
                            max(max(shafts) for shafts in tie_up.values()))
    
    if tie_up is None:
        # If none provided, generate a straight draw tie-up
        tie_up = {i + 1: [i + 1] for i in range(max(num_shafts,
                                                    max(treadling)))}

    draft = np.zeros((num_picks, num_warp))

    for pick_nr, treadle in enumerate(treadling):
        if treadle in tie_up:
            lifted_shafts = tie_up[treadle]
            for warp_thread, shaft in enumerate(threading):
                if shaft in lifted_shafts:
                    draft[pick_nr, warp_thread] = 1
    
    plt.imshow(draft, cmap=DelftBlueColormap)
    plt.axis("on")
    if title:
        title = f"Fig. {FIGURE_NUMBER}: {title}"
        plt.title(title)

    if not os.path.isdir("./figs"):
        os.mkdir("./figs")
    plt.savefig(f"./figs/fig-{FIGURE_NUMBER}.png", bbox_inches="tight")
    plt.show()
    FIGURE_NUMBER += 1


generate_draft([1, 2, 1, 2, 1, 2], [1, 1, 2, 2, 1, 1],
               title="Een simpele profieltekening.")
No description has been provided for this image

Lucas-rijen van ongeveer gewenste lengte¶

We hebben het al eerder gehad over het berekenen van de som van alle elementen in $L^{a,b}_{0:n}$. Dat wilden we zodat we dan ook weten hoeveel draden in de schering nodig zijn voor dat stuk van een Lucas-rij. Maar wat nou als dat aantal draden al (ongeveer) vaststaat?

We kunnen alleen maar hopen dat we een rij vinden die precies op ons gewenste aantal draden uitkomt. Daarom zoeken we maar meteen naar 2 waarden van $n$. De eerste waarde $n_1$ hoort bij de grootste rij $L^{a,b}_{0:n_1}$ waarvan de som nog onder onze richtwaarde $\tau$ zit. De tweede waarde $n_2$ hoort bij de kleinste rij $L^{a,b}_{0:n_2}$ waarvan de som precies gelijk of groter is aan $\tau$.

Ik had natuurlijk ook kunnen kiezen om $n_1$ zo te kiezen dat de som van $L^{a,b}_{0:n_1}$ kleiner dan of gelijk aan $\tau$ is, maar aangezien latere elementen in een Lucas-rij (veel) groter lijken te zijn, zorgt dit ervoor dat we dichter bij $\tau$ blijven.

De functie find_seq_by_sum(a, b, target) geeft deze twee rijen terug.

In [4]:
def find_seq_by_sum(a: int, b: int, target: int) -> tuple[LucasSequence, LucasSequence]:
    """
    Find 2 Lucas sequences L1 = L^{a, b}_{0..n}, L2 = L^{a, b}_{0..n+1} 
    such that sum(L1) < target <= sum(L2).
    """
    for n in range(target):
        if LucasSequence(a, b, n).sum() >= target:
            return (LucasSequence(a, b, n - 1), LucasSequence(a, b, n))
    raise ValueError("sum(L^{a,b}_i for i in range(target+2)) is not large "
                     "enough.  Are you sure this even exists?")

Compositie van één Lucas-rij¶

Laten we nu kijken naar een aantal mogelijke composities van deze basis. Deze composities blijven beperkt tot een tweebloks profieltekening, waarvan de meest interessante zullen worden uitgewerkt tot een complete bindingstekening, met WinWeef.

Bij name drafts converteren we betekenisvolle letters naar rijen schachtnummers, maar er zijn natuurlijk ook andere manieren om betekenisvolle expressies in je werk te verwerken. Bijvoorbeeld door de twee startwaarden te kiezen voor een Lucas-rij. In een eerder voorbeeld had ik al gekozen voor $a = 5, b = 2$, wat toen misschien wat willekeurig leek. Maar: ik woon op huisnummer 52. 52 als een van de eerste startwaarden kiezen, geeft wel een érg breed blok in dit geval, en dat is niet zo wenselijk.

Simpele rij¶

We kunnen nu een ontwerp voor een servet laten genereren met de Lucasrij $L^{5,2}$ zodanig dat de som van de elementen van de (sub-)rij zo dicht mogelijk bij het gewenste aantal zit.

In [5]:
def generate_block_profile(seq: list[int],
                           scheme: list[int] = [1, 2]) -> list[int]:
    """
    Generate a profile draft from a list of block repeats.
    
    Each element of seq represents the width of a block.
    
    A mapping from widths to block numbers can be provided as scheme.
    If none is provided, we assume alternating between blocks A and B.
    """
    threading = []
    for i, n in enumerate(seq):
        shaft = scheme[i % len(scheme)]
        threading += n * [shaft]
    return threading

A = 5
B = 2
approx_wanted_seqs = find_seq_by_sum(A, B, TOTAL_BLOCKS)
for seq in approx_wanted_seqs:
    threading = generate_block_profile(seq)
    generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                    f"blokken om en om"
                                    f"\n{len(threading)}×{len(threading)} blokken")
No description has been provided for this image
No description has been provided for this image

Spiegeling¶

Bovenstaande profieltekening op basis van ons huisnummer vind ik wat saai. Het nodigt uit om te spiegelen in zowel schering als inslag, maar dan wordt het totale weefsel wel érg groot. Dit zal een bol- of hol-effect geven, afhankelijk van welke kant in het midden zit. Ik vind dit niet héél interessant eruit zien; het lijkt op zaken die ik al eerder geweven heb als proeflap, en ik wil een nieuwer scenario.

In [6]:
def mirrored(seq: DraftSequence,
             left_to_right=True,
             repeat_middle=True) -> list[int]:
    """
    Join a sequence of numbers to a reversed version of itself.

    By default, the reversed list is appended to the right side. If you want
    to append it to the left side, set left_to_right=False.

    When you don't want to repeat the block that will be in the middle of the
    new sequence, set repeat_middle=False.
    """
    if left_to_right:
        original: list[int] = list(seq)
    else:
        original: list[int] = list(reversed(list(seq)))
    
    offset = 0
    if not repeat_middle:
        offset = 1

    reflection = []
    for i in reversed(range(len(original) - offset)):
        reflection.append(original[i])
    return original + reflection

# We herhalen een variant van deze reeks, en daarom delen we TOTAL_BLOCKS 
# door het aantal herhalingen.
approx_wanted_seqs = find_seq_by_sum(A, B, TOTAL_BLOCKS//2)

for seq in approx_wanted_seqs:
    threading = generate_block_profile(mirrored(seq))
    generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                    f"gespiegeld"
                                    f"\n{len(threading)}×{len(threading)} blokken")

    threading = generate_block_profile(mirrored(seq, left_to_right=False))
    generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                    f"binnenstebuiten gespiegeld"
                                    f"\n{len(threading)}×{len(threading)} blokken")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Tegengestelde richting¶

Een andere manier om een rij te herhalen is door de lengte van blokken A in aflopende volgorde van de reeks te laten bepalen, en van blokken B in oplopende volgorde. Door te wisselen welk van de twee blokken eerst mogen (A of B) krijgen we een andere sfeer.

Deze ontwerpen vind ik al wat boeiender eruit zien; er is wat meer contrast tussen grote en kleine vlakken. Door met korte blokken te beginnen ontstaat er een "rand" om het werk heen.

In [7]:
def interweave(seq_a: DraftSequence, seq_b: DraftSequence) -> list[int]:
    """
    Alternatingly, join elements from seq_a and seq_b in a single list.
    """
    result = []
    for item_a, item_b in zip(seq_a, seq_b):
        result += [item_a, item_b]
    return result

approx_wanted_seqs = find_seq_by_sum(A, B, TOTAL_BLOCKS//2)

for seq in approx_wanted_seqs:
    threading = generate_block_profile(interweave(seq, reversed(seq)))
    generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                    f"blokken in tegengestelde richting, "
                                    f"eerst blok A"
                                    f"\n{len(threading)}×{len(threading)} blokken")

    threading = generate_block_profile(interweave(reversed(seq), seq))
    generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                    f"blokken in tegengestelde richting, "
                                    f"eerst blok B"
                                    f"\n{len(threading)}×{len(threading)} blokken")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Gespiegelde tegengestelde richting¶

Bewerkingen kunnen natuurlijk ook elkaar opvolgen. Hier volgen een aantal ontwerpen waarbij eerst de rijen in tegengestelde richting zijn gelegd, en daarna nog eens zijn gespiegeld.

Ik merk nu op dat ik in het algemeen meer afwisseling tussen grote en kleine blokken interessanter vind dan wanneer blokken dicht bij elkaars grootte zitten (of "schijnblokken" vormen die dat doen, zoals "$L^{5,2}_{0:4}$ blokken in tegengestelde richting, gespiegeld, eerst blok A")

In [8]:
approx_wanted_seqs = find_seq_by_sum(A, B, TOTAL_BLOCKS//4)

for seq in approx_wanted_seqs:
    threading = generate_block_profile(mirrored(interweave(seq, reversed(seq))))
    generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                    f"blokken in tegengestelde richting, "
                                    f"gespiegeld, "
                                    f"eerst blok A"
                                    f"\n{len(threading)}×{len(threading)} blokken")

    threading = generate_block_profile(mirrored(interweave(reversed(seq), seq)))
    generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                    f"blokken in tegengestelde richting, "
                                    f"gespiegeld, "
                                    f"eerst blok B"
                                    f"\n{len(threading)}×{len(threading)} blokken")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Ongelijke aantallen¶

De lengtes van de twee rijen die in tegengestelde richting met elkaar worden samengevoegd kunnen 1 element meer of minder dan de andere bevatten. Dit zorgt voor een "symmetrisch" punt in het midden. Naar mijn smaak zijn de situaties waarin er een dunne streep in het midden is ontstaan wel érg druk, en gaan richting onwenselijk.

In [9]:
approx_wanted_seqs = find_seq_by_sum(A, B, TOTAL_BLOCKS//4)

for seq in approx_wanted_seqs:
    s = mirrored(interweave(seq, reversed(seq)) + [lucas(seq.a, seq.b, seq.n)],
                 repeat_middle=False)
    threading = generate_block_profile(s)
    generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                    f"blokken in tegengestelde richting, "
                                    f"ongelijke aantallen, "
                                    f"eerst blok A"
                                    f"\n{len(threading)}×{len(threading)} blokken")

    s = mirrored(reversed(interweave(seq, reversed(seq)) + [lucas(seq.a, seq.b, seq.n)]),
                 repeat_middle=False)
    threading = generate_block_profile(s)
    generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                    f"blokken in tegengestelde richting, "
                                    f"ongelijke aantallen, "
                                    f"eerst blok B"
                                    f"\n{len(threading)}×{len(threading)} blokken")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Inslag ≠ inrijg¶

Tot nu toe waren inslag en inrijg gelijk aan elkaar. Laten we eens kijken wat er gebeurt als we twee verschillende rijen daarvoor kiezen. Als tweede rij gebruik ik $L^{1,4}$, aangezien mijn kat 14 jaar oud is. De ontwerpen zijn moeilijk vierkant te krijgen, aangezien verschillende Lucas-rijen snel uiteen lopen qua waarden, maar ik zou er altijd voor kunnen kiezen om maar een gedeelte van de gegenereerde bindingstekening te weven. Voor wat meer inzicht laat ik ook de verhouding tussen breedte en hoogte op de afbeeldingen schrijven.

Simpel, twee rijen¶

Wat deze ontwerpen anders maakt dan de experimenten uit Simpele rij, is hun verhouding. We hebben geen vierkant stuk meer, maar werken met een rechthoek. Dat is niet wat ik zoek voor dit project; voor mijn gevoel zouden deze servetten vierkant moeten zijn. Ook vind ik dit niet genoeg spanning in het ontwerp creëren ten opzichte van de eerste experimenten.

In [10]:
A_2 = 1
B_2 = 4

approx_wanted_threading = find_seq_by_sum(A, B, TOTAL_BLOCKS)
approx_wanted_treadling = find_seq_by_sum(A_2, B_2, TOTAL_BLOCKS)
for seq1 in approx_wanted_threading:
    threading = generate_block_profile(seq1)
    for seq2 in approx_wanted_treadling:
        treadling = generate_block_profile(seq2)
        generate_draft(threading, treadling, title=f"$L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                   f"en $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                   f"blokken om en om"
                                                   f"\n1 : {len(treadling)/len(threading):.2f}"
                                                   f"\n{len(threading)}×{len(treadling)} blokken")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Spiegeling, twee rijen¶

In deze ontwerpen ontstaat er al wat meer spanning dan in de vorige serie, en is de verhouding tussen breedte en hoogte meer richting $1:1$. Alsnog voelen ze wat simpel aan.

In [11]:
approx_wanted_threading = find_seq_by_sum(A, B, TOTAL_BLOCKS//2)
approx_wanted_treadling = find_seq_by_sum(A_2, B_2, TOTAL_BLOCKS//2)

for seq1 in approx_wanted_threading:
    threading = generate_block_profile(mirrored(seq1))
    for seq2 in approx_wanted_treadling:
        treadling = generate_block_profile(mirrored(seq2, left_to_right=False))
        generate_draft(threading, treadling, title=f"$L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                   f"en $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                   f"gespiegeld"
                                                   f"\n1 : {len(treadling)/len(threading):.2f}"
                                                   f"\n{len(threading)}×{len(treadling)} blokken")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Tegengestelde richting, twee rijen¶

Hoewel er minder spanning is, voelen de ontwerpen in deze serie voor mij toch wel boeiend om naar te kijken. Er is een soort symmetrie over een diagonaal ontstaan. Ik denk dat dit nog niet is wat ik zoek, maar deze ontwerpstrategie houdt wel langer m'n interesse vast.

In [12]:
approx_wanted_threading = find_seq_by_sum(A, B, TOTAL_BLOCKS//2)
approx_wanted_treadling = find_seq_by_sum(A_2, B_2, TOTAL_BLOCKS//2)

for seq1 in approx_wanted_threading:
    threading1 = generate_block_profile(interweave(seq1, reversed(seq1)))
    threading2 = generate_block_profile(interweave(reversed(seq1), seq1))
    for seq2 in approx_wanted_treadling:
        treadling = generate_block_profile(interweave(seq2, reversed(seq2)))
        generate_draft(threading1, treadling, title=f"$L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"eerst blok A"
                                                    f"\n1 : {len(treadling)/len(threading1):.2f}"
                                                    f"\n{len(threading1)}×{len(treadling)} blokken")
        generate_draft(threading2, treadling, title=f"rev. $L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"eerst blok B"
                                                    f"\n1 : {len(treadling)/len(threading2):.2f}"
                                                    f"\n{len(threading2)}×{len(treadling)} blokken")

        treadling = generate_block_profile(interweave(reversed(seq2), seq2))
        generate_draft(threading1, treadling, title=f"$L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en rev. $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"eerst blok A"
                                                    f"\n1 : {len(treadling)/len(threading1):.2f}"
                                                    f"\n{len(threading1)}×{len(treadling)} blokken")
        generate_draft(threading2, treadling, title=f"rev. $L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en rev. $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"eerst blok B"
                                                    f"\n1 : {len(treadling)/len(threading2):.2f}"
                                                    f"\n{len(threading2)}×{len(treadling)} blokken")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Gespiegelde tegengestelde richting, twee rijen¶

In deze serie lijkt er herhaling van het patroon plaats te vinden. Gegeven de gewenste grootte van het project, denk ik niet dat ik dit ontwerp vaak genoeg kan herhalen om echt het herhalende aspect te benadrukken.

In [13]:
approx_wanted_threading = find_seq_by_sum(A, B, TOTAL_BLOCKS//4)
approx_wanted_treadling = find_seq_by_sum(A_2, B_2, TOTAL_BLOCKS//4)

for seq1 in approx_wanted_threading:
    threading1 = generate_block_profile(mirrored(interweave(seq1, reversed(seq1))))
    threading2 = generate_block_profile(mirrored(interweave(reversed(seq1), seq1)))
    for seq2 in approx_wanted_treadling:
        treadling = generate_block_profile(mirrored(interweave(seq2, reversed(seq2))))
        generate_draft(threading1, treadling, title=f"$L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"gespiegeld, "
                                                    f"eerst blok A"
                                                    f"\n1 : {len(treadling)/len(threading1):.2f}"
                                                    f"\n{len(threading1)}×{len(treadling)} blokken")
        generate_draft(threading2, treadling, title=f"rev. $L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"gespiegeld, "
                                                    f"eerst blok B"
                                                    f"\n1 : {len(treadling)/len(threading2):.2f}"
                                                    f"\n{len(threading2)}×{len(treadling)} blokken")

        treadling = generate_block_profile(mirrored(interweave(reversed(seq2), seq2)))
        generate_draft(threading1, treadling, title=f"$L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en rev. $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"gespiegeld, "
                                                    f"eerst blok A"
                                                    f"\n1 : {len(treadling)/len(threading1):.2f}"
                                                    f"\n{len(threading1)}×{len(treadling)} blokken")
        generate_draft(threading2, treadling, title=f"rev. $L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en rev. $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"gespiegeld, "
                                                    f"eerst blok B"
                                                    f"\n1 : {len(treadling)/len(threading2):.2f}"
                                                    f"\n{len(threading2)}×{len(treadling)} blokken")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Ongelijke aantallen, twee rijen¶

De ontwerpen die uit deze serie komen vind ik wel wat interessants hebben; er zijn weer veel afwisselingen tussen lange en korte blokken, waardoor ik er wat langer naar blijf kijken. Maar keuzes maken waar het denkbeeldige mes moet komen om het op een vierkant ontwerp te laten passen, vind ik toch moeilijk.

In [14]:
approx_wanted_threading = find_seq_by_sum(A, B, TOTAL_BLOCKS//4)
approx_wanted_treadling = find_seq_by_sum(A_2, B_2, TOTAL_BLOCKS//4)

for seq1 in approx_wanted_threading:
    s = mirrored(interweave(seq1, reversed(seq1)) + [lucas(seq1.a, seq1.b, seq1.n)], repeat_middle=False)
    threading1 = generate_block_profile(s)
    s = mirrored(reversed(interweave(seq1, reversed(seq1)) + [lucas(seq1.a, seq1.b, seq1.n)]), repeat_middle=False)
    threading2 = generate_block_profile(s)
    for seq2 in approx_wanted_treadling:
        s = mirrored(interweave(seq2, reversed(seq2)) + [lucas(seq2.a, seq2.b, seq2.n)], repeat_middle=False)
        treadling = generate_block_profile(s)
        generate_draft(threading1, treadling, title=f"$L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"ongelijke aantallen, "
                                                    f"eerst blok A"
                                                    f"\n1 : {len(treadling)/len(threading1):.2f}"
                                                    f"\n{len(threading1)}×{len(treadling)} blokken")
        generate_draft(threading2, treadling, title=f"rev. $L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"ongelijke aantallen, "
                                                    f"eerst blok B"
                                                    f"\n1 : {len(treadling)/len(threading2):.2f}"
                                                    f"\n{len(threading2)}×{len(treadling)} blokken")

        s = mirrored(reversed(interweave(seq2, reversed(seq2)) + [lucas(seq2.a, seq2.b, seq2.n)]), repeat_middle=False)
        treadling = generate_block_profile(s)
        generate_draft(threading1, treadling, title=f"$L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en rev. $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"ongelijke aantallen, "
                                                    f"eerst blok A"
                                                    f"\n1 : {len(treadling)/len(threading1):.2f}"
                                                    f"\n{len(threading1)}×{len(treadling)} blokken")
        generate_draft(threading2, treadling, title=f"rev. $L^{{{seq1.a},{seq1.b}}}_{{0:{seq1.n}}}$ "
                                                    f"en rev. $L^{{{seq2.a}, {seq2.b}}}_{{0:{seq2.n}}}$, "
                                                    f"blokken in tegengestelde richting, "
                                                    f"ongelijke aantallen, "
                                                    f"eerst blok B"
                                                    f"\n1 : {len(treadling)/len(threading2):.2f}"
                                                    f"\n{len(threading2)}×{len(treadling)} blokken")
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image
No description has been provided for this image

Handmatige aanpassingen¶

In [15]:
seq = LucasSequence(5, 2, 5)
threading = generate_block_profile(mirrored(interweave(reversed(seq), seq)))
treadling = threading[:]
threading[108:110] = [2, 2]
threading[124:126] = [1, 1]
print(f"{len(threading)} dr")
generate_draft(threading, title=f"$L^{{{seq.a},{seq.b}}}_{{0:{seq.n}}}$, "
                                f"blokken in tegengestelde richting, "
                                f"gespiegeld, "
                                f"eerst blok B, met handmatig gebroddel"
                                f"\n{len(threading)}×{len(threading)} blokken")
156 dr
No description has been provided for this image

Niet geheel wiskundige ontwerpen¶

Hier volgt een rij ontwerpen die 3 banen bevatten die elk op een rij zijn gebaseerd; één middelste baan op basis van $L^{1,4}$ (onze kat Niks is 14 jaar oud), en twee "buitenranden" van $L^{5,2}$ (het huisnummer weer). De breedte van de banen worden dynamisch bepaald. De buitenranden zijn max. 40% van het gehele ontwerp breed. Ze zijn gemaakt uit de kleinere rij die find_seq_by_sum(...) vindt voor een rij van 20% van TOTAL_BLOCKS. Deze rij wordt gespiegeld rondom het grootste blok herhaald. De middenbaan neemt zoveel mogelijk van de overgebleven blokken in beslag.

Voor de middelste baan neem ik zo'n smalle sectie, zodat er meer overblijft voor de middenbaan. Uit onderstaande proefjes merk ik op dat ik de overgang tussen de smalle patroontjes van de gespiegelde $L^{5,2}$-rij naar de brede gespiegelde, omgekeerde $L^{1,4}$ boeiende fish eye lensing-effecten vind geven, doordat er vanuit het midden naar de hoeken een opbouw naar grotere vlakken ontstaat, die bijna abrupt wordt omgezet naar kleine vlakken. Er treedt een variatie op de diepte-illusies van de ontwerpen uit Simpele rij en Spiegeling, die niet met het gebruiken van één rij zou lukken.

In [16]:
blocks_left = TOTAL_BLOCKS

border_seq = find_seq_by_sum(5, 2, blocks_left//5)[0]
border = mirrored(border_seq,
                  repeat_middle=False)
blocks_left -= 2*sum(border)

center_seq = find_seq_by_sum(1, 4, blocks_left//2)[1]
center = mirrored(center_seq,
                  repeat_middle=False)
blocks_left -= sum(center)

print(f"{border = }")
print(f"{center = }")
print(f"{blocks_left = }")

threading = generate_block_profile(border + center + border)
generate_draft(threading, title=f"$L^{{{border_seq.a},{border_seq.b}}}_{{0:{border_seq.n}}}$ "
                                f"gespiegeld voor randen, "
                                f"$L^{{{center_seq.a},{center_seq.b}}}_{{0:{center_seq.n}}}$ voor midden"
                                f"\n{len(threading)}×{len(threading)} blokken")
border = [5, 2, 7, 9, 7, 2, 5]
center = [1, 4, 5, 9, 14, 23, 14, 9, 5, 4, 1]
blocks_left = -13
No description has been provided for this image
In [17]:
blocks_left = 150

border_seq = find_seq_by_sum(5, 2, blocks_left//8)[0]
border = mirrored(border_seq,
                  repeat_middle=False)
blocks_left -= 2*sum(border)

center_seq = find_seq_by_sum(1, 4, blocks_left//2)[1]
center = mirrored(reversed(center_seq),
                  repeat_middle=False)
blocks_left -= sum(center)

print(f"{border = }")
print(f"{center = }")
print(f"{blocks_left = }")

threading = generate_block_profile(border + center + border)
generate_draft(threading, title=f"$L^{{{border_seq.a},{border_seq.b}}}_{{0:{border_seq.n}}}$ "
                                f"gespiegeld voor randen, "
                                f"rev. $L^{{{center_seq.a},{center_seq.b}}}_{{0:{center_seq.n}}}$ voor midden"
                                f"\n{len(threading)}×{len(threading)} blokken")
border = [5, 2, 7, 2, 5]
center = [23, 14, 9, 5, 4, 1, 4, 5, 9, 14, 23]
blocks_left = -3
No description has been provided for this image
In [18]:
blocks_left = 150

border_seq = find_seq_by_sum(5, 2, blocks_left//8)[1]
border = mirrored(border_seq,
                  repeat_middle=False)
blocks_left -= 2*sum(border)

center_seq = find_seq_by_sum(1, 4, blocks_left//2)[1]
center = mirrored(reversed(center_seq),
                  repeat_middle=False)
blocks_left -= sum(center)

print(f"{border = }")
print(f"{center = }")
print(f"{blocks_left = }")

threading = generate_block_profile(border + center + border)
generate_draft(threading, title=f"$L^{{{border_seq.a},{border_seq.b}}}_{{0:{border_seq.n}}}$ "
                                f"gespiegeld voor randen, "
                                f"rev. $L^{{{center_seq.a},{center_seq.b}}}_{{0:{center_seq.n}}}$ voor midden"
                                f"\n{len(threading)}×{len(threading)} blokken")
border = [5, 2, 7, 9, 7, 2, 5]
center = [23, 14, 9, 5, 4, 1, 4, 5, 9, 14, 23]
blocks_left = -35
No description has been provided for this image
In [19]:
blocks_left = 150

border_seq = find_seq_by_sum(5, 2, blocks_left//8)[1]
border = mirrored(border_seq,
                  repeat_middle=False)
blocks_left -= 2*sum(border)

center_seq = find_seq_by_sum(1, 4, blocks_left//2)[0]
center = mirrored(reversed(center_seq),
                  repeat_middle=False)
blocks_left -= sum(center)

print(f"{border = }")
print(f"{center = }")
print(f"{blocks_left = }")

threading = generate_block_profile(border + center + border)
generate_draft(threading, title=f"$L^{{{border_seq.a},{border_seq.b}}}_{{0:{border_seq.n}}}$ "
                                f"gespiegeld voor randen, "
                                f"rev. $L^{{{center_seq.a},{center_seq.b}}}_{{0:{center_seq.n}}}$ voor midden"
                                f"\n{len(threading)}×{len(threading)} blokken")
border = [5, 2, 7, 9, 7, 2, 5]
center = [14, 9, 5, 4, 1, 4, 5, 9, 14]
blocks_left = 11
No description has been provided for this image
In [20]:
blocks_left = 150

border_seq = find_seq_by_sum(5, 2, blocks_left//8)[1]
border = mirrored(border_seq,
                  repeat_middle=False)
blocks_left -= sum(border)

center_seq = find_seq_by_sum(1, 4, blocks_left//2)[1]
center = mirrored(reversed(center_seq),
                  repeat_middle=False)
blocks_left -= sum(center)

print(f"{border = }")
print(f"{center = }")
print(f"{blocks_left = }")

threading = generate_block_profile(border + center)
generate_draft(threading, title=f"$L^{{{border_seq.a},{border_seq.b}}}_{{0:{border_seq.n}}}$ "
                                f"gespiegeld voor één rand, "
                                f"rev. $L^{{{center_seq.a},{center_seq.b}}}_{{0:{center_seq.n}}}$ voor de rest"
                                f"\n{len(threading)}×{len(threading)} blokken")
border = [5, 2, 7, 9, 7, 2, 5]
center = [23, 14, 9, 5, 4, 1, 4, 5, 9, 14, 23]
blocks_left = 2
No description has been provided for this image
In [21]:
blocks_left = 150

border_seq = find_seq_by_sum(1, 4, blocks_left//8)[0]
border = mirrored(reversed(border_seq),
                  repeat_middle=False)
blocks_left -= 2*sum(border)

center_seq = find_seq_by_sum(5, 2, blocks_left//2)[1]
center = mirrored(reversed(center_seq),
                  repeat_middle=False)
blocks_left -= sum(center)

print(f"{border = }")
print(f"{center = }")
print(f"{blocks_left = }")


threading = generate_block_profile(border + center + border)
generate_draft(threading, title=f"rev. $L^{{{border_seq.a},{border_seq.b}}}_{{0:{border_seq.n}}}$ "
                                f"gespiegeld voor randen, "
                                f"rev. $L^{{{center_seq.a},{center_seq.b}}}_{{0:{center_seq.n}}}$ voor midden"
                                f"\n{len(threading)}×{len(threading)} blokken")
border = [5, 4, 1, 4, 5]
center = [25, 16, 9, 7, 2, 5, 2, 7, 9, 16, 25]
blocks_left = -11
No description has been provided for this image
In [22]:
blocks_left = 120

border_seq = find_seq_by_sum(1, 4, blocks_left//8)[0]
border = mirrored(reversed(border_seq),
                  repeat_middle=False)
blocks_left -= 2*sum(border)

center_seq = find_seq_by_sum(5, 2, blocks_left//2)[0]
center = mirrored(reversed(center_seq),
                  repeat_middle=False)
blocks_left -= sum(center)

print(f"{border = }")
print(f"{center = }")
print(f"{blocks_left = }")

threading = generate_block_profile(border + center + border)
generate_draft(threading, title=f"rev. $L^{{{border_seq.a},{border_seq.b}}}_{{0:{border_seq.n}}}$ "
                                f"gespiegeld voor randen, "
                                f"rev. $L^{{{center_seq.a},{center_seq.b}}}_{{0:{center_seq.n}}}$ voor midden"
                                f"\n{len(threading)}×{len(threading)} blokken")
border = [5, 4, 1, 4, 5]
center = [16, 9, 7, 2, 5, 2, 7, 9, 16]
blocks_left = 9
No description has been provided for this image

Geselecteerde compositie¶

Ik heb gekozen voor een ontwerp uit Niet geheel wiskundig ontwerpen, waarbij een compositie van meerdere bewerkte Lucas-rijen is gemaakt.

Mijn twee favoriete kandidaten voor dit project zijn de laatste twee ontwerpen uit die sectie: "rev. $L^{1,4}_{0:3}$ gespiegeld voor randen, rev. $L^{5,2}_{0:6}$ voor midden" (161×161 blokken) en "rev. $L^{1,4}_{0:3}$ gespiegeld voor randen, rev. $L^{5,2}_{0:5}$ voor midden" (111×111 blokken). Om strict binnen de gegeven richtlijnen van de opdracht te voldoen, zal ik voor de 111-bloksversie moeten gaan. Maar het ontwerp van 161 blokken heeft mijn voorkeur; het contrast met de grote blokken uit $L^{5,2}_5$ en de kleine blokken (die toch op hun grootst zijn) uit $L^{1,4}_{0:3}$ geven net meer speelsigheid en dynamiek. Daarentegen past het ontwerp van 111 blokken wel binnen de door de wedstrijd meegegeven ontwerpkaders; 161 blokken wordt daarvoor te groot.

Door persoonlijke omstandigheden heb ik uiteindelijk moeten besluiten niet mee te doen met de servetontwerpwedstrijd. Daarmee kan ik ook de harde afmetingseis loslaten, en maken wat mijn eigen voorkeur heeft. Dat is dus het 161-bloks ontwerp, wat ik wil gaan gebruiken voor een omslagdoek aangezien ik zelden een servet gebruik. Ik heb gekozen om het ontwerp nog langer te maken, met een compositie van border + center + border + center + border te weven.

In [23]:
blocks_left = 150

border_seq = find_seq_by_sum(1, 4, blocks_left//8)[0]
border = mirrored(reversed(border_seq),
                  repeat_middle=False)
blocks_left -= 2*sum(border)

center_seq = find_seq_by_sum(5, 2, blocks_left//2)[1]
center = mirrored(reversed(center_seq),
                  repeat_middle=False)
blocks_left -= sum(center)

print(f"{border = }")
print(f"{center = }")
print(f"{blocks_left = }")

threading = generate_block_profile(border + center + border)
treadling = generate_block_profile(border + center + border + center + border)
generate_draft(threading, treadling,
               title=f"rev. $L^{{{border_seq.a},{border_seq.b}}}_{{0:{border_seq.n}}}$ "
                     f"gespiegeld voor randen, "
                     f"rev. $L^{{{center_seq.a},{center_seq.b}}}_{{0:{center_seq.n}}}$ voor midden,"
                     f"\nverlengd in inslag met nogmaals $L^{{{center_seq.a},{center_seq.b}}}_{{0:{center_seq.n}}}$"
                     f" + $L^{{{border_seq.a},{border_seq.b}}}_{{0:{border_seq.n}}}$"
                     f"\n{len(threading)}×{len(treadling)} blokken")
border = [5, 4, 1, 4, 5]
center = [25, 16, 9, 7, 2, 5, 2, 7, 9, 16, 25]
blocks_left = -11
No description has been provided for this image

Detaillering¶

Ik ga dit project weven op mijn Louët Jane van 70 cm weefbreedte, met 16 schachten. Het is een tafelgetouw, en daarom vind ik het in dit geval prettiger om een schema met hefplan in WinWeef te genereren.

Ik heb de profieltekening uit deze notities overgenomen in WinWeef. Om tot een bindingstekening zonder grondbinding te komen (zoals gebruikelijk voor zomer en winter), heb ik de volgende stappen uitgevoerd:

  • Voor de schering moet elk profielblok op profielschacht $A$ of $B$ worden omgezet naar inrijg $1, x, 2, x$, waarbij $x$ gelijk is aan een patroonschacht ($A$ wordt gekoppeld aan $3$, $B$ wordt gekoppeld aan $4$). Na het laatste blok komt nog een scheringdraad op schacht 1.

    1. Wissel naar Werken met blokken (F2). Bij rijging: Blok over alles → Uitrekken (Ctrl+U), invoer: 2.
    2. Menu Technieken → Rijging bindrapport. Hoogte rapport: 2. Breedte rapport: 4.
    3. In Weefplan (Ctrl+W): verhoog Max. lengte rijging met 1.
    4. Wissel naar Tekenen (F2). Aan rechterzijde die ene draad op schacht 1 inrijgen.
  • Voor de inslag moet elk profielblok op trapper A of B worden omgezet naar trapwijze $1+x, 2+x, 2+x, 1+x$, waarbij $x$ gelijk is aan de patroonschacht van het te weven profielblok.

    1. Wissel naar Werken met blokken (F2). Bij trapwijze: Blok over alles → Uitrekken (Ctrl+U), invoer: 4.
    2. In Weefplan (Ctrl+W): verhoog Aantal trappers met 2. Laat deze twee trappers invoegen voor trapper 1.
    3. Menu Technieken → Ontwerpen hefplan. Ga naar tabblad Compact.
    4. Teken in een van deze vierkantjes de trapwijze in zonder de patroonschacht. Klik daarna op Vul.
    5. Klik op Importeer.
    6. Klik op Uitvoeren, en daarna op OK.
  • Om ook de grondbinding in te tekenen, heb ik de volgende stappen gevolgd. Deze bewerking kan niet in hefplan-modus, dus wisselen we kort naar Aanbinding en gaan dan weer terug.

    1. In Weefplan (Ctrl+W): verander Aanbinding en trappers naar Aanbinding.
    2. Menu Technieken → Trapwijze bindinslag. Selecteer Zomer-en-winter-aanbinding. Bindinslag: Beginnend even.
    3. In Weefplan (Ctrl+W): verander Aanbinding en trappers naar Hefplan.

    Ik heb de drie ontwerpstadia (profieltekening, bindingstekening zonder grondbinding en bindingstekening met grondbinding) beschikbaar in zowel WinWeef .wf2-format als algemeen WIF-format.

Realisatie¶

Ik heb het project opgezet zoals hierboven beschreven. Ik heb een 40/10-riet gebruikt, en ingeregen met 3 dr/opening. Er waren twee inrijgfoutjes naast elkaar gekomen, waarbij er 4 dr/opening waren. Dit is in het werk terug te zien als een meer prominente witte streep. Aan het begin en einde van het werk heb ik een kort stukje linnenbinding in wit gemaakt, wat ik wel mooi vond staan.

Omdat ik het garen al had geverfd toen ik één of twee servetten wilde weven, en de sjaal beduidend langer dan dat is geworden, heb ik voor de overige inslagen een nieuwe patroondraad geverfd. Er is een kleurverschil te zien; zowel de tint, intensiteit als de gestreeptheid van het garen zijn anders. Dit komt omdat mijn verfaantekeningen niet compleet genoeg waren.

Ik heb ervoor gekozen voor een open zoomsteek aan beide uiteindes. Ik heb de scheringeindjes eerst in grote bundels gevochten, het textiel met de hand gewassen, laten drogen, gestreken, en daarna de lange scheringeindjes kort geknipt. Ik heb ervoor gekozen ze niet verder te bewerken. Ik heb gedraaide franjes overwogen en een franjedraaier gefabriceerd, maar dat vond ik te stijf worden bij het eindproduct. Een langer vlechtwerk vond ik ook niet passen bij de hoekige vormen van dit werk.

Foto van het gehele product. Product ligt op de vloer. Franjes zijn nog erg lang. Het product ligt nog wat kreukelig. Foto van het gehele product. Product ligt op een herfstige tuintafel. Franjes zijn ingekort. Het product ligt glad en is gestreken.
Foto 1 en 2. Foto's van het gehele product, zowel onafgewerkt (links) als afgewerkt (rechts).
Closeup-foto van de O-zijde van deze zomer en winter. Closeup-foto van de X-zijde van deze zomer en winter.
Foto 3 en 4. Closeup van voor- en achterkant van het weefsel. Aan de voorkant zijn de O's wel te zien, maar aan de achterkant zijn de X'en minder zichtbaar.
Closeup van het weefsel waar de patroondraden uit twee verschillende verfsessies zijn gebruikt.
Foto 5. Closeup van het weefsel waar de patroondraden uit beide verfbaden zijn gebruikt. Boven is het garen uit het tweede bad te zien. De kleurtint, kleurintensiteit en de onderlinge verschillen op het garen zijn zichtbaar anders. Het witte garen lijkt lichtblauw door de hoeveelheid donkerder blauw in dat gedeelte.
Closeup van de rand van het weefsel.  Franjes zijn kort. Er is een open zoomsteek toegepast.
Foto 6. Closeup van de rand van het weefsel. De afwerking met de open zoomsteek en de afgeknipte, "ongedraaide" franjes zijn zichtbaar.

Conclusie en evaluatie¶

Het ontwerptraject heeft enkele bochten gekend, waarmee ik van servet naar omslagdoek ben gegaan. Ik heb ervaren dat ik goed kan werken wanneer ik een eindproduct in gedachten neem. Het thema dat ik in de servetten-fase heb opgepikt, is wel overeind gebleven. Het eindproduct is naar eigen smaak afgerond, en ik verwacht het nog een lange tijd te gebruiken.

De typische X'en van deze inslagvolgorde zijn niet zo goed te zien aan de achterkant van het product. Ik verwacht dat hier drie factoren samen dit wat moeilijker te zien maken voor het brein:

  • Er is een patroon in zowel garen als weefsel. Blijkbaar is het patroon in het garen meer aanwezig, en komt het patroon in het weefsel daardoor minder naar de voorgrond.
  • Er is geen vierkantsinstelling voor de patroondraad. Hierdoor zijn de X'en langwerpiger en worden ze ook minder makkelijk waargenomen.
  • Twee dezelfde patrooninslagen liggen nu dicht tegen elkaar aan, met wat ruimte tussen de volgende twee. Experimenten met de volgorde van de linnenbindingsinslagen zouden kunnen laten zien of dit een ander effect teweeg zal brengen.

Waarom de O's aan de voorkant van het product beter uitkomen, begrijp ik nog niet helemaal.

Maar ook al voldoet dit niet aan mijn oorspronkelijke plan: het eindproduct ligt wel in mijn smaak. Ik wilde een grotere variatie aan blauwtinten hebben, dan er door de halftonen van zomer en winter zouden ontstaan, en dat is gelukt. Op een grotere afstand lijkt de sjaal een licht gestreept, waterverf-achtig karakter te hebben. Ook het gebruik van ongemerceriseerd en gemercericeerd katoen heeft het gewenste effect bereikt; er is wel wát glans, maar niet al te veel.