mirror of
https://github.com/bspeice/speice.io
synced 2024-12-22 16:48:10 -05:00
192 lines
192 KiB
HTML
192 lines
192 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: The fractal flame algorithm | 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><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: The fractal flame algorithm | The Old Speice Guy"><meta data-rh=true name=description content="Wikipedia describes fractal flames as:"><meta data-rh=true property=og:description content="Wikipedia describes fractal flames as:"><meta data-rh=true property=og:type content=article><meta data-rh=true property=article:published_time content=2024-12-16T21:30: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><link data-rh=true rel=alternate href=https://speice.io/2024/11/playing-with-fire hreflang=en><link data-rh=true rel=alternate href=https://speice.io/2024/11/playing-with-fire hreflang=x-default><script data-rh=true type=application/ld+json>{"@context":"https://schema.org","@id":"https://speice.io/2024/11/playing-with-fire","@type":"BlogPosting","author":{"@type":"Person","name":"Bradlee Speice"},"dateModified":"2024-12-17T02:30:05.000Z","datePublished":"2024-12-16T21:30:00.000Z","description":"Wikipedia describes fractal flames as:","headline":"Playing with fire: The fractal flame algorithm","isPartOf":{"@id":"https://speice.io/","@type":"Blog","name":"Blog"},"keywords":[],"mainEntityOfPage":"https://speice.io/2024/11/playing-with-fire","name":"Playing with fire: The fractal flame algorithm","url":"https://speice.io/2024/11/playing-with-fire"}</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="Sierpinski Gasket" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src=/img/logo-dark.svg alt="Sierpinski Gasket" class="themedComponent_mlkZ themedComponent--dark_xIcU"></div><b class="navbar__title text--truncate">The Old Speice Guy<
|
|||
|
<blockquote>
|
|||
|
<p>a member of the iterated function system class of fractals</p>
|
|||
|
</blockquote>
|
|||
|
<p>It's tedious, but technically correct. I choose to think of them a different way: beauty in mathematics.</p>
|
|||
|
<!-- -->
|
|||
|
<center><img src=/assets/images/banner-506be1e2d2e720d32f10924e117435d5.png style=filter:invert(1)></center>
|
|||
|
<p>I don't remember when exactly I first learned about fractal flames, but I do remember being entranced by the images they created.
|
|||
|
I also remember their unique appeal to my young engineering mind; this was an art form I could participate in.</p>
|
|||
|
<p>The <a href=https://flam3.com/flame_draves.pdf target=_blank rel="noopener noreferrer">Fractal Flame Algorithm paper</a> describing their structure was too much
|
|||
|
for me to handle at the time (I was ~12 years old), so I was content to play around and enjoy the pictures.
|
|||
|
But the desire to understand it stuck around. Now, with a graduate degree under my belt, I wanted to revisit it.</p>
|
|||
|
<p>This guide is my attempt to explain how fractal flames work so that younger me — and others interested in the art —
|
|||
|
can understand without too much prior knowledge.</p>
|
|||
|
<hr>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=iterated-function-systems>Iterated function systems<a href=#iterated-function-systems class=hash-link aria-label="Direct link to Iterated function systems" title="Direct link to Iterated function systems"></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 2 of the Fractal Flame Algorithm paper</div></div>
|
|||
|
<p>As mentioned, fractal flames are a type of "<a href=https://en.wikipedia.org/wiki/Iterated_function_system target=_blank rel="noopener noreferrer">iterated function system</a>,"
|
|||
|
or IFS. The formula for an IFS is short, but takes some time to work through:</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mrow><mi>S</mi><mo>=</mo><munderover><mo>⋃</mo><mrow><mi>i</mi><mo>=</mo><mn>0</mn></mrow><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></munderover><msub><mi>F</mi><mi>i</mi></msub><mo stretchy=false>(</mo><mi>S</mi><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>S = \bigcup_{i=0}^{n-1} F_i(S)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</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:3.0788em;vertical-align:-1.2777em></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.8011em><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">i</span><span class="mrel mtight">=</span><span class="mord mtight">0</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 style=top:-4.3em;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">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.2777em><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.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" style=margin-right:0.05764em>S</span><span class=mclose>)</span></span></span></span></span>
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=solution-set>Solution set<a href=#solution-set class=hash-link aria-label="Direct link to Solution set" title="Direct link to Solution set"></a></h3>
|
|||
|
<p>First, <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>S</mi></mrow><annotation encoding=application/x-tex>S</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</span></span></span></span>. <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>S</mi></mrow><annotation encoding=application/x-tex>S</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</span></span></span></span> is the set of points in two dimensions (in math terms, <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>S</mi><mo>∈</mo><msup><mi mathvariant=double-struck>R</mi><mn>2</mn></msup></mrow><annotation encoding=application/x-tex>S \in \mathbb{R}^2</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.7224em;vertical-align:-0.0391em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</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.8141em></span><span class=mord><span class="mord mathbb">R</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141em><span style=top:-3.063em;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>)
|
|||
|
that represent a "solution" of some kind to our equation.
|
|||
|
Our goal is to find all the points in <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>S</mi></mrow><annotation encoding=application/x-tex>S</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</span></span></span></span>, plot them, and display that image.</p>
|
|||
|
<p>For example, if we say <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>S</mi><mo>=</mo><mo stretchy=false>{</mo><mo stretchy=false>(</mo><mn>0</mn><mo separator=true>,</mo><mn>0</mn><mo stretchy=false>)</mo><mo separator=true>,</mo><mo stretchy=false>(</mo><mn>1</mn><mo separator=true>,</mo><mn>1</mn><mo stretchy=false>)</mo><mo separator=true>,</mo><mo stretchy=false>(</mo><mn>2</mn><mo separator=true>,</mo><mn>2</mn><mo stretchy=false>)</mo><mo stretchy=false>}</mo></mrow><annotation encoding=application/x-tex>S = \{(0,0), (1, 1), (2, 2)\}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</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>0</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class=mord>0</span><span class=mclose>)</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class=mopen>(</span><span class=mord>1</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class=mord>1</span><span class=mclose>)</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class=mopen>(</span><span class=mord>2</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class=mord>2</span><span class=mclose>)}</span></span></span></span>, there are three points to plot:</p>
|
|||
|
<!-- -->
|
|||
|
<div class=VictoryContainer style=height:100%;width:100%;user-select:none;pointer-events:none;touch-action:none;position:relative><svg width=450 height=300 role=img viewBox="0 0 450 300" style=width:100%;height:100%;pointer-events:all><g><path d="M 60, 240 m -5, 0 a 5, 5 0 1,0 10,0 a 5, 5 0 1,0 -10,0" style=fill:blue;opacity:1;stroke:transparent;stroke-width:0 role=presentation shape-rendering=auto /><path d="M 225, 150 m -5, 0 a 5, 5 0 1,0 10,0 a 5, 5 0 1,0 -10,0" style=fill:blue;opacity:1;stroke:transparent;stroke-width:0 role=presentation shape-rendering=auto /><path d="M 390, 60 m -5, 0 a 5, 5 0 1,0 10,0 a 5, 5 0 1,0 -10,0" style=fill:blue;opacity:1;stroke:transparent;stroke-width:0 role=presentation shape-rendering=auto /></g><g role=presentation><line vector-effect=non-scaling-stroke style=stroke:#757575;fill:transparent;stroke-width:1;stroke-linecap:round;stroke-linejoin:round role=presentation shape-rendering=auto x1=60 x2=390 y1=240 y2=240 /><g role=presentation><text id=chart-axis-1-tickLabels-0 direction=inherit dx=0 x=142.5 y=263.26><tspan x=142.5 dx=0 dy=0 text-anchor=middle style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">0.5</tspan></text></g><g role=presentation><text id=chart-axis-1-tickLabels-1 direction=inherit dx=0 x=225 y=263.26><tspan x=225 dx=0 dy=0 text-anchor=middle style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">1.0</tspan></text></g><g role=presentation><text id=chart-axis-1-tickLabels-2 direction=inherit dx=0 x=307.5 y=263.26><tspan x=307.5 dx=0 dy=0 text-anchor=middle style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">1.5</tspan></text></g><g role=presentation><text id=chart-axis-1-tickLabels-3 direction=inherit dx=0 x=390 y=263.26><tspan x=390 dx=0 dy=0 text-anchor=middle style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">2.0</tspan></text></g></g><g role=presentation><line vector-effect=non-scaling-stroke style=stroke:#757575;fill:transparent;stroke-width:1;stroke-linecap:round;stroke-linejoin:round role=presentation shape-rendering=auto x1=60 x2=60 y1=60 y2=240 /><g role=presentation><text id=chart-axis-2-tickLabels-0 direction=inherit dx=0 x=47 y=199.26><tspan x=47 dx=0 dy=0 text-anchor=end style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">0.5</tspan></text></g><g role=presentation><text id=chart-axis-2-tickLabels-1 direction=inherit dx=0 x=47 y=154.26><tspan x=47 dx=0 dy=0 text-anchor=end style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">1.0</tspan></text></g><g role=presentation><text id=chart-axis-2-tickLabels-2 direction=inherit dx=0 x=47 y=109.26><tspan x=47 dx=0 dy=0 text-anchor=end style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">1.5</tspan></text></g><g role=presentation><text id=chart-axis-2-tickLabels-3 direction=inherit dx=0 x=47 y=64.26><tspan x=47 dx=0 dy=0 text-anchor=end style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">2.0</tspan></text></g></g></svg><div style=width:100%;height:100%;z-index:99;position:absolute;top:0;left:0><svg width=450 height=300 viewBox="0 0 450 300" style=width:100%;height:100%;overflow:visible /></div></div>
|
|||
|
<p>With fractal flames, rather than listing individual points, we use functions to describe the solution.
|
|||
|
This means there are an infinite number of points, but if we find <em>enough</em> points to plot, we get a nice picture.
|
|||
|
And if the functions change, the solution also changes, and we get something new.</p>
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=transform-functions>Transform functions<a href=#transform-functions class=hash-link aria-label="Direct link to Transform functions" title="Direct link to Transform functions"></a></h3>
|
|||
|
<p>Second, the <span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>F</mi><mi>i</mi></msub><mo stretchy=false>(</mo><mi>S</mi><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>F_i(S)</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" style=margin-right:0.05764em>S</span><span class=mclose>)</span></span></span></span> functions, also known as "transforms."
|
|||
|
Each transform takes in a 2-dimensional point and gives a new point back
|
|||
|
(in math terms, <span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>F</mi><mi>i</mi></msub><mo>∈</mo><msup><mi mathvariant=double-struck>R</mi><mn>2</mn></msup><mo>→</mo><msup><mi mathvariant=double-struck>R</mi><mn>2</mn></msup></mrow><annotation encoding=application/x-tex>F_i \in \mathbb{R}^2 \rightarrow \mathbb{R}^2</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 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.8141em></span><span class=mord><span class="mord mathbb">R</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141em><span style=top:-3.063em;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.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.8141em></span><span class=mord><span class="mord mathbb">R</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141em><span style=top:-3.063em;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>).
|
|||
|
While you could theoretically use any function, we'll focus on a specific kind of function
|
|||
|
called an "<a href=https://en.wikipedia.org/wiki/Affine_transformation target=_blank rel="noopener noreferrer">affine transformation</a>." Every transform uses the same formula:</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><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(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><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=strut style=height:0.8889em;vertical-align:-0.1944em></span><span class=mord><span class="mord mathnormal">c</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=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class=mord><span class="mord mathnormal">d</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="mor
|
|||
|
<!-- -->
|
|||
|
<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%)">Transform</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 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"> 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><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 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><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%)">interface</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">Coefs</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"
|
|||
|
<p>The parameters (<span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>a</mi><mi>i</mi></msub></mrow><annotation encoding=application/x-tex>a_i</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.5806em;vertical-align:-0.15em></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></span></span>, <span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>b</mi><mi>i</mi></msub></mrow><annotation encoding=application/x-tex>b_i</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8444em;vertical-align:-0.15em></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></span></span>, etc.) are values we choose.
|
|||
|
For example, we can define a "shift" function 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><mi>a</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><mn>1</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi>b</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><mn>0</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi>c</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><mn>0.5</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi>d</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><mn>0</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi>e</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><mn>1</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mi>f</mi></mstyle></mtd><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><mrow/><mo>=</mo><mn>1.5</mn></mrow></mstyle></mtd></mtr><mtr><mtd><mstyle scriptlevel=0 displaystyle=true><mrow><msub><mi>F</mi><mrow><mi>s</mi><mi>h</mi><mi>i</mi><mi>f</mi><mi>t</mi></mrow></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><mn>1</mn><mo>⋅</mo><mi>x</mi><mo>+</mo><mn>0.5</mn><mo separator=true>,</mo><mn>1</mn><mo>⋅</mo><mi>y</mi><mo>+</mo><mn>1.5</mn><mo stretchy=false>)</mo></mrow></mstyle></mtd></mtr></mtable><annotation encoding=application/x-tex>\begin{align*}
|
|||
|
a &= 1 \\
|
|||
|
b &= 0 \\
|
|||
|
c &= 0.5 \\
|
|||
|
d &= 0 \\
|
|||
|
e &= 1 \\
|
|||
|
f &= 1.5 \\
|
|||
|
F_{shift}(x, y) &= (1 \cdot x + 0.5, 1 \cdot y + 1.5)
|
|||
|
\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 class="mord mathnormal">a</span></span></span><span style=top:-6.16em><span class=pstrut style=height:3em></span><span class=mord><span class="mord mathnormal">b</span></span></span><span style=top:-4.66em><span class=pstrut style=height:3em></span><span class=mord><span class="mord mathnormal">c</span></span></span><span style=top:-3.16em><span class=pstrut style=height:3em></span><span class=mord><span class="mord mathnormal">d</span></span></span><span style=top:-1.66em><span class=pstrut style=height:3em></span><span class=mord><span class="mord mathnormal">e</span></span></span><span style=top:-0.16em><span class=pstrut style=height:3em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.10764em>f</span></span></span><span style=top:1.34em><span class=pstrut style=height:3em></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.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">s</span><span class="mord mathnormal mtight">hi</span><span class="mord mathnormal mtight" style=margin-right:0.10764em>f</span><span class="mord mathnormal mtight">t</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=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: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=mspace style=margin-right:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span><span class=mord>1</span></span></span><span style=top:-6.16em><span class=pstrut style=height:3em></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>0</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:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span><span class=mord>0.5</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:0.2778em></span><span class=mrel>=</span><span class=mspace style=margin-right:0.2778em></span><span class=mord>0</span></span></span><span style=top:-1.66em><span class=pstrut style=height:3em></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>1</span></span></span><span style=top:-0.16em><span class=pstrut style=height:3em></span><span class=mord><span class=mord></span><span class=mspace style=margin-right:0.2778em></span><span class=mrel
|
|||
|
<p>Applying this transform to the original points gives us a new set of points:</p>
|
|||
|
<!-- -->
|
|||
|
<!-- -->
|
|||
|
<!-- -->
|
|||
|
<div class=VictoryContainer style=height:100%;width:100%;user-select:none;pointer-events:none;touch-action:none;position:relative><svg width=450 height=300 role=img viewBox="0 0 450 300" style=width:100%;height:100%;pointer-events:all><g><path d="M 60, 240 m -5, 0 a 5, 5 0 1,0 10,0 a 5, 5 0 1,0 -10,0" style=fill:blue;opacity:1;stroke:transparent;stroke-width:0 role=presentation shape-rendering=auto /><path d="M 192, 188.57142857142858 m -5, 0 a 5, 5 0 1,0 10,0 a 5, 5 0 1,0 -10,0" style=fill:blue;opacity:1;stroke:transparent;stroke-width:0 role=presentation shape-rendering=auto /><path d="M 324, 137.14285714285714 m -5, 0 a 5, 5 0 1,0 10,0 a 5, 5 0 1,0 -10,0" style=fill:blue;opacity:1;stroke:transparent;stroke-width:0 role=presentation shape-rendering=auto /></g><g><path d="M 126, 162.85714285714286 m -5, 0 a 5, 5 0 1,0 10,0 a 5, 5 0 1,0 -10,0" style=fill:orange;opacity:1;stroke:transparent;stroke-width:0 role=presentation shape-rendering=auto /><path d="M 258, 111.42857142857143 m -5, 0 a 5, 5 0 1,0 10,0 a 5, 5 0 1,0 -10,0" style=fill:orange;opacity:1;stroke:transparent;stroke-width:0 role=presentation shape-rendering=auto /><path d="M 390, 60 m -5, 0 a 5, 5 0 1,0 10,0 a 5, 5 0 1,0 -10,0" style=fill:orange;opacity:1;stroke:transparent;stroke-width:0 role=presentation shape-rendering=auto /></g><g><rect vector-effect=non-scaling-stroke style=fill:none;stroke:#E8E8E8;stroke-width:2;padding:16px role=presentation shape-rendering=auto x=75 y=10 width=93.44375 height=72.98 /><path d="M 97, 32 m -4.8, 0 a 4.8, 4.8 0 1,0 9.6,0 a 4.8, 4.8 0 1,0 -9.6,0" style=fill:blue;type:circle role=presentation shape-rendering=auto /><path d="M 97, 58.49 m -4.8, 0 a 4.8, 4.8 0 1,0 9.6,0 a 4.8, 4.8 0 1,0 -9.6,0" style=fill:orange;type:circle role=presentation shape-rendering=auto /><text id=chart-legend-2-labels-0 direction=inherit dx=0 x=111.4 y=36.26><tspan x=111.4 dx=0 dy=0 text-anchor=start style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">(x,y)</tspan></text><text id=chart-legend-2-labels-1 direction=inherit dx=0 x=111.4 y=62.75><tspan x=111.4 dx=0 dy=0 text-anchor=start style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">F(x,y)</tspan></text></g><g role=presentation><line vector-effect=non-scaling-stroke style=stroke:#757575;fill:transparent;stroke-width:1;stroke-linecap:round;stroke-linejoin:round role=presentation shape-rendering=auto x1=60 x2=390 y1=240 y2=240 /><g role=presentation><text id=chart-axis-3-tickLabels-0 direction=inherit dx=0 x=126 y=263.26><tspan x=126 dx=0 dy=0 text-anchor=middle style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">0.5</tspan></text></g><g role=presentation><text id=chart-axis-3-tickLabels-1 direction=inherit dx=0 x=192 y=263.26><tspan x=192 dx=0 dy=0 text-anchor=middle style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">1.0</tspan></text></g><g role=presentation><text id=chart-axis-3-tickLabels-2 direction=inherit dx=0 x=258 y=263.26><tspan x=258 dx=0 dy=0 text-anchor=middle style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">1.5</tspan></text></g><g role=presentation><text id=chart-axis-3-tickLabels-3 direction=inherit dx=0 x=324 y=263.26><tspan x=324 dx=0 dy=0 text-anchor=middle style="font-family:'Inter', 'Helvetica Neue', 'Seravek', 'Helvetica', sans-serif;font-size:12px;font-weight:300;letter-spacing:normal;padding:8px;fill:#292929;stroke:transparent">2.0</tspan></text></g><g role=presentation><text id=chart-axis-3-tickLabels-4 direction=inherit dx=0 x=390 y=263.26><tspan
|
|||
|
<p>Fractal flames use more complex functions, but they all start with this structure.</p>
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=fixed-set>Fixed set<a href=#fixed-set class=hash-link aria-label="Direct link to Fixed set" title="Direct link to Fixed set"></a></h3>
|
|||
|
<p>With those definitions in place, let's revisit the initial problem:</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mrow><mi>S</mi><mo>=</mo><munderover><mo>⋃</mo><mrow><mi>i</mi><mo>=</mo><mn>0</mn></mrow><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></munderover><msub><mi>F</mi><mi>i</mi></msub><mo stretchy=false>(</mo><mi>S</mi><mo stretchy=false>)</mo></mrow><annotation encoding=application/x-tex>S = \bigcup_{i=0}^{n-1} F_i(S)</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</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:3.0788em;vertical-align:-1.2777em></span><span class="mop op-limits"><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.8011em><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">i</span><span class="mrel mtight">=</span><span class="mord mtight">0</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 style=top:-4.3em;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">n</span><span class="mbin mtight">−</span><span class="mord mtight">1</span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:1.2777em><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.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" style=margin-right:0.05764em>S</span><span class=mclose>)</span></span></span></span></span>
|
|||
|
<p>Or, in English, we might say:</p>
|
|||
|
<blockquote>
|
|||
|
<p>Our solution, <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>S</mi></mrow><annotation encoding=application/x-tex>S</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</span></span></span></span>, is the union of all sets produced by applying each function, <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>,
|
|||
|
to points in the solution.</p>
|
|||
|
</blockquote>
|
|||
|
<p>There's just one small problem: to find the solution, we must already know which points are in the solution.
|
|||
|
What?</p>
|
|||
|
<p>John E. Hutchinson provides an explanation in the <a href=https://maths-people.anu.edu.au/~john/Assets/Research%20Papers/fractals_self-similarity.pdf target=_blank rel="noopener noreferrer">original paper</a>
|
|||
|
defining the mathematics of iterated function systems:</p>
|
|||
|
<blockquote>
|
|||
|
<p>Furthermore, <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>S</mi></mrow><annotation encoding=application/x-tex>S</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</span></span></span></span> is compact and is the closure of the set of fixed points <span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>s</mi><mrow><msub><mi>i</mi><mn>1</mn></msub><mi mathvariant=normal>.</mi><mi mathvariant=normal>.</mi><mi mathvariant=normal>.</mi><msub><mi>i</mi><mi>p</mi></msub></mrow></msub></mrow><annotation encoding=application/x-tex>s_{i_1...i_p}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.7779em;vertical-align:-0.3473em></span><span class=mord><span class="mord mathnormal">s</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 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3173em><span style=top:-2.357em;margin-left:0em;margin-right:0.0714em><span class=pstrut style=height:2.5em></span><span class="sizing reset-size3 size1 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.143em><span></span></span></span></span></span></span><span class="mord mtight">...</span><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.1645em><span style=top:-2.357em;margin-left:0em;margin-right:0.0714em><span class=pstrut style=height:2.5em></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2819em><span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.3473em><span></span></span></span></span></span></span></span></span></span>
|
|||
|
of finite compositions <span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>F</mi><mrow><msub><mi>i</mi><mn>1</mn></msub><mi mathvariant=normal>.</mi><mi mathvariant=normal>.</mi><mi mathvariant=normal>.</mi><msub><mi>i</mi><mi>p</mi></msub></mrow></msub></mrow><annotation encoding=application/x-tex>F_{i_1...i_p}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.0307em;vertical-align:-0.3473em></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 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3173em><span style=top:-2.357em;margin-left:0em;margin-right:0.0714em><span class=pstrut style=height:2.5em></span><span class="sizing reset-size3 size1 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.143em><span></span></span></span></span></span></span><span class="mord mtight">...</span><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.1645em><span style=top:-2.357em;margin-left:0em;margin-right:0.0714em><span class=pstrut style=height:2.5em></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2819em><span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.3473em><span></span></span></span></span></span></span></span></span></span> of members of <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.6833em></span><span class="mord mathnormal" style=margin-right:0.13889em>F</span></span></span></span>.</p>
|
|||
|
</blockquote>
|
|||
|
<p>Before your eyes glaze over, let's unpack this:</p>
|
|||
|
<ul>
|
|||
|
<li><strong>Furthermore, <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>S</mi></mrow><annotation encoding=application/x-tex>S</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</span></span></span></span> is <a href=https://en.wikipedia.org/wiki/Compact_space target=_blank rel="noopener noreferrer">compact</a>...</strong>: All points in our solution will be in a finite range</li>
|
|||
|
<li><strong>...and is the <a href=https://en.wikipedia.org/wiki/Closure_(mathematics) target=_blank rel="noopener noreferrer">closure</a> of the set of <a href=https://en.wikipedia.org/wiki/Fixed_point_(mathematics) target=_blank rel="noopener noreferrer">fixed points</a></strong>:
|
|||
|
Applying our functions to points in the solution will give us other points that are in the solution</li>
|
|||
|
<li><strong>...of finite compositions <span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>F</mi><mrow><msub><mi>i</mi><mn>1</mn></msub><mi mathvariant=normal>.</mi><mi mathvariant=normal>.</mi><mi mathvariant=normal>.</mi><msub><mi>i</mi><mi>p</mi></msub></mrow></msub></mrow><annotation encoding=application/x-tex>F_{i_1...i_p}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.0307em;vertical-align:-0.3473em></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 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3173em><span style=top:-2.357em;margin-left:0em;margin-right:0.0714em><span class=pstrut style=height:2.5em></span><span class="sizing reset-size3 size1 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.143em><span></span></span></span></span></span></span><span class="mord mtight">...</span><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.1645em><span style=top:-2.357em;margin-left:0em;margin-right:0.0714em><span class=pstrut style=height:2.5em></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2819em><span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.3473em><span></span></span></span></span></span></span></span></span></span> of members of <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.6833em></span><span class="mord mathnormal" style=margin-right:0.13889em>F</span></span></span></span></strong>: By composing our functions (that is,
|
|||
|
using the output of one function as input to the next), we will arrive at the points in the solution</li>
|
|||
|
</ul>
|
|||
|
<p>Thus, by applying the functions to fixed points of our system, we will find the other points we care about.</p>
|
|||
|
<details class="details_lb9f alert alert--info details_b_Ee" data-collapsed=true><summary>If you want a bit more math...</summary><div><div class=collapsibleContent_i85q><p>...then there are some extra details I've glossed over so far.<p>First, the Hutchinson paper requires that the functions <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> be <em>contractive</em> for the solution set to exist.
|
|||
|
That is, applying the function to a point must bring it closer to other points. However, as the fractal flame
|
|||
|
algorithm demonstrates, we only need functions to be contractive <em>on average</em>. At worst, the system will
|
|||
|
degenerate and produce a bad image.<p>Second, we're focused on <span class=katex><span class=katex-mathml><math><semantics><mrow><msup><mi mathvariant=double-struck>R</mi><mn>2</mn></msup></mrow><annotation encoding=application/x-tex>\mathbb{R}^2</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.8141em></span><span class=mord><span class="mord mathbb">R</span><span class=msupsub><span class=vlist-t><span class=vlist-r><span class=vlist style=height:0.8141em><span style=top:-3.063em;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> because we're generating images, but the math
|
|||
|
allows for arbitrary dimensions; you could also have 3-dimensional fractal flames.<p>Finally, there's a close relationship between fractal flames and <a href=https://en.wikipedia.org/wiki/Attractor target=_blank rel="noopener noreferrer">attractors</a>.
|
|||
|
Specifically, the fixed points of <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>S</mi></mrow><annotation encoding=application/x-tex>S</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6833em></span><span class="mord mathnormal" style=margin-right:0.05764em>S</span></span></span></span> act as attractors for the chaos game (explained below).</div></div></details>
|
|||
|
<p>This is still a bit vague, so let's work through an example.</p>
|
|||
|
<h2 class="anchor anchorWithStickyNavbar_LWe7" id=sierpinskis-gasket><a href=https://www.britannica.com/biography/Waclaw-Sierpinski target=_blank rel="noopener noreferrer">Sierpinski's gasket</a><a href=#sierpinskis-gasket class=hash-link aria-label="Direct link to sierpinskis-gasket" title="Direct link to sierpinskis-gasket"></a></h2>
|
|||
|
<p>The Fractal Flame paper gives three functions to use for a first IFS:</p>
|
|||
|
<span class=katex-display><span class=katex><span class=katex-mathml><math display=block><semantics><mrow><msub><mi>F</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><mrow><mo fence=true>(</mo><mfrac><mi>x</mi><mn>2</mn></mfrac><mo separator=true>,</mo><mfrac><mi>y</mi><mn>2</mn></mfrac><mo fence=true>)</mo></mrow><mspace linebreak=newline /><mtext> </mtext><mspace linebreak=newline /><msub><mi>F</mi><mn>1</mn></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo><mo>=</mo><mrow><mo fence=true>(</mo><mfrac><mrow><mi>x</mi><mo>+</mo><mn>1</mn></mrow><mn>2</mn></mfrac><mo separator=true>,</mo><mfrac><mi>y</mi><mn>2</mn></mfrac><mo fence=true>)</mo></mrow><mspace linebreak=newline /><mtext> </mtext><mspace linebreak=newline /><msub><mi>F</mi><mn>2</mn></msub><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><mo stretchy=false>)</mo><mo>=</mo><mrow><mo fence=true>(</mo><mfrac><mi>x</mi><mn>2</mn></mfrac><mo separator=true>,</mo><mfrac><mrow><mi>y</mi><mo>+</mo><mn>1</mn></mrow><mn>2</mn></mfrac><mo fence=true>)</mo></mrow></mrow><annotation encoding=application/x-tex>F_0(x, y) = \left({x \over 2}, {y \over 2} \right) \\
|
|||
|
~\\
|
|||
|
F_1(x, y) = \left({{x + 1} \over 2}, {y \over 2} \right) \\
|
|||
|
~\\
|
|||
|
F_2(x, y) = \left({x \over 2}, {{y + 1} \over 2} \right)</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.3011em><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">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:1.836em;vertical-align:-0.686em></span><span class=minner><span class="mopen delimcenter" style=top:0em><span class="delimsizing size2">(</span></span><span class=mord><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1076em><span style=top:-2.314em><span class=pstrut style=height:3em></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em><span class=pstrut style=height:3em></span><span class=frac-line style=border-bottom-width:0.04em></span></span><span style=top:-3.677em><span class=pstrut style=height:3em></span><span class=mord><span class="mord mathnormal">x</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class=mord><span class=mord><span class="mopen nulldelimiter"></span><span class=mfrac><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:1.1076em><span style=top:-2.314em><span class=pstrut style=height:3em></span><span class=mord><span class=mord>2</span></span></span><span style=top:-3.23em><span class=pstrut style=height:3em></span><span class=frac-line style=border-bottom-width:0.04em></span></span><span style=top:-3.677em><span class=pstrut style=height:3em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.03588em>y</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.686em><span></span></span></span></span></span><span class="mclose nulldelimiter"></span></span></span><span class="mclose delimcenter" style=top:0em><span class="delimsizing size2">)</span></span></span></span><span class="mspace newline"></span><span class=base><span class=strut style=height:0em></span><span class="mspace nobreak"> </span></span><span class="mspace newline"></span><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.3011em><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">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=mopen>(</span><span class="mord mathnormal">x</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class="mord
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=the-chaos-game>The chaos game<a href=#the-chaos-game class=hash-link aria-label="Direct link to The chaos game" title="Direct link to The chaos game"></a></h3>
|
|||
|
<p>Now, how do we find the "fixed points" mentioned earlier? The paper lays out an algorithm called the "<a href=https://en.wikipedia.org/wiki/Chaos_game target=_blank rel="noopener noreferrer">chaos game</a>"
|
|||
|
that gives us points in the solution:</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 /><mtext>plot</mtext><mo stretchy=false>(</mo><mi>x</mi><mo separator=true>,</mo><mi>y</mi><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} \text{plot}(x,y) \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:9em;vertical-align:-4.25em></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:4.75em><span style=top:-6.91em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:-5.41em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:-3.91em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:-2.41em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:-0.91em><span class=pstrut style=height:3em></span><span class=mord></span></span><span style=top:0.59em><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:4.25em><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:4.75em><span style=top:-6.91em><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:-5.41em><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:-3.91em><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:-2.41em><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:-0.91em><span class=pstrut style=height:3em></span><span class=mord><span class=mord></span><span class=mspac
|
|||
|
<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>The chaos game algorithm is effectively the "finite compositions of <span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>F</mi><mrow><msub><mi>i</mi><mn>1</mn></msub><mi mathvariant=normal>.</mi><mi mathvariant=normal>.</mi><msub><mi>i</mi><mi>p</mi></msub></mrow></msub></mrow><annotation encoding=application/x-tex>F_{i_1..i_p}</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:1.0307em;vertical-align:-0.3473em></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 mtight"><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.3173em><span style=top:-2.357em;margin-left:0em;margin-right:0.0714em><span class=pstrut style=height:2.5em></span><span class="sizing reset-size3 size1 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.143em><span></span></span></span></span></span></span><span class="mord mtight">..</span><span class="mord mtight"><span class="mord mathnormal mtight">i</span><span class=msupsub><span class="vlist-t vlist-t2"><span class=vlist-r><span class=vlist style=height:0.1645em><span style=top:-2.357em;margin-left:0em;margin-right:0.0714em><span class=pstrut style=height:2.5em></span><span class="sizing reset-size3 size1 mtight"><span class="mord mathnormal mtight">p</span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.2819em><span></span></span></span></span></span></span></span></span></span></span><span class=vlist-s></span></span><span class=vlist-r><span class=vlist style=height:0.3473em><span></span></span></span></span></span></span></span></span></span>" mentioned earlier.</div></div>
|
|||
|
<p>Let's turn this into code, one piece at a time.</p>
|
|||
|
<p>To start, we need to generate some random numbers. The "bi-unit square" is the range <span class=katex><span class=katex-mathml><math><semantics><mrow><mo stretchy=false>[</mo><mo>−</mo><mn>1</mn><mo separator=true>,</mo><mn>1</mn><mo stretchy=false>]</mo></mrow><annotation encoding=application/x-tex>[-1, 1]</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>−</span><span class=mord>1</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class=mord>1</span><span class=mclose>]</span></span></span></span>,
|
|||
|
and we can do this using an existing API:</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 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%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">randomBiUnit</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 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%)">return</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%)">2</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%)">1</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><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>Next, we need to choose a random integer from <span class=katex><span class=katex-mathml><math><semantics><mrow><mn>0</mn></mrow><annotation encoding=application/x-tex>0</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6444em></span><span class=mord>0</span></span></span></span> to <span class=katex><span class=katex-mathml><math><semantics><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow><annotation encoding=application/x-tex>n - 1</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.6667em;vertical-align:-0.0833em></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><span class=base><span class=strut style=height:0.6444em></span><span class=mord>1</span></span></span></span>:</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 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%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">randomInteger</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"> min</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"> max</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 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%)">let</span><span class="token plain"> v </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 punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">max </span><span class="token operator" style="color:hsl(221, 87%, 60%)">-</span><span class="token plain"> min</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%)">return</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%)">floor</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">v</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"> min</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><br></span></code></pre><div class=buttonGroup__atx><button type=button aria-label="Copy code to clipboard" title=Copy class=clean-btn
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=plotting>Plotting<a href=#plotting class=hash-link aria-label="Direct link to Plotting" title="Direct link to Plotting"></a></h3>
|
|||
|
<p>Finally, implementing the <code>plot</code> function. This blog series is interactive,
|
|||
|
so everything displays directly in the browser. As an alternative,
|
|||
|
software like <code>flam3</code> and Apophysis can "plot" by saving an image to disk.</p>
|
|||
|
<p>To see the results, we'll use the <a href=https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API target=_blank rel="noopener noreferrer">Canvas API</a>.
|
|||
|
This allows us to manipulate individual pixels in an image and show it on screen.</p>
|
|||
|
<p>First, we need to convert from fractal flame coordinates to pixel coordinates.
|
|||
|
To simplify things, we'll assume that we're plotting a square image
|
|||
|
with range <span class=katex><span class=katex-mathml><math><semantics><mrow><mo stretchy=false>[</mo><mn>0</mn><mo separator=true>,</mo><mn>1</mn><mo stretchy=false>]</mo></mrow><annotation encoding=application/x-tex>[0, 1]</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>0</span><span class=mpunct>,</span><span class=mspace style=margin-right:0.1667em></span><span class=mord>1</span><span class=mclose>]</span></span></span></span> for both <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>:</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 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%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">camera</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"> size</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 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 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 keyword" style="color:hsl(301, 63%, 40%)">return</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"> Math</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">floor</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">x </span><span class="token operator" style="color:hsl(221, 87%, 60%)">*</span><span class="token plain"> size</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"> Math</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">floor</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">y </span><span class="token operator" style="
|
|||
|
<p>Next, we'll store the pixel data in an <a href=https://developer.mozilla.org/en-US/docs/Web/API/ImageData target=_blank rel="noopener noreferrer"><code>ImageData</code> object</a>.
|
|||
|
Each pixel on screen has a corresponding index in the <code>data</code> array.
|
|||
|
To plot a point, we set that pixel to be black:</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"> camera </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%)">"./cameraGasket"</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" 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%)">function</span><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">imageIndex</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"> width</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 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%)">return</span><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 punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">width </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%)">4</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"> x </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%)">4</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain">
|
|||
|
<p>Putting it all together, we have our first image:</p>
|
|||
|
<!-- -->
|
|||
|
<!-- -->
|
|||
|
<div class=playgroundContainer_TGbA><div class=playgroundHeader_qwyd>Live Editor</div><div class=playgroundEditor_PvJ1><pre class="prism-code language-tsx" style="margin:0;outline:none;padding:10px;font-family:inherit;background-color:hsl(230, 1%, 98%);color:hsl(230, 8%, 24%)" spellcheck=false><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token comment" style="color:hsl(230, 4%, 64%)">// Hint: try changing the iteration count</span><span class="token plain"></span>
|
|||
|
</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"> iterations </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%)">100000</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span>
|
|||
|
</span><span class=token-line style="color:hsl(230, 8%, 24%)">
|
|||
|
</span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token comment" style="color:hsl(230, 4%, 64%)">// Hint: negating `x` and `y` creates some cool images</span><span class="token plain"></span>
|
|||
|
</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"> xforms </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>
|
|||
|
</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 arrow 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 operator" style="color:hsl(221, 87%, 60%)">/</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">2</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><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 number" style="color:hsl(35, 99%, 36%)">2</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><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 arrow 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 punctuation" style="color:hsl(119, 34%, 47%)">(</span><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 number" style="color:hsl(35, 99%, 36%)">1</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%)">2</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><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 number" style="color:hsl(35, 99%, 36%)">2</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><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 arrow 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 operator" style="color:hsl(221, 87%, 60%)">/</span><span class="token plain"> </span><span class="token number" style="color:hsl(35, 99%, 36%)">2</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><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 number" style="color:hsl(35, 99%, 36%)">1</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%)">2</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</span><span class="token plain"></span>
|
|||
|
</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><span class=token-line style="color:hsl(230, 8%, 24%)">
|
|||
|
</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%)">function</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%)">chaosGame</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"> width</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> height </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 punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span>
|
|||
|
</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%)">let</span><span class="token plain"> img </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"></span>
|
|||
|
</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%)">new</span><span class="token plain"> </span><span class="token class-name" style="color:hsl(35, 99%, 36%)">ImageData</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">width</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> height</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><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%)">let</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 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>
|
|||
|
</span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">randomBiUnit</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>
|
|||
|
</span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">randomBiUnit</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><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><span class=token-line style="color:hsl(230, 8%, 24%)">
|
|||
|
</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%)">for</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token keyword" style="color:hsl(301, 63%, 40%)">let</span><span class="token plain"> i </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 punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"> i </span><span class="token operator" style="color:hsl(221, 87%, 60%)"><</span><span class="token plain"> iterations</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"> i</span><span class="token operator" style="color:hsl(221, 87%, 60%)">++</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token plain"></span>
|
|||
|
</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"> index </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"></span>
|
|||
|
</span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">randomInteger</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token number" style="color:hsl(35, 99%, 36%)">0</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> xforms</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token property-access">length</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><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"> xforms</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">index</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">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><span class="token plain"></span>
|
|||
|
</span><span class=token-line style="color:hsl(230, 8%, 24%)">
|
|||
|
</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%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">i </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%)">20</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span>
|
|||
|
</span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"> </span><span class="token function" style="color:hsl(221, 87%, 60%)">plot</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"> img</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><span class=token-line style="color:hsl(230, 8%, 24%)">
|
|||
|
</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%)">if</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token plain">i </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%)">1000</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 punctuation" style="color:hsl(119, 34%, 47%)">)</span><span class="token plain"></span>
|
|||
|
</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%)">yield</span><span class="token plain"> img</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span>
|
|||
|
</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><span class=token-line style="color:hsl(230, 8%, 24%)">
|
|||
|
</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%)">yield</span><span class="token plain"> img</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">;</span><span class="token plain"></span>
|
|||
|
</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><span class=token-line style="color:hsl(230, 8%, 24%)">
|
|||
|
</span><span class=token-line style="color:hsl(230, 8%, 24%)"><span class="token plain"></span><span class="token function" style="color:hsl(221, 87%, 60%)">render</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">(</span><span class="token tag punctuation" style="color:hsl(119, 34%, 47%)"><</span><span class="token tag class-name" style="color:hsl(35, 99%, 36%)">Gasket</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag attr-name" style="color:hsl(35, 99%, 36%)">f</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:hsl(119, 34%, 47%)">=</span><span class="token tag script language-javascript punctuation" style="color:hsl(119, 34%, 47%)">{</span><span class="token tag script language-javascript" style="color:hsl(5, 74%, 59%)">chaosGame</span><span class="token tag script language-javascript punctuation" style="color:hsl(119, 34%, 47%)">}</span><span class="token tag" style="color:hsl(5, 74%, 59%)"> </span><span class="token tag 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></pre></div><div class=playgroundHeader_qwyd>Result</div><div class=playgroundPreview_bb8I><div>Loading...</div></div></div>
|
|||
|
<hr>
|
|||
|
<small><p>The image here is slightly different than in the paper.
|
|||
|
I think the paper has an error, so I'm plotting the image
|
|||
|
like the <a href=https://github.com/scottdraves/flam3/blob/7fb50c82e90e051f00efcc3123d0e06de26594b2/rect.c#L440-L441 target=_blank rel="noopener noreferrer">reference implementation</a>.</small>
|
|||
|
<h3 class="anchor anchorWithStickyNavbar_LWe7" id=weights>Weights<a href=#weights class=hash-link aria-label="Direct link to Weights" title="Direct link to Weights"></a></h3>
|
|||
|
<p>There's one last step before we finish the introduction. So far, each transform has
|
|||
|
the same chance of being picked in the chaos game.
|
|||
|
We can change that by giving them a "weight" (<span class=katex><span class=katex-mathml><math><semantics><mrow><msub><mi>w</mi><mi>i</mi></msub></mrow><annotation encoding=application/x-tex>w_i</annotation></semantics></math></span><span class=katex-html aria-hidden=true><span class=base><span class=strut style=height:0.5806em;vertical-align:-0.15em></span><span class=mord><span class="mord mathnormal" style=margin-right:0.02691em>w</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.0269em;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>) instead:</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 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%)">function</span><span class="token plain"> </span><span class="token generic-function function" style="color:hsl(221, 87%, 60%)">randomChoice</span><span class="token generic-function generic class-name operator" style="color:hsl(221, 87%, 60%)"><</span><span class="token generic-function generic class-name constant" style="color:hsl(35, 99%, 36%)">T</span><span class="token generic-function generic class-name operator" style="color:hsl(221, 87%, 60%)">></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"> choices</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 constant" style="color:hsl(35, 99%, 36%)">T</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"></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 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 constant" style="color:hsl(35, 99%, 36%)">T</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">]</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 keyword" style="color:hsl(301, 63%, 40%)">const</span><span class="token plain"> weightSum </span><span class="token operator" style="color:hsl(221, 87%, 60%)">=</span><span class="token plain"> choices</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">.</span><span class="token function" style="color:hsl(221, 87%, 60%)">reduce</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">sum</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><span class="token plain"> </span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">[</span><span class="token plain">weight</span><span class="token punctuation" style="color:hsl(119, 34%, 47%)">,</span><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 op
|
|||
|
<p>If we let the chaos game run forever, these weights wouldn't matter.
|
|||
|
But because the iteration count is limited, changing the weights
|
|||
|
means we don't plot some parts of the image:</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"> 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"> 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%)">"./plot"</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" style=display:inline-block></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%)">const</span><span class="token plain"> quality </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 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"></spa
|
|||
|
<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>Double-click the image if you want to save a copy!</div></div>
|
|||
|
<!-- -->
|
|||
|
<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>Studying the foundations of fractal flames is challenging,
|
|||
|
but we now have an understanding of the mathematics
|
|||
|
and the implementation of iterated function systems.</p>
|
|||
|
<p>In the next post, we'll look at the first innovation of fractal flame algorithm: variations.</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=/2011/11/webpack-industrial-complex><div class=pagination-nav__sublabel>Older post</div><div class=pagination-nav__label>The webpack industrial complex</div></a><a class="pagination-nav__link pagination-nav__link--next" href=/2024/11/playing-with-fire-transforms><div class=pagination-nav__sublabel>Newer post</div><div class=pagination-nav__label>Playing with fire: Transforms and variations</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=#iterated-function-systems class="table-of-contents__link toc-highlight">Iterated function systems</a><ul><li><a href=#solution-set class="table-of-contents__link toc-highlight">Solution set</a><li><a href=#transform-functions class="table-of-contents__link toc-highlight">Transform functions</a><li><a href=#fixed-set class="table-of-contents__link toc-highlight">Fixed set</a></ul><li><a href=#sierpinskis-gasket class="table-of-contents__link toc-highlight">Sierpinski's gasket</a><ul><li><a href=#the-chaos-game class="table-of-contents__link toc-highlight">The chaos game</a><li><a href=#plotting class="table-of-contents__link toc-highlight">Plotting</a><li><a href=#weights class="table-of-contents__link toc-highlight">Weights</a></ul><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>
|