s použitím Elixiru, SVG a Poisson disc samplingu
Chtěla jsem si vytvořit algoritmus na generování navazujících vzorů. Vygenerovat dlaždici, na které budou prvky „náhodně“ rozmístěné pomocí Poisson disc samplingu tak, aby na sebe protilehlé okraje navazovaly a mohla jsem ji použít do opakujícího se vzoru.
Tady je pár poznámek k postupu a nějaké obrázky, jakýsi záznam programování – potřebovala jsem si na něčem zobrazit, jak mi algoritmus funguje, tak jsem narychlo použila ty nejjednodušší SVG objekty – kruhy a čtverce. Některé výstupy vypadaly hezky nebo zajímavě, tak jsem si občas udělala screenshot – z čehož nakonec neplánovaně vzniká tenhle článek.
Rozmístění objektů na jedné dlaždici
Pro výpočet souřadnic objektů jsem musela trochu upravit svůj Poisson disc algoritmus – přidat kromě hlídání minimální vzdálenosti mezi jednotlivými body (jak je jeho smyslem) také hlídání, zda body poblíž okrajů dlaždice mají minimální vzdálenost i od bodů na případných sousedících dlaždicích. Až jich poskládám víc vedle sebe, aby se okolo linií, kde se dlaždice dotýkají, objekty neshlukovaly nebo nepřekrývaly.
Navazování dlaždic v SVG
Když pak na příslušných souřadnicích vygeneruju objekty, ty, které jsou větší a střed mají blízko okraje dlaždice, někdy částečně přesahují mimo. Na protilehlém okraji dlaždice bych naopak potřebovala, aby se mi v ní tenhle kousek objektu zobrazil – aby na sebe vzor na okrajích navazoval.
To zařídím v SVG. Při vytváření „dlaždice“ a vykreslování objektů (v mém případě předdefinovaných v defs) objekt vykreslím nejen na jeho pozici, ale vykreslím i jeho „kopie“, které by byly na sousedících dlaždicích – tedy souřadnice vždy posunu o šířku/výšku dlaždice. Pokud je tedy některý objekt např. na levém kraji dlaždice a přečnívá ven, jeho kopie vpravo bude naopak přečnívat směrem do dlaždice – ve výsledku se mi tedy ve výřezu (v pattern dané šířky a délky) zobrazí i části objektů přesahující ze sousedících dlaždic – protilehlé strany dlaždice tak na sebe budou plynule navazovat.
< pattern id="my_pattern" patternUnits="userSpaceOnUse" width="<%= @pattern_w %>" height="<%= @pattern_h %>"> <%= for object <- @pattern_objects do %> < use href="#<%= object.name %>" fill="<%= object.color %>" x="<%= object.x %>" y="<%= object.y %>" /> < use href="#<%= object.name %>" fill="<%= object.color %>" x="<%= object.x + @pattern_w %>" y="<%= object.y %>" /> < use href="#<%= object.name %>" fill="<%= object.color %>" x="<%= object.x %>" y="<%= object.y + @pattern_h %>" /> ... <% end %> < /pattern>