mirror of
https://github.com/bspeice/speice.io
synced 2024-12-22 16:48:10 -05:00
115 lines
164 KiB
HTML
115 lines
164 KiB
HTML
|
<!doctype html><html lang=en dir=ltr class="blog-wrapper blog-post-page plugin-blog plugin-id-default" data-has-hydrated=false><meta charset=UTF-8><meta name=generator content="Docusaurus v3.6.1"><title data-rh=true>Playing with fire: Transforms and variations | The Old Speice Guy</title><meta data-rh=true name=viewport content="width=device-width,initial-scale=1.0"><meta data-rh=true name=twitter:card content=summary_large_image><meta data-rh=true property=og:url content=https://speice.io/2024/11/playing-with-fire-transforms><meta data-rh=true property=og:locale content=en><meta data-rh=true name=docusaurus_locale content=en><meta data-rh=true name=docusaurus_tag content=default><meta data-rh=true name=docsearch:language content=en><meta data-rh=true name=docsearch:docusaurus_tag content=default><meta data-rh=true property=og:title content="Playing with fire: Transforms and variations | The Old Speice Guy"><meta data-rh=true name=description content="Now that we've learned about the chaos game, it's time to spice things up. Variations create the"><meta data-rh=true property=og:description content="Now that we've learned about the chaos game, it's time to spice things up. Variations create the"><meta data-rh=true property=og:type content=article><meta data-rh=true property=article:published_time content=2024-12-16T21:31:00.000Z><link data-rh=true rel=icon href=/img/favicon.ico><link data-rh=true rel=canonical href=https://speice.io/2024/11/playing-with-fire-transforms><link data-rh=true rel=alternate href=https://speice.io/2024/11/playing-with-fire-transforms hreflang=en><link data-rh=true rel=alternate href=https://speice.io/2024/11/playing-with-fire-transforms hreflang=x-default><script data-rh=true type=application/ld+json>{"@context":"https://schema.org","@id":"https://speice.io/2024/11/playing-with-fire-transforms","@type":"BlogPosting","author":{"@type":"Person","name":"Bradlee Speice"},"dateModified":"2024-12-17T02:30:05.000Z","datePublished":"2024-12-16T21:31:00.000Z","description":"Now that we've learned about the chaos game, it's time to spice things up. Variations create the","headline":"Playing with fire: Transforms and variations","isPartOf":{"@id":"https://speice.io/","@type":"Blog","name":"Blog"},"keywords":[],"mainEntityOfPage":"https://speice.io/2024/11/playing-with-fire-transforms","name":"Playing with fire: Transforms and variations","url":"https://speice.io/2024/11/playing-with-fire-transforms"}</script><link rel=alternate type=application/rss+xml href=/rss.xml title="The Old Speice Guy RSS Feed"><link rel=alternate type=application/atom+xml href=/atom.xml title="The Old Speice Guy Atom Feed"><link rel=stylesheet href=/katex/katex.min.css><link rel=stylesheet href=/assets/css/styles.16c3428d.css><script src=/assets/js/runtime~main.29a27dcf.js defer></script><script src=/assets/js/main.d461af80.js defer></script><body class=navigation-with-keyboard><script>!function(){var t,e=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();t=null!==e?e:"light",document.documentElement.setAttribute("data-theme",t)}(),function(){try{for(var[t,e]of new URLSearchParams(window.location.search).entries())if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id=__docusaurus><div role=region aria-label="Skip to main content"><a class=skipToContent_fXgn href=#__docusaurus_skipToContent_fallback>Skip to main content</a></div><nav aria-label=Main class="navbar navbar--fixed-top"><div class=navbar__inner><div class=navbar__items><button aria-label="Toggle navigation bar" aria-expanded=false class="navbar__toggle clean-btn" type=button><svg width=30 height=30 viewBox="0 0 30 30" aria-hidden=true><path stroke=currentColor stroke-linecap=round stroke-miterlimit=10 stroke-width=2 d="M4 7h22M4 15h22M4 23h22"/></svg></button><a class=navbar__brand href=/><div class=navbar__logo><img src=/img/logo.svg alt="Sierpi
|
|||
|
shapes and patterns that fractal flames are known for.</p>
|
|||
|
<div class="theme-admonition theme-admonition-info admonition_xJq3 alert alert--info"><div class=admonitionHeading_Gvgb><span class=admonitionIcon_Rf37><svg viewBox="0 0 14 16"><path fill-rule=evenodd d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg></span>info</div><div class=admonitionContent_BuS1><p>This post uses <a href=/assets/files/params-79404da2c6b544cbaf223f19db41fabf.flame target=_blank>reference parameters</a> to demonstrate the fractal flame algorithm.
|
|||
|
If you're interested in tweaking the parameters, or creating your own, <a href=https://sourceforge.net/projects/apophysis/ target=_blank rel="noopener noreferrer">Apophysis</a>
|
|||
|
can load that file.</div></div>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=variations>Variations<a href=#variations class=hash-link aria-label="Direct link to Variations" title="Direct link to Variations"></a></h2>
|
|||
|
<div class="theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary"><div class=admonitionHeading_Gvgb><span class=admonitionIcon_Rf37><svg viewBox="0 0 14 16"><path fill-rule=evenodd d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"/></svg></span>note</div><div class=admonitionContent_BuS1><p>This post covers section 3 of the Fractal Flame Algorithm paper</div></div>
|
|||
|
<!-- -->
|
|||
|
<p>We previously introduced transforms as the "functions" of an "iterated function system," and showed how
|
|||
|
playing the chaos game gives us an image of Sierpinski's Gasket. Even though we used simple functions,
|
|||
|
the image it generates is intriguing. But what would happen if we used something more complex?</p>
|
|||
|
<p>This leads us to the first big innovation of the fractal flame algorithm: adding non-linear functions
|
|||
|
after the affine transform. These functions are called "variations":</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mrow><msub><mi>F</mi><mi>i</mi></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo><mo>=</mo><msub><mi>V</mi><mi>j</mi></msub><mo stretchy=false>(</mo><msub><mi>a</mi><mi>i</mi></msub><mi>x</mi><mo>+</mo><msub><mi>b</mi><mi>i</mi></msub><mi>y</mi><mo>+</mo><msub><mi>c</mi><mi>i</mi></msub><mo separator=true>,</mo><msub><mi>d</mi><mi>i</mi></msub><mi>x</mi><mo>+</mo><msub><mi>e</mi><mi>i</mi></msub><mi>y</mi><mo>+</mo><msub><mi>f</mi><mi>i</mi></msub><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>F_i(x, y) = V_j(a_i x + b_i y + c_i, d_i x + e_i y + f_i)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.1389em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span></span><span class=base><span class=strut style=height:1.0361em;vertical-align:-0.2861em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.22222em>V</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.2222em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style=margin-right:0.05724em>j</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2861em><span></span></span></span></span></span></span><span class=mopen>(</span><span class=mord><span class="mord mathnormal">a</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:0em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222em></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222em></span></span><span class=base><span class=strut style=height:0.8889em;vertical-align:-0.1944em></span><span class=mord><span class="mord mathnormal">b</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:0em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mspace style=margin-right:0.2222em></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222em></span></span><span class=base><span class
|
|||
|
<!-- -->
|
|||
|
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">type</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Variation</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> x</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> y</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<p>Just like transforms, variations (<span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>V</mi><mi>j</mi></msub></mrow><annotation encoding=application/x-tex>V_j</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.9694em;vertical-align:-0.2861em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.22222em>V</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.2222em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style=margin-right:0.05724em>j</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2861em><span></span></span></span></span></span></span></span></span></span>) are functions that take in <span class=katex><span class=katex-mathml><math><semantics><mrow><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>(x, y)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span></span></span></span> coordinates
|
|||
|
and give back new <span class=katex><span class=katex-mathml><math><semantics><mrow><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>(x, y)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span></span></span></span> coordinates.
|
|||
|
However, the sky is the limit for what happens between input and output.
|
|||
|
The Fractal Flame paper lists 49 variation functions,
|
|||
|
and the official <code>flam3</code> implementation supports <a href=https://github.com/scottdraves/flam3/blob/7fb50c82e90e051f00efcc3123d0e06de26594b2/variations.c target=_blank rel="noopener noreferrer">98 different variations</a>.</p>
|
|||
|
<p>To draw our reference image, we'll focus on just four:</p>
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=linear-variation-0>Linear (variation 0)<a href=#linear-variation-0 class=hash-link aria-label="Direct link to Linear (variation 0)" title="Direct link to Linear (variation 0)"></a></h3>
|
|||
|
<p>This variation is dead simple: return the <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>x</mi></mrow><annotation encoding=application/x-tex>x</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.4306em></span><span class="mord mathnormal">x</span></span></span></span> and <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>y</mi></mrow><annotation encoding=application/x-tex>y</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.1944em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span></span></span></span> coordinates as-is.</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mrow><msub><mi>V</mi><mn>0</mn></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo><mo>=</mo><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>V_0(x,y) = (x,y)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.22222em>V</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3011em><span style=top:-2.55em;margin-left:-0.2222em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">0</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span></span></span></span></span>
|
|||
|
<!-- -->
|
|||
|
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain">Variation</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"./variation"</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> linear</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(221, 87%, 60%)">Variation</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">x</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn><span class=copyButtonIcons_eSgA aria-hidden=true><svg viewBox="0 0 24 24" class=copyButtonIcon_y97N><path fill=currentColor d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"/></svg><svg viewBox="0 0 24 24" class=copyButtonSuccessIcon_LjdS><path fill=currentColor d=M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z /></svg></span></button></div></div></div>
|
|||
|
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class=admonitionHeading_Gvgb><span class=admonitionIcon_Rf37><svg viewBox="0 0 12 16"><path fill-rule=evenodd d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"/></svg></span>tip</div><div class=admonitionContent_BuS1><p>In a way, we've already been using this variation! The transforms that define Sierpinski's Gasket
|
|||
|
apply the affine coefficients to the input point and use that as the output.</div></div>
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=julia-variation-13>Julia (variation 13)<a href=#julia-variation-13 class=hash-link aria-label="Direct link to Julia (variation 13)" title="Direct link to Julia (variation 13)"></a></h3>
|
|||
|
<p>This variation is a good example of a non-linear function. It uses both trigonometry
|
|||
|
and probability to produce interesting shapes:</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mtable rowspacing=0.25em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi>r</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><msqrt><mrow><msup><mi>x</mi><mn>2</mn></msup><mo>+</mo><msup><mi>y</mi><mn>2</mn></msup></mrow></msqrt></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi>θ</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><mtext>arctan</mtext><mo stretchy=false>(</mo><mi>x</mi><mi mathvariant=normal>/</mi><mi>y</mi><mo stretchy=false>)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi mathvariant=normal>Ω</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><mrow><mo fence=true>{</mo><mtable rowspacing=0.16em columnalign="left right" columnspacing=1em><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mrow><mn>0</mn><mspace width=1.1381em /><mtext>w.p. </mtext><mn>0.5</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=false><mrow><mi>π</mi><mspace width=1.1381em /><mtext>w.p. </mtext><mn>0.5</mn></mrow></mstyle></mtd></mtr></mtable><mo fence=true>}</mo></mrow></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><msub><mi>V</mi><mn>13</mn></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><msqrt><mi>r</mi></msqrt><mo>⋅</mo><mo stretchy=false>(</mo><mtext>cos</mtext><mo stretchy=false>(</mo><mi>θ</mi><mi mathvariant=normal>/</mi><mn>2</mn><mo>+</mo><mi mathvariant=normal>Ω</mi><mo stretchy=false>)</mo><mo separator=true>,</mo><mtext>sin</mtext><mo stretchy=false>(</mo><mi>θ</mi><mi mathvariant=normal>/</mi><mn>2</mn><mo>+</mo><mi mathvariant=normal>Ω</mi><mo stretchy=false>)</mo><mo stretchy=false>)</mo></mrow></mstyle></mtd></mtr></mtable><annotation encoding=application/x-tex>\begin{align*}
|
|||
|
r &= \sqrt{x^2 + y^2} \\
|
|||
|
\theta &= \text{arctan}(x / y) \\
|
|||
|
\Omega &= \left\{
|
|||
|
\begin{array}{lr}
|
|||
|
0 \hspace{0.4cm} \text{w.p. } 0.5 \\
|
|||
|
\pi \hspace{0.4cm} \text{w.p. } 0.5 \\
|
|||
|
\end{array}
|
|||
|
\right\} \\
|
|||
|
|
|||
|
V_{13}(x, y) &= \sqrt{r} \cdot (\text{cos} ( \theta / 2 + \Omega ), \text{sin} ( \theta / 2 + \Omega ))
|
|||
|
\end{align*}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:7.3759em;vertical-align:-3.4379em></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:3.9379em><span style=top:-6.3812em><span class=pstrut style=height:3.45em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.02778em>r</span></span></span><span style=top:-4.8812em><span class=pstrut style=height:3.45em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.02778em>θ</span></span></span><span style=top:-2.7712em><span class=pstrut style=height:3.45em></span><span class=mord><span class=mord>Ω</span></span></span><span style=top:-0.6721em><span class=pstrut style=height:3.45em></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.22222em>V</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3011em><span style=top:-2.55em;margin-left:-0.2222em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">13</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:3.4379em><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:3.9379em><span style=top:-6.3812em><span class=pstrut style=height:3.45em></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span><span class="mord sqrt"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.0067em><span class=svg-align style=top:-3.2em><span class=pstrut style=height:3.2em></span><span class=mord style=padding-left:1em><span class=mord><span class="mord mathnormal">x</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7401em><span style=top:-2.989em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2222em></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.7401em><span style=top:-2.989em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span></span></span></span></span></span></span><span style=top:-2.9667em><span class=pstrut style=height:3.2em></span><span class=hide-tail style=min-width:1.02em;height:1.28em><svg width=400em height=1.28em viewBox="0 0 400000 1296" preserveAspectRatio="xMinYMin slice"><path d="M263,681c0.7,0,18,39.7,52,119 c34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120 c340,-704.7,510.7,-1060.3,512,-1067 l0 -0 c4.7,-7.3,11,-11,19,-11 H40000v40H1012.3 s-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232 c-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1 s-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26 c-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-
|
|||
|
<!-- -->
|
|||
|
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> Variation </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"./variation"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(221, 87%, 60%)">omega</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=></span><span class="token plain"> Math</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">random</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">></span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0.5</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">?</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> Math</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token constant" style="color:hsl(35, 99%, 36%)">PI</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain" style=display:inline-block></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> julia</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token function-variable function" style="color:hsl(221, 87%, 60%)">Variation</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> y</span><s
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=popcorn-variation-17>Popcorn (variation 17)<a href=#popcorn-variation-17 class=hash-link aria-label="Direct link to Popcorn (variation 17)" title="Direct link to Popcorn (variation 17)"></a></h3>
|
|||
|
<p>Some variations rely on knowing the transform's affine coefficients; they're called "dependent variations."
|
|||
|
For this variation, we use <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>c</mi></mrow><annotation encoding=application/x-tex>c</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.4306em></span><span class="mord mathnormal">c</span></span></span></span> and <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>f</mi></mrow><annotation encoding=application/x-tex>f</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8889em;vertical-align:-0.1944em></span><span class="mord mathnormal" style=margin-right:0.10764em>f</span></span></span></span>:</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mrow><msub><mi>V</mi><mn>17</mn></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo><mo>=</mo><mo stretchy=false>(</mo><mi>x</mi><mo>+</mo><mi>c</mi><mtext> sin</mtext><mo stretchy=false>(</mo><mtext>tan </mtext><mn>3</mn><mi>y</mi><mo stretchy=false>)</mo><mo separator=true>,</mo><mi>y</mi><mo>+</mo><mi>f</mi><mtext> sin</mtext><mo stretchy=false>(</mo><mtext>tan </mtext><mn>3</mn><mi>x</mi><mo stretchy=false>)</mo><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>V_{17}(x,y) = (x + c\ \text{sin}(\text{tan }3y), y + f\ \text{sin}(\text{tan }3x))</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.22222em>V</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3011em><span style=top:-2.55em;margin-left:-0.2222em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mtight">17</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222em></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222em></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class="mord mathnormal">c</span><span class=mspace> </span><span class="mord text"><span class=mord>sin</span></span><span class=mopen>(</span><span class="mord text"><span class=mord>tan </span></span><span class=mord>3</span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mspace style=margin-right:0.2222em></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222em></span></span><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class="mord mathnormal" style=margin-right:0.10764em>f</span><span class=mspace> </span><span class="mord text"><span class=mord>sin</span></span><span class=mopen>(</span><span class="mord text"><span class=mord>tan </span></span><span class=mord>3</span><span class="mord mathnormal">x</span><span class=mclose>))</span></span></span></span></span>
|
|||
|
<!-- -->
|
|||
|
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> Coefs </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"./transform"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> Variation </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"./variation"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> popcorn </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> c</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> f </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> Coefs</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> Variation </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=></span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> x </span><span class="token operator" style="color:hsl(221, 87%, 60%)">+</span><span class="token plain"> c </span><span class="token operator" style="color:hsl(221, 87%, 60%)">*</span><span class="token plain"> Math</span><span class="token punctuation" style
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=pdj-variation-24>PDJ (variation 24)<a href=#pdj-variation-24 class=hash-link aria-label="Direct link to PDJ (variation 24)" title="Direct link to PDJ (variation 24)"></a></h3>
|
|||
|
<p>Some variations have extra parameters we can choose; they're called "parametric variations."
|
|||
|
For the PDJ variation, there are four extra parameters:</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mrow><msub><mi>p</mi><mn>1</mn></msub><mo>=</mo><mtext>pdj.a</mtext><mspace width=0.2845em /><msub><mi>p</mi><mn>2</mn></msub><mo>=</mo><mtext>pdj.b</mtext><mspace width=0.2845em /><msub><mi>p</mi><mn>3</mn></msub><mo>=</mo><mtext>pdj.c</mtext><mspace width=0.2845em /><msub><mi>p</mi><mn>4</mn></msub><mo>=</mo><mtext>pdj.d</mtext><mspace linebreak=newline /><msub><mi>V</mi><mn>24</mn></msub><mo>=</mo><mo stretchy=false>(</mo><mtext>sin</mtext><mo stretchy=false>(</mo><msub><mi>p</mi><mn>1</mn></msub><mi>y</mi><mo stretchy=false>)</mo><mo>−</mo><mtext>cos</mtext><mo stretchy=false>(</mo><msub><mi>p</mi><mn>2</mn></msub><mi>x</mi><mo stretchy=false>)</mo><mo separator=true>,</mo><mtext>sin</mtext><mo stretchy=false>(</mo><msub><mi>p</mi><mn>3</mn></msub><mi>x</mi><mo stretchy=false>)</mo><mo>−</mo><mtext>cos</mtext><mo stretchy=false>(</mo><msub><mi>p</mi><mn>4</mn></msub><mi>y</mi><mo stretchy=false>)</mo><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>p_1 = \text{pdj.a} \hspace{0.1cm} p_2 = \text{pdj.b} \hspace{0.1cm} p_3 = \text{pdj.c} \hspace{0.1cm} p_4 = \text{pdj.d} \\
|
|||
|
V_{24} = (\text{sin}(p_1 y) - \text{cos}(p_2 x), \text{sin}(p_3 x) - \text{cos}(p_4 y))</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.1944em></span><span class=mord><span class="mord mathnormal">p</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3011em><span style=top:-2.55em;margin-left:0em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">1</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span></span><span class=base><span class=strut style=height:0.8889em;vertical-align:-0.1944em></span><span class="mord text"><span class=mord>pdj.a</span></span><span class=mspace style=margin-right:0.2845em></span><span class=mord><span class="mord mathnormal">p</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3011em><span style=top:-2.55em;margin-left:0em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">2</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span></span><span class=base><span class=strut style=height:0.8889em;vertical-align:-0.1944em></span><span class="mord text"><span class=mord>pdj.b</span></span><span class=mspace style=margin-right:0.2845em></span><span class=mord><span class="mord mathnormal">p</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3011em><span style=top:-2.55em;margin-left:0em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">3</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span></span><span class=base><span class=strut style=height:0.8889em;vertical-align:-0.1944em></span><span class="mord text"><span class=mord>pdj.c</span></span><span class=mspace style=margin-right:0.2845em></span><span class=mord><span class="mord mathnormal">p</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3011em><span style=top:-2.55em;margin-left:0em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight">4</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span></span><span class=base><span class=strut style=height:0.8889em;vertical-align:-0.1944em></span><span class="mord text"><span class=mord>pdj.d</span></span></span><span class="mspace newline"></span><span class=base><span class=strut style=height:0.8333em;vertical-align:-0.15em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.22222em>V</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3011em><span style=top:-2.55em;margin-left:-0.2222em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-s
|
|||
|
<!-- -->
|
|||
|
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> Variation </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">'./variation'</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">type</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">PdjParams</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> a</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> b</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> c</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> d</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> pdj </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain">a</span>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=blending>Blending<a href=#blending class=hash-link aria-label="Direct link to Blending" title="Direct link to Blending"></a></h2>
|
|||
|
<p>Now, one variation is fun, but we can also combine variations in a process called "blending."
|
|||
|
Each variation receives the same <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>x</mi></mrow><annotation encoding=application/x-tex>x</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.4306em></span><span class="mord mathnormal">x</span></span></span></span> and <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>y</mi></mrow><annotation encoding=application/x-tex>y</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.1944em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span></span></span></span> inputs, and we add together each variation's <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>x</mi></mrow><annotation encoding=application/x-tex>x</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.4306em></span><span class="mord mathnormal">x</span></span></span></span> and <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>y</mi></mrow><annotation encoding=application/x-tex>y</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.625em;vertical-align:-0.1944em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span></span></span></span> outputs.
|
|||
|
We'll also give each variation a weight (<span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>v</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub></mrow><annotation encoding=application/x-tex>v_{ij}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.7167em;vertical-align:-0.2861em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em>v</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.0359em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.05724em>ij</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2861em><span></span></span></span></span></span></span></span></span></span>) that changes how much it contributes to the result:</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mrow><msub><mi>F</mi><mi>i</mi></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo><mo>=</mo><munder><mo>∑</mo><mi>j</mi></munder><msub><mi>v</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub><msub><mi>V</mi><mi>j</mi></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>F_i(x,y) = \sum_{j} v_{ij} V_j(x, y)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1em;vertical-align:-0.25em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.1389em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span></span><span class=base><span class=strut style=height:2.4638em;vertical-align:-1.4138em></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.05em><span style=top:-1.8723em;margin-left:0em><span class=pstrut style=height:3.05em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.05724em>j</span></span></span></span><span style=top:-3.05em><span class=pstrut style=height:3.05em></span><span><span class="mop op-symbol large-op">∑</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.4138em><span></span></span></span></span></span><span class=mspace style=margin-right:0.1667em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em>v</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.0359em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.05724em>ij</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2861em><span></span></span></span></span></span></span><span class=mord><span class="mord mathnormal" style=margin-right:0.22222em>V</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.2222em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight" style=margin-right:0.05724em>j</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2861em><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span></span></span></span></span>
|
|||
|
<p>The formula looks intimidating, but it's not hard to implement:</p>
|
|||
|
<!-- -->
|
|||
|
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> Variation </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"./variation"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">type</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Blend</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> Variation</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain" style=display:inline-block></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">blend</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> x</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> y</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token builtin" style="color:hsl(119, 34%, 47%)">number</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> varFns</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> Blend</span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> </span><span class="token pu
|
|||
|
<p>With that in place, we have enough to render a fractal flame. We'll use the same
|
|||
|
chaos game as before, but the new transforms and variations produce a dramatically different image:</p>
|
|||
|
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class=admonitionHeading_Gvgb><span class=admonitionIcon_Rf37><svg viewBox="0 0 12 16"><path fill-rule=evenodd d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"/></svg></span>tip</div><div class=admonitionContent_BuS1><p>Try using the variation weights to figure out which parts of the image each transform controls.</div></div>
|
|||
|
<!-- -->
|
|||
|
<center><center><div style=width:75%;aspect-ratio:1/1></div></center></center>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=post-transforms>Post transforms<a href=#post-transforms class=hash-link aria-label="Direct link to Post transforms" title="Direct link to Post transforms"></a></h2>
|
|||
|
<p>Next, we'll introduce a second affine transform applied <em>after</em> variation blending. This is called a "post transform."</p>
|
|||
|
<p>We'll use some new variables, but the post transform should look familiar:</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mtable rowspacing=0.25em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><msub><mi>P</mi><mi>i</mi></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><mo stretchy=false>(</mo><msub><mi>α</mi><mi>i</mi></msub><mi>x</mi><mo>+</mo><msub><mi>β</mi><mi>i</mi></msub><mi>y</mi><mo>+</mo><msub><mi>γ</mi><mi>i</mi></msub><mo separator=true>,</mo><msub><mi>δ</mi><mi>i</mi></msub><mi>x</mi><mo>+</mo><msub><mi>ϵ</mi><mi>i</mi></msub><mi>y</mi><mo>+</mo><msub><mi>ζ</mi><mi>i</mi></msub><mo stretchy=false>)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><msub><mi>F</mi><mi>i</mi></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo></mrow></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><msub><mi>P</mi><mi>i</mi></msub><mrow><mo fence=true>(</mo><munder><mo>∑</mo><mi>j</mi></munder><msub><mi>v</mi><mrow><mi>i</mi><mi>j</mi></mrow></msub><msub><mi>V</mi><mi>j</mi></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo><mo fence=true>)</mo></mrow></mrow></mstyle></mtd></mtr></mtable><annotation encoding=application/x-tex>\begin{align*}
|
|||
|
P_i(x, y) &= (\alpha_i x + \beta_i y + \gamma_i, \delta_i x + \epsilon_i y + \zeta_i) \\
|
|||
|
F_i(x, y) &= P_i\left(\sum_{j} v_{ij} V_j(x, y)\right)
|
|||
|
\end{align*}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:4.9638em;vertical-align:-2.2319em></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.7319em><span style=top:-5.6419em><span class=pstrut style=height:3.75em></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em>P</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.1389em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span></span></span><span style=top:-3.2319em><span class=pstrut style=height:3.75em></span><span class=mord><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.1389em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:2.2319em><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:2.7319em><span style=top:-5.6419em><span class=pstrut style=height:3.75em></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span><span class=mopen>(</span><span class=mord><span class="mord mathnormal" style=margin-right:0.0037em>α</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.0037em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class="mord mathnormal">x</span><span class=mspace style=margin-right:0.2222em></span><span class=mbin>+</span><span class=mspace style=margin-right:0.2222em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.05278em>β</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.0528em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mspace style=margin-right:0.2222em></span><span class
|
|||
|
<!-- -->
|
|||
|
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> applyCoefs</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> Coefs</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> Transform </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"../src/transform"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">export</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> transformPost </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> transform</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> Transform</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> coefs</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> Coefs</span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token operator" style="color:hsl(221, 87%, 60%)">:</span><span class="token plain"> Transform </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=></span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">x</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=></span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span><br></span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">x</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> y</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"> </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">transform</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><s
|
|||
|
<p>The image below uses the same transforms/variations as the previous fractal flame,
|
|||
|
but allows changing the post-transform coefficients:</p>
|
|||
|
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed=true><summary>If you want to test your understanding...</summary><div><div class=collapsibleContent_i85q><ul>
|
|||
|
<li>What post-transform coefficients will give us the previous image?</li>
|
|||
|
<li>What post-transform coefficients will give us a <em>mirrored</em> image?</li>
|
|||
|
</ul></div></div></details>
|
|||
|
<!-- -->
|
|||
|
<center><center><div style=width:75%;aspect-ratio:1/1></div></center></center>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=final-transforms>Final transforms<a href=#final-transforms class=hash-link aria-label="Direct link to Final transforms" title="Direct link to Final transforms"></a></h2>
|
|||
|
<p>The last step is to introduce a "final transform" (<span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>F</mi><mrow><mi>f</mi><mi>i</mi><mi>n</mi><mi>a</mi><mi>l</mi></mrow></msub></mrow><annotation encoding=application/x-tex>F_{final}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.9694em;vertical-align:-0.2861em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3361em><span style=top:-2.55em;margin-left:-0.1389em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mtight"><span class="mord mathnormal mtight" style=margin-right:0.10764em>f</span><span class="mord mathnormal mtight">ina</span><span class="mord mathnormal mtight" style=margin-right:0.01968em>l</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2861em><span></span></span></span></span></span></span></span></span></span>) that is applied
|
|||
|
regardless of which regular transform (<span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>F</mi><mi>i</mi></msub></mrow><annotation encoding=application/x-tex>F_i</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8333em;vertical-align:-0.15em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.1389em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span></span></span></span>) the chaos game selects.
|
|||
|
It's just like a normal transform (composition of affine transform, variation blend, and post transform),
|
|||
|
but it doesn't affect the chaos game state.</p>
|
|||
|
<p>After adding the final transform, our chaos game algorithm looks like this:</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mtable rowspacing=0.25em columnalign="right left" columnspacing=0em><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow/></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo><mo>=</mo><mtext>random point in the bi-unit square</mtext></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow/></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mtext>iterate </mtext><mo stretchy=false>{</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow/></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mspace width=2.8453em /><mi>i</mi><mo>=</mo><mtext>random integer from 0 to </mtext><mi>n</mi><mo>−</mo><mn>1</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow/></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mspace width=2.8453em /><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo><mo>=</mo><msub><mi>F</mi><mi>i</mi></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow/></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mspace width=2.8453em /><mo stretchy=false>(</mo><msub><mi>x</mi><mi>f</mi></msub><mo separator=true>,</mo><msub><mi>y</mi><mi>f</mi></msub><mo stretchy=false>)</mo><mo>=</mo><msub><mi>F</mi><mrow><mi>f</mi><mi>i</mi><mi>n</mi><mi>a</mi><mi>l</mi></mrow></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow/></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mspace width=2.8453em /><mtext>plot</mtext><mo stretchy=false>(</mo><msub><mi>x</mi><mi>f</mi></msub><mo separator=true>,</mo><msub><mi>y</mi><mi>f</mi></msub><mo stretchy=false>)</mo><mtext> if iterations</mtext><mo>></mo><mn>20</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mo stretchy=false lspace=0em rspace=0em>}</mo></mstyle></mtd></mtr></mtable><annotation encoding=application/x-tex>\begin{align*}
|
|||
|
&(x, y) = \text{random point in the bi-unit square} \\
|
|||
|
&\text{iterate } \{ \\
|
|||
|
&\hspace{1cm} i = \text{random integer from 0 to } n - 1 \\
|
|||
|
&\hspace{1cm} (x,y) = F_i(x,y) \\
|
|||
|
&\hspace{1cm} (x_f,y_f) = F_{final}(x,y) \\
|
|||
|
&\hspace{1cm} \text{plot}(x_f,y_f) \text{ if iterations} > 20 \\
|
|||
|
\}
|
|||
|
\end{align*}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:10.5em;vertical-align:-5em></span><span class=mord><span class=mtable><span class=col-align-r><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:5.5em><span style=top:-7.66em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:-6.16em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:-4.66em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:-3.16em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:-1.66em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:-0.16em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:1.34em><span class=pstrut style=height:3em></span><span class=mord><span class=mclose>}</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:5em><span></span></span></span></span></span><span class=col-align-l><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:5.5em><span style=top:-7.66em><span class=pstrut style=height:3em></span><span class=mord><span class=mord></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span><span class="mord text"><span class=mord>random point in the bi-unit square</span></span></span></span><span style=top:-6.16em><span class=pstrut style=height:3em></span><span class=mord><span class=mord></span><span class="mord text"><span class=mord>iterate </span></span><span class=mopen>{</span></span></span><span style=top:-4.66em><span class=pstrut style=height:3em></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:2.8453em></span><span class="mord mathnormal">i</span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span><span class="mord text"><span class=mord>random integer from 0 to </span></span><span class="mord mathnormal">n</span><span class=mspace style=margin-right:0.2222em></span><span class=mbin>−</span><span class=mspace style=margin-right:0.2222em></span><span class=mord>1</span></span></span><span style=top:-3.16em><span class=pstrut style=height:3em></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:2.8453em></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span><span class=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.13889em>F</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3117em><span style=top:-2.55em;margin-left:-0.1389em;margin-right:0.05em><span class=pstrut style=height:2.7em></span><span class="sizing reset-size6 size3 mtight"><span class="mord mathnormal mtight">i</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.15em><span></span></span></span></span></span></span><span class=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord mathnormal" style=margin-right:0.03588em>y</span><span class=mclose>)</span></span></span><span style=top:-1.66em><span cl
|
|||
|
<!-- -->
|
|||
|
<div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-background-color:hsl(230, 1%, 98%);--prism-color:hsl(230, 8%, 24%)"><div class=codeBlockContent_biex><pre tabindex=0 class="prism-code language-typescript codeBlock_bY9V thin-scrollbar" style="background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)"><code class=codeBlockLines_e6Vv><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> randomBiUnit </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"../src/randomBiUnit"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> randomChoice </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"../src/randomChoice"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> plotBinary </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">as</span><span class="token plain"> plot </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"../src/plotBinary"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> Transform </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="token plain"> </span><span class="token string" style="color:hsl(119, 34%, 47%)">"../src/transform"</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span><br></span><span class="token-line code-block-hidden" style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token keyword" style="color:hsl(301, 63%, 40%)">import</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"> Props </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">as</span><span class="token plain"> WeightedProps </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token plain"> </span><span class="token keyword" style="color:hsl(301, 63%, 40%)">from</span><span class="
|
|||
|
<p>This image uses the same normal/post transforms as above, but allows modifying
|
|||
|
the coefficients and variations of the final transform:</p>
|
|||
|
<!-- -->
|
|||
|
<center><center><div style=width:75%;aspect-ratio:1/1></div></center></center>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=summary>Summary<a href=#summary class=hash-link aria-label="Direct link to Summary" title="Direct link to Summary"></a></h2>
|
|||
|
<p>Variations are the fractal flame algorithm's first major innovation.
|
|||
|
By blending variation functions and post/final transforms, we generate unique images.</p>
|
|||
|
<p>However, these images are grainy and unappealing. In the next post, we'll clean up
|
|||
|
the image quality and add some color.</div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Blog post page navigation"><a class="pagination-nav__link pagination-nav__link--prev" href=/2024/11/playing-with-fire><div class=pagination-nav__sublabel>Older post</div><div class=pagination-nav__label>Playing with fire: The fractal flame algorithm</div></a><a class="pagination-nav__link pagination-nav__link--next" href=/2024/11/playing-with-fire-log-density><div class=pagination-nav__sublabel>Newer post</div><div class=pagination-nav__label>Playing with fire: Tone mapping and color</div></a></nav></main><div class="col col--2"><div class="tableOfContents_bqdL thin-scrollbar"><ul class="table-of-contents table-of-contents__left-border"><li><a href=#variations class="table-of-contents__link toc-highlight">Variations</a><ul><li><a href=#linear-variation-0 class="table-of-contents__link toc-highlight">Linear (variation 0)</a><li><a href=#julia-variation-13 class="table-of-contents__link toc-highlight">Julia (variation 13)</a><li><a href=#popcorn-variation-17 class="table-of-contents__link toc-highlight">Popcorn (variation 17)</a><li><a href=#pdj-variation-24 class="table-of-contents__link toc-highlight">PDJ (variation 24)</a></ul><li><a href=#blending class="table-of-contents__link toc-highlight">Blending</a><li><a href=#post-transforms class="table-of-contents__link toc-highlight">Post transforms</a><li><a href=#final-transforms class="table-of-contents__link toc-highlight">Final transforms</a><li><a href=#summary class="table-of-contents__link toc-highlight">Summary</a></ul></div></div></div></div></div><footer class=footer><div class="container container-fluid"><div class="footer__bottom text--center"><div class=footer__copyright>Copyright © 2024 Bradlee Speice</div></div></div></footer></div>
|