speice.io/2024/11/playing-with-fire-transforms/index.html

115 lines
164 KiB
HTML
Raw Normal View History

<!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>